summaryrefslogtreecommitdiff
path: root/qpid/java
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/java')
-rw-r--r--qpid/java/broker-plugins/access-control/MANIFEST.MF1
-rw-r--r--qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java361
-rw-r--r--qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java15
-rw-r--r--qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java281
-rw-r--r--qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java194
-rw-r--r--qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java229
-rw-r--r--qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/Activator.java9
-rw-r--r--qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java2
-rwxr-xr-xqpid/java/broker-plugins/experimental/shutdown/src/main/java/shutdown.bnd2
-rw-r--r--qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java148
-rw-r--r--qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java21
-rw-r--r--qpid/java/broker-plugins/simple-xml/MANIFEST.MF36
-rw-r--r--qpid/java/broker-plugins/simple-xml/build.xml29
-rwxr-xr-xqpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/config/PrincipalPermissions.java687
-rw-r--r--qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java427
-rw-r--r--qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLActivator.java42
-rw-r--r--qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLConfiguration.java57
-rw-r--r--qpid/java/broker-plugins/simple-xml/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java209
-rw-r--r--qpid/java/broker/bin/qpid-server.bat12
-rw-r--r--qpid/java/broker/etc/access19
-rw-r--r--qpid/java/broker/etc/config.xml22
-rw-r--r--qpid/java/broker/etc/jmxremote.access23
-rw-r--r--qpid/java/broker/etc/passwdVhost19
-rw-r--r--qpid/java/broker/etc/qpid-server.conf.jpp3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java11
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java70
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java63
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java420
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java152
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java525
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java73
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java178
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java75
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java28
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java33
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java51
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java15
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java13
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java15
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java81
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Channel_logmessages.properties4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java56
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java61
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java41
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java43
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java37
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java196
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngineFactory.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java115
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java28
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java73
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java30
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java29
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java16
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java27
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java21
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java84
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java217
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java367
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java11
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java53
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/security/PrincipalHolder.java29
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java34
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java77
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java221
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java35
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java49
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java407
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java58
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java406
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java54
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java21
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java99
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java58
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java163
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java118
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionList.java213
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java12
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java174
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java54
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java121
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java96
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java5
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java47
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java4
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java32
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java120
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java196
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java143
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/RunBrokerWithCommand.java132
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java767
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java26
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java12
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java16
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java202
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java27
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java4
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java12
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java10
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java213
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java754
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java53
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java358
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java269
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/CRAMMD5HexServerTest.java228
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java86
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java122
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/stats/StatisticsCounterTest.java144
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java3
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java20
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionListTest.java429
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockAction.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java11
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java11
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java57
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/HouseKeepingTaskTest.java67
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java271
-rw-r--r--qpid/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java2
-rw-r--r--qpid/java/build.deps62
-rw-r--r--qpid/java/build.xml29
-rw-r--r--qpid/java/client/README.txt2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java4
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/transport/ExistingSocketConnectorDemo.java171
-rwxr-xr-xqpid/java/client/src/main/java/client.bnd2
-rw-r--r--qpid/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java478
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java13
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java38
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java111
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java4
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java52
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java31
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java19
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java112
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java100
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java113
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java32
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java75
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java3
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java17
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java4
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java51
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java20
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java29
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java9
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java87
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java35
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java35
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessage.java5
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java35
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java15
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java52
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java10
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java4
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties1
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java30
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java17
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClient.java52
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClientFactory.java52
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java90
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java351
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java63
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java4
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java60
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java13
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java5
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java6
-rw-r--r--qpid/java/client/src/test/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java125
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java5
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java23
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java99
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.java78
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/jms/FailoverPolicyTest.java338
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java9
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java99
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java6
-rw-r--r--qpid/java/common.xml29
-rwxr-xr-xqpid/java/common/src/main/java/common.bnd2
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/common/FixedSizeByteBufferAllocator.java467
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java227
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/common/support/IoServiceListenerSupport.java351
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferFullExeception.java48
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferLimitFilterBuilder.java272
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/filter/codec/OurCumulativeProtocolDecoder.java197
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/filter/codec/QpidProtocolCodecFilter.java440
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketAcceptor.java547
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketConnector.java486
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketFilterChain.java67
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketIoProcessor.java1026
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionConfigImpl.java240
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionImpl.java488
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/transport/vmpipe/QpidVmPipeConnector.java151
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java3
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java3
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/AMQException.java16
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/ToyBroker.java208
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/ToyClient.java108
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/ToyExchange.java154
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java57
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java83
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java12
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java5
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngineFactory.java4
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/thread/QpidThreadExecutor.java2
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/ClientDelegate.java6
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java50
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionDelegate.java1
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionSettings.java2
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriver.java63
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriverConfiguration.java (renamed from qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java)20
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java47
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java96
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java16
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/SocketConnectorFactory.java8
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/TransportBuilder.java78
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java1
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkTransport.java20
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/Transport.java123
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/InputHandler_0_9.java130
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoAcceptor.java (renamed from qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IoAcceptor.java)0
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoContext.java (renamed from qpid/java/common/src/test/java/org/apache/qpid/transport/MockSender.java)38
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java93
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java87
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java30
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java51
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoTransport.java231
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MINANetworkDriver.java435
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaHandler.java274
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkConnection.java81
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkHandler.java149
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkTransport.java219
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaSender.java65
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioHandler.java135
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioSender.java126
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/SecurityLayer.java9
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/sasl/SASLSender.java6
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java12
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java3
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java25
-rw-r--r--qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterClient.java396
-rw-r--r--qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterServer.java157
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java13
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java214
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java55
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/TestNetworkDriver.java (renamed from qpid/java/common/src/test/java/org/apache/qpid/transport/TestNetworkConnection.java)19
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/network/TransportTest.java157
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IoTransport.java165
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/network/mina/MINANetworkDriverTest.java (renamed from qpid/java/common/src/test/java/org/apache/qpid/transport/network/mina/MinaNetworkHandlerTest.java)266
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java82
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/util/default.properties2
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/util/mydefaults.properties2
-rw-r--r--qpid/java/ivy.xml39
-rw-r--r--qpid/java/lib/backport-util-concurrent-2.2.jarbin0 -> 326319 bytes
-rw-r--r--qpid/java/lib/commons-pool-1.4.jarbin0 -> 87077 bytes
-rw-r--r--qpid/java/lib/core-3.1.1.jarbin0 -> 3566844 bytes
-rw-r--r--qpid/java/lib/geronimo-servlet_2.5_spec-1.2.jarbin0 -> 70593 bytes
-rw-r--r--qpid/java/lib/ivy/README.txt11
-rw-r--r--qpid/java/lib/javassist.jarbin0 -> 471005 bytes
-rw-r--r--qpid/java/lib/jline-0.9.94.jarbin0 -> 87325 bytes
-rw-r--r--qpid/java/lib/jsp-2.1.jarbin0 -> 1024681 bytes
-rw-r--r--qpid/java/lib/jsp-api-2.1.jarbin0 -> 134910 bytes
-rw-r--r--qpid/java/lib/junit-4.4.jarbin0 -> 161477 bytes
-rwxr-xr-xqpid/java/lib/mina-core-1.0.1.jarbin0 -> 313338 bytes
-rw-r--r--qpid/java/lib/mina-core-1.1.7.jarbin315582 -> 0 bytes
-rwxr-xr-xqpid/java/lib/mina-filter-ssl-1.0.1.jarbin0 -> 28950 bytes
-rw-r--r--qpid/java/lib/mina-filter-ssl-1.1.7.jarbin29188 -> 0 bytes
-rw-r--r--qpid/java/lib/muse-core-2.2.0.jarbin0 -> 121976 bytes
-rw-r--r--qpid/java/lib/muse-platform-mini-2.2.0.jarbin0 -> 8227 bytes
-rw-r--r--qpid/java/lib/muse-util-2.2.0.jarbin0 -> 23215 bytes
-rw-r--r--qpid/java/lib/muse-util-qname-2.2.0.jarbin0 -> 4968 bytes
-rw-r--r--qpid/java/lib/muse-util-xml-2.2.0.jarbin0 -> 19082 bytes
-rw-r--r--qpid/java/lib/muse-wsa-soap-2.2.0.jarbin0 -> 25030 bytes
-rw-r--r--qpid/java/lib/muse-wsdm-muws-adv-api-2.2.0.jarbin0 -> 4145 bytes
-rw-r--r--qpid/java/lib/muse-wsdm-muws-adv-impl-2.2.0.jarbin0 -> 10366 bytes
-rw-r--r--qpid/java/lib/muse-wsdm-muws-api-2.2.0.jarbin0 -> 18492 bytes
-rw-r--r--qpid/java/lib/muse-wsdm-muws-impl-2.2.0.jarbin0 -> 57860 bytes
-rw-r--r--qpid/java/lib/muse-wsdm-wef-api-2.2.0.jarbin0 -> 9125 bytes
-rw-r--r--qpid/java/lib/muse-wsdm-wef-impl-2.2.0.jarbin0 -> 18049 bytes
-rw-r--r--qpid/java/lib/muse-wsn-api-2.2.0.jarbin0 -> 29692 bytes
-rw-r--r--qpid/java/lib/muse-wsn-impl-2.2.0.jarbin0 -> 80531 bytes
-rw-r--r--qpid/java/lib/muse-wsrf-api-2.2.0.jarbin0 -> 58684 bytes
-rw-r--r--qpid/java/lib/muse-wsrf-impl-2.2.0.jarbin0 -> 127656 bytes
-rw-r--r--qpid/java/lib/muse-wsrf-rmd-2.2.0.jarbin0 -> 5625 bytes
-rw-r--r--qpid/java/lib/muse-wsx-api-2.2.0.jarbin0 -> 4624 bytes
-rw-r--r--qpid/java/lib/muse-wsx-impl-2.2.0.jarbin0 -> 9349 bytes
-rw-r--r--qpid/java/lib/poms/backport-util-concurrent-2.2.xml (renamed from qpid/java/ivysettings-nexus.xml)20
-rw-r--r--qpid/java/lib/poms/mina-core-1.0.1.xml (renamed from qpid/java/lib/poms/mina-core-1.1.7.xml)2
-rw-r--r--qpid/java/lib/poms/mina-filter-ssl-1.0.1.xml (renamed from qpid/java/lib/poms/mina-filter-ssl-1.1.7.xml)2
-rw-r--r--qpid/java/lib/start.jarbin0 -> 17125 bytes
-rw-r--r--qpid/java/lib/wsdl4j-1.6.1.jarbin0 -> 148522 bytes
-rw-r--r--qpid/java/lib/xercesImpl-2.8.1.jarbin0 -> 1212965 bytes
-rw-r--r--qpid/java/lib/xml-apis-1.3.03.jarbin0 -> 195119 bytes
-rw-r--r--qpid/java/management/agent/build.xml27
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java706
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java (renamed from qpid/java/client/src/main/java/org/apache/qpid/client/message/QpidMessageProperties.java)27
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java27
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java138
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java52
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java72
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java90
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFAgent.java34
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java42
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java39
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java42
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java39
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java40
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java42
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java213
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java50
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java137
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java601
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java108
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java131
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java95
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java91
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java121
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java131
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java465
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java46
-rw-r--r--qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java70
-rw-r--r--qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java113
-rw-r--r--qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java (renamed from qpid/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java)38
-rw-r--r--qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java29
-rw-r--r--qpid/java/management/client/README.txt42
-rw-r--r--qpid/java/management/client/bin/qman-jmx.cmd78
-rw-r--r--qpid/java/management/client/bin/qman-jmx.sh76
-rw-r--r--qpid/java/management/client/bin/qman-wsdm-start.cmd88
-rw-r--r--qpid/java/management/client/bin/qman-wsdm-start.sh89
-rw-r--r--qpid/java/management/client/bin/qman-wsdm-stop.cmd37
-rw-r--r--qpid/java/management/client/bin/qman-wsdm-stop.sh38
-rw-r--r--qpid/java/management/client/build.xml213
-rw-r--r--qpid/java/management/client/console/brokers_management.jsp209
-rw-r--r--qpid/java/management/client/console/console.jsp122
-rw-r--r--qpid/java/management/client/console/error_page.jsp59
-rw-r--r--qpid/java/management/client/console/fragments/header.jsp36
-rw-r--r--qpid/java/management/client/console/fragments/menu.jsp31
-rw-r--r--qpid/java/management/client/console/images/asf-logo.pngbin0 -> 4735 bytes
-rw-r--r--qpid/java/management/client/console/images/menu.gifbin0 -> 1953 bytes
-rw-r--r--qpid/java/management/client/console/images/menuleft.gifbin0 -> 640 bytes
-rw-r--r--qpid/java/management/client/console/images/menuright.gifbin0 -> 1398 bytes
-rw-r--r--qpid/java/management/client/console/images/qpid-logo.pngbin0 -> 39056 bytes
-rw-r--r--qpid/java/management/client/console/images/style.css202
-rw-r--r--qpid/java/management/client/console/jmx_perspective.jsp157
-rw-r--r--qpid/java/management/client/console/logging_configuration.jsp241
-rw-r--r--qpid/java/management/client/console/resources_management.jsp105
-rw-r--r--qpid/java/management/client/console/tbd.jsp48
-rw-r--r--qpid/java/management/client/console/wsdm_operations_perspective.jsp174
-rw-r--r--qpid/java/management/client/console/wsdm_properties_perspective.jsp218
-rw-r--r--qpid/java/management/client/console/wsdm_rmd_perspective.jsp99
-rw-r--r--qpid/java/management/client/console/wsdm_wsdl_perspective.jsp99
-rw-r--r--qpid/java/management/client/doc/man/qman-jmx17
-rw-r--r--qpid/java/management/client/etc/jetty.xml47
-rw-r--r--qpid/java/management/client/etc/qman-config.xml68
-rw-r--r--qpid/java/management/client/etc/qman-config.xsd63
-rw-r--r--qpid/java/management/client/etc/qman.log4j29
-rw-r--r--qpid/java/management/client/src/example/ConnectWithBroker.out.ok81
-rw-r--r--qpid/java/management/client/src/example/GetMultipleResourceProperties.out.ok262
-rw-r--r--qpid/java/management/client/src/example/GetQManResourceMembers.out.ko54
-rw-r--r--qpid/java/management/client/src/example/GetQManResourceMembers.out.ok55
-rw-r--r--qpid/java/management/client/src/example/GetResourceMetadataDescriptor.out.ok188
-rw-r--r--qpid/java/management/client/src/example/GetResourcePropertyDocument.out.ok138
-rw-r--r--qpid/java/management/client/src/example/GetResourcePropertyRequest.out.ok588
-rw-r--r--qpid/java/management/client/src/example/GetWsdlMetadata.out.ko.no.resources58
-rw-r--r--qpid/java/management/client/src/example/GetWsdlMetadata.out.ok1968
-rw-r--r--qpid/java/management/client/src/example/PauseAndResumeSubscription.out.ok133
-rw-r--r--qpid/java/management/client/src/example/README.txt69
-rw-r--r--qpid/java/management/client/src/example/SetResourcePropertiesRequest.out.ok2316
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/AbstractQManExample.java140
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/ConnectWithBrokerExample.java240
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java293
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/GetMultipleResourcePropertiesExample.java179
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/GetQManResourceMembersExample.java93
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourceMetadataDescriptorExample.java156
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyDocumentExample.java111
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyExample.java172
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/GetWSDLMetadataExample.java156
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/PausableSubscriptionExample.java88
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/SetResourcePropertyExample.java306
-rw-r--r--qpid/java/management/client/src/main/java/muse.xml209
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java175
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java216
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java52
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerAlreadyConnectedException.java53
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java280
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.java136
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionException.java42
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java485
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/ConfigurationException.java51
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java240
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/IParser.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java64
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/QpidDatasource.java249
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.java54
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownAccessCodeException.java53
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownBrokerException.java (renamed from qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java)36
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownTypeCodeException.java53
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/WorkerManagerConfigurationParser.java109
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/BaseMessageHandler.java54
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandler.java114
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/IMessageHandler.java52
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/ConfigurationMessageHandler.java57
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java51
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/HeartBeatIndicationMessageHandler.java39
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/IMethodInvocationListener.java41
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InstrumentationMessageHandler.java57
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java157
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodOrEventDataTransferObject.java68
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodResponseMessageHandler.java106
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObject.java314
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObjectMBean.java234
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java217
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/AccessMode.java33
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/Direction.java33
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java239
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/IValidator.java (renamed from qpid/java/common/src/main/java/org/apache/qpid/transport/network/IncomingNetworkTransport.java)22
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/InvocationEvent.java76
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java410
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/MissingFeatureAttributesException.java35
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java123
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidAttribute.java105
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java833
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClassMBean.java41
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java184
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java493
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEventMBean.java41
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java86
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java454
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java147
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java286
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java295
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java (renamed from qpid/java/common/src/main/java/org/apache/qpid/transport/network/OutgoingNetworkTransport.java)20
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java51
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java105
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/AbsTime.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java169
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Boolean.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/DeltaTime.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Double.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Float.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int16.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int32.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int64.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int8.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java45
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/ObjectReference.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str16.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str8.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Type.java101
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint16.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint32.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint64.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint8.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uuid.java46
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java183
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.java249
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MessageTokenizer.java152
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MethodInvocationException.java50
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java412
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java361
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/SequenceNumberGenerator.java41
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/StartupFailureException.java42
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/UnableToComplyException.java31
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/EntityLifecycleNotification.java147
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/OperationHasBeenInvokedNotification.java168
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/ManagementMessage.java189
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/MethodInvocationRequestMessage.java161
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/SchemaRequestMessage.java68
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/ConnectQManToBroker.java89
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManLifeCycleManager.java79
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/WSDMAdapter.java109
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.java100
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java204
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleAction.java117
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleModel.java158
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/JmxPerspectiveAction.java189
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/LoggingConfigurationAction.java114
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ResourcesManagementAction.java91
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmOperationsPerspectiveAction.java191
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java185
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java139
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.java140
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmu.java130
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java95
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuMBean.java48
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ArtifactsNotAvailableException.java76
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/BuilderException.java41
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Constants.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.java68
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java86
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/IArtifactBuilder.java82
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java219
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java549
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java557
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMessageHandler.java104
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java99
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java57
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java135
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java196
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifacts.java93
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java140
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java460
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java58
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/MethodInvocationFault.java79
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/NoSuchAttributeFault.java70
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ObjectNameIdFactory.java61
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManFault.java72
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManResourceIdFactory.java57
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java105
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSessionManager.java68
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/UnableToConnectWithBrokerFault.java86
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java118
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterIsolationLayer.java57
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java762
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ByteArraySerializer.java83
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/DateSerializer.java75
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java85
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java134
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ObjectSerializer.java202
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/UUIDSerializer.java72
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEvent.java149
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEventType.java34
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/WsdlDebugger.java49
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/XmlDebugger.java92
-rw-r--r--qpid/java/management/client/src/main/java/router-entries/adapter/resource-instance-1.xml23
-rw-r--r--qpid/java/management/client/src/main/java/router-entries/consumer/resource-instance-1.xml23
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/QManAdapter.rmd27
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/QManAdapter.wsdl694
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/QManWsResource.rmd17
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl507
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/SOAP-Envelope-1_2.xsd181
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-Addressing-2005_08.xsd169
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-BaseFaults-1_2.xsd84
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl449
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.xsd577
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-MetadataExchange-2004_09.xsd134
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.wsdl54
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.xsd48
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.wsdl83
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.xsd130
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ResourceMetadataDescriptor-CD-01.xsd325
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.wsdl395
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.xsd394
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.wsdl269
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.xsd233
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl206
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-Topics-1_3.xsd185
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part1-1_1.xsd114
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part2-1_1.xsd677
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WsResource.rmd14
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WsResourceFactory.wsdl22
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/XML-Namespace-1998.xsd46
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java67
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java181
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java163
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/MappingParsersTest.java79
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandlerTest.java59
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseDomainModelTestCase.java44
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseQpidFeatureBuilderTestCase.java96
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/DomainModelTest.java55
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/OptionalPropertiesTest.java187
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java408
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java293
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidMethodBuilderTest.java147
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidNumberPropertyTest.java171
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPackageTest.java53
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPropertyBuilderTest.java269
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStatisticBuilderTest.java159
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStringPropertyTest.java127
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/type/BinaryTest.java59
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java241
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/MessageTokenizerTest.java140
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/BaseWsDmAdapterTestCase.java143
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/EnhancedReflectionProxyHandler.java72
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetMultipleResourcePropertiesTestCase.java125
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertiesTestCase.java105
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertyDocumentTestCase.java134
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/MetadataExchangeInterfaceTestCase.java169
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/OperationInvocationInterfaceTestCase.java580
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/ServerThread.java118
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/SetResourcePropertiesTestCase.java219
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WebApplicationLifeCycleListener.java61
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java156
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilderTest.java335
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityTest.java204
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapabilityTest.java81
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilderTest.java110
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/web.xml32
-rw-r--r--qpid/java/management/client/web.xml149
-rw-r--r--qpid/java/management/common/src/main/java/management-common.bnd2
-rw-r--r--qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedBroker.java118
-rw-r--r--qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedConnection.java127
-rw-r--r--qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ServerInformation.java121
-rw-r--r--qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/UserManagement.java98
-rw-r--r--qpid/java/management/console/build.xml27
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/AbstractConsole.java81
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/Agent.java116
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/Broker.java504
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/ClassKey.java146
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/Console.java51
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/ConsoleException.java48
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/EventSeverity.java37
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/MethodResult.java88
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/ObjectID.java93
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFEvent.java108
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFObject.java423
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaArgument.java65
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaClass.java251
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaMethod.java125
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaProperty.java81
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaStatistic.java88
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaVariable.java185
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/SequenceManager.java (renamed from qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java)106
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/Session.java980
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/Util.java184
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/XMLUtil.java155
-rw-r--r--qpid/java/management/console/src/test/java/org/apache/qpid/console/ClassKeyTest.java39
-rw-r--r--qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF2
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java2
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java29
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java25
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java2
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/LegacySupportingUserManagement.java132
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/UserManagementTabControl.java199
-rw-r--r--qpid/java/management/tools/qpid-cli/Guide.txt143
-rw-r--r--qpid/java/management/tools/qpid-cli/LICENSE225
-rw-r--r--qpid/java/management/tools/qpid-cli/NOTICE12
-rw-r--r--qpid/java/management/tools/qpid-cli/README.txt64
-rwxr-xr-xqpid/java/management/tools/qpid-cli/bin/qpid-cli (renamed from qpid/java/tools/bin/check-qpid-java-env)27
-rwxr-xr-xqpid/java/management/tools/qpid-cli/bin/qpid-cli.bat28
-rw-r--r--qpid/java/management/tools/qpid-cli/build.xml31
-rw-r--r--qpid/java/management/tools/qpid-cli/report.property26
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Command.java (renamed from qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java)17
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandExecutionEngine.java76
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandLineInterpreter.java263
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Connector.java49
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ConnectorFactory.java (renamed from qpid/java/systests/src/main/java/org/apache/qpid/test/utils/SpawnedBrokerHolder.java)40
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ReportGenerator.java195
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/CommandImpl.java153
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commanddelete.java199
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandget.java211
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandhelp.java56
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandinfo.java206
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandlist.java232
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandmove.java259
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandset.java260
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandview.java255
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandviewcontent.java248
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/AllObjects.java38
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ConnectionObject.java46
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ExchangeObject.java45
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ObjectNames.java591
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/QueueObject.java67
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/UserManagementObject.java38
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/VirtualHostObject.java47
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOption.java104
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionConstants.java37
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionParser.java231
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfigProperty.java29
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfiguration.java182
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXinfo.java53
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/AllTest.java41
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/ConnectionConstants.java30
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandExecutionEngine.java73
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandLineInterpreter.java80
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestConnector.java79
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestReportGenerator.java (renamed from qpid/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerHolder.java)6
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommand.java79
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommanddelete.java79
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandinfo.java77
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandlist.java82
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandmove.java80
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandview.java78
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandviewcontent.java78
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestAllObject.java69
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestConnectionObject.java83
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestExchangeObject.java83
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestObjectNames.java (renamed from qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AmqpProtocolVersion.java)7
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestQueueObject.java83
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestUserManagementObject.java74
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestVirtualHostObject.java84
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOption.java64
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOptionParser.java79
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfigProperty.java26
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfiguration.java64
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXinfo.java30
-rw-r--r--qpid/java/maven-settings.xml2
-rw-r--r--qpid/java/module.xml127
-rw-r--r--qpid/java/perftests/src/main/java/org/apache/qpid/test/testcases/MessageThroughputPerf.java207
-rw-r--r--qpid/java/resources/NOTICE7
-rw-r--r--qpid/java/systests/etc/config-systests-ServerConfigurationTest-New.xml78
-rw-r--r--qpid/java/systests/etc/config-systests-ServerConfigurationTest-Old.xml92
-rw-r--r--qpid/java/systests/etc/config-systests-acl-settings.xml26
-rw-r--r--qpid/java/systests/etc/config-systests-acl.xml30
-rw-r--r--qpid/java/systests/etc/config-systests-firewall-2.xml22
-rw-r--r--qpid/java/systests/etc/config-systests-firewall-3.xml22
-rw-r--r--qpid/java/systests/etc/virtualhosts-ServerConfigurationTest-New.xml45
-rw-r--r--qpid/java/systests/etc/virtualhosts-systests-acl-settings.xml180
-rw-r--r--qpid/java/systests/etc/virtualhosts-systests-acl.xml29
-rw-r--r--qpid/java/systests/src/main/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java125
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java1
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/client/DispatcherTest.java1
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java82
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageTest.java26
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/jms/xa/XAResourceTest.java116
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageConnectionStatisticsTest.java102
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsConfigurationTest.java162
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsDeliveryTest.java110
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsReportingTest.java90
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTest.java218
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTestCase.java128
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java6
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java15
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java8
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/failover/FailoverMethodTest.java110
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java2
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java13
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ChannelLoggingTest.java4
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ManagementLoggingTest.java17
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java19
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java246
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/queue/PriorityTest.java1
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java6
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java611
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java644
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java18
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java542
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java56
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/AMQPFeatureDecorator.java96
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureDecorator.java95
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureInVM.java70
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/InVMBrokerDecorator.java136
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/Acknowledge2ConsumersTest.java4
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/QuickAcking.java2
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java1
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java6
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java22
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java1
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java105
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java64
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java25
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java7
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ct/DurableSubscriberTest.java4
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java41
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutConfigurationTest.java82
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java72
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java335
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java253
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java22
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java111
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java303
-rw-r--r--qpid/java/test-profiles/08StandaloneExcludes (renamed from qpid/java/test-profiles/JavaPre010Excludes)7
-rwxr-xr-xqpid/java/test-profiles/CPPExcludes11
-rw-r--r--qpid/java/test-profiles/Excludes2
-rwxr-xr-xqpid/java/test-profiles/Java010Excludes16
-rw-r--r--qpid/java/test-profiles/JavaExcludes50
-rw-r--r--qpid/java/test-profiles/JavaInVMExcludes43
-rw-r--r--qpid/java/test-profiles/JavaStandaloneExcludes55
-rw-r--r--qpid/java/test-profiles/cpp.async.testprofile2
-rw-r--r--qpid/java/test-profiles/cpp.testprofile5
-rw-r--r--qpid/java/test-profiles/default.testprofile (renamed from qpid/java/test-profiles/testprofile.defaults)11
-rw-r--r--qpid/java/test-profiles/java-dby.0-10.testprofile30
-rw-r--r--qpid/java/test-profiles/java-dby.0-9-1.testprofile36
-rw-r--r--qpid/java/test-profiles/java-derby.0.10.testprofile (renamed from qpid/java/test-profiles/java-dby-spawn.0-10.testprofile)7
-rw-r--r--qpid/java/test-profiles/java-derby.testprofile (renamed from qpid/java/test-profiles/java-dby-spawn.0-9-1.testprofile)7
-rw-r--r--qpid/java/test-profiles/java-mms-spawn.0-9-1.testprofile31
-rw-r--r--qpid/java/test-profiles/java-mms.0-9-1.testprofile32
-rw-r--r--qpid/java/test-profiles/java.0.10.testprofile (renamed from qpid/java/test-profiles/java-mms.0-10.testprofile)7
-rw-r--r--qpid/java/test-profiles/java.testprofile (renamed from qpid/java/test-profiles/java-mms-spawn.0-10.testprofile)8
-rw-r--r--qpid/java/test-profiles/test-provider.properties4
-rwxr-xr-xqpid/java/tools/bin/Profile-run-from-source71
-rw-r--r--qpid/java/tools/bin/controller132
-rwxr-xr-xqpid/java/tools/bin/perf_report.sh (renamed from qpid/java/tools/bin/perf-report)45
-rw-r--r--[-rwxr-xr-x]qpid/java/tools/bin/qpid-bench16
-rwxr-xr-xqpid/java/tools/bin/qpid-python-testkit11
-rw-r--r--[-rwxr-xr-x]qpid/java/tools/bin/run_pub.sh (renamed from qpid/java/tools/bin/run-sub)14
-rw-r--r--[-rwxr-xr-x]qpid/java/tools/bin/run_sub.sh (renamed from qpid/java/tools/bin/run-pub)9
-rw-r--r--qpid/java/tools/bin/set-testkit-env.sh88
-rw-r--r--qpid/java/tools/bin/setenv.sh49
-rw-r--r--qpid/java/tools/bin/start-consumers119
-rw-r--r--qpid/java/tools/bin/start-producers136
-rw-r--r--qpid/java/tools/etc/perf-report.gnu42
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/Clock.java92
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/LatencyTest.java12
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfBase.java166
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfConsumer.java224
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfProducer.java256
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfTestController.java422
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java70
-rw-r--r--qpid/java/upload.xml90
828 files changed, 74295 insertions, 18250 deletions
diff --git a/qpid/java/broker-plugins/access-control/MANIFEST.MF b/qpid/java/broker-plugins/access-control/MANIFEST.MF
index 78072850e4..1cd285ba20 100644
--- a/qpid/java/broker-plugins/access-control/MANIFEST.MF
+++ b/qpid/java/broker-plugins/access-control/MANIFEST.MF
@@ -35,7 +35,6 @@ Import-Package: org.apache.qpid,
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,
diff --git a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
index 78355a7501..ebc73440ed 100644
--- a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
+++ b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
@@ -18,24 +18,20 @@
*/
package org.apache.qpid.server.security.access.config;
-import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.WeakHashMap;
-import javax.security.auth.Subject;
-
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.security.Result;
@@ -49,132 +45,147 @@ import org.apache.qpid.server.security.access.logging.AccessControlMessages;
* Models the rule configuration for the access control plugin.
*
* The access control rule definitions are loaded from an external configuration file, passed in as the
- * target to the {@link load(ConfigurationFile)} method. The file specified
+ * target to the {@link load(ConfigurationFile)} method. The file specified
*/
public class RuleSet
{
+ private static final Logger _logger = Logger.getLogger(RuleSet.class);
+
private static final String AT = "@";
- private static final String SLASH = "/";
+ private static final String SLASH = "/";
- public static final String DEFAULT_ALLOW = "defaultallow";
- public static final String DEFAULT_DENY = "defaultdeny";
- public static final String TRANSITIVE = "transitive";
- public static final String EXPAND = "expand";
+ public static final String DEFAULT_ALLOW = "defaultallow";
+ public static final String DEFAULT_DENY = "defaultdeny";
+ public static final String TRANSITIVE = "transitive";
+ public static final String EXPAND = "expand";
public static final String AUTONUMBER = "autonumber";
public static final String CONTROLLED = "controlled";
public static final String VALIDATE = "validate";
-
+
public static final List<String> CONFIG_PROPERTIES = Arrays.asList(
DEFAULT_ALLOW, DEFAULT_DENY, TRANSITIVE, EXPAND, AUTONUMBER, CONTROLLED
);
-
+
private static final Integer _increment = 10;
-
- private final Map<String, List<String>> _aclGroups = new HashMap<String, List<String>>();
+
+ private final Map<String, List<String>> _groups = 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>>>>();
+ private final Map<String, Map<Operation, Map<ObjectType, List<Rule>>>> _cache =
+ new WeakHashMap<String, Map<Operation, Map<ObjectType, List<Rule>>>>();
private final Map<String, Boolean> _config = new HashMap<String, Boolean>();
-
+
public RuleSet()
{
// set some default configuration properties
configure(DEFAULT_DENY, Boolean.TRUE);
configure(TRANSITIVE, Boolean.TRUE);
}
-
+
/**
- * Clear the contents, including acl groups, rules and configuration.
+ * Clear the contents, invluding groups, rules and configuration.
*/
public void clear()
{
_rules.clear();
_cache.clear();
_config.clear();
- _aclGroups.clear();
+ _groups.clear();
}
-
+
public int getRuleCount()
{
return _rules.size();
}
-
- /**
- * Filtered rules list based on a subject and operation.
- *
- * Allows only enabled rules with identity equal to all, the same, or a group with identity as a member,
- * and operation is either all or the same operation.
- */
- public List<Rule> getRules(final Subject subject, final Operation operation, final ObjectType objectType)
- {
- final Map<ObjectType, List<Rule>> objects = getObjectToRuleCache(subject, operation);
+
+ /**
+ * Filtered rules list based on an identity and operation.
+ *
+ * Allows only enabled rules with identity equal to all, the same, or a group with identity as a member,
+ * and operation is either all or the same operation.
+ */
+ public List<Rule> getRules(String identity, Operation operation, ObjectType objectType)
+ {
+ // Lookup identity in cache and create empty operation map if required
+ Map<Operation, Map<ObjectType, List<Rule>>> operations = _cache.get(identity);
+ if (operations == null)
+ {
+ operations = new EnumMap<Operation, Map<ObjectType, List<Rule>>>(Operation.class);
+ _cache.put(identity, operations);
+ }
+
+ // Lookup operation and create empty object type map if required
+ Map<ObjectType, List<Rule>> objects = operations.get(operation);
+ if (objects == null)
+ {
+ objects = new EnumMap<ObjectType, List<Rule>>(ObjectType.class);
+ operations.put(operation, objects);
+ }
// Lookup object type rules for the operation
if (!objects.containsKey(objectType))
{
- final Set<Principal> principals = subject.getPrincipals();
boolean controlled = false;
List<Rule> filtered = new LinkedList<Rule>();
for (Rule rule : _rules.values())
{
- final Action ruleAction = rule.getAction();
if (rule.isEnabled()
- && (ruleAction.getOperation() == Operation.ALL || ruleAction.getOperation() == operation)
- && (ruleAction.getObjectType() == ObjectType.ALL || ruleAction.getObjectType() == objectType))
+ && (rule.getAction().getOperation() == Operation.ALL || rule.getAction().getOperation() == operation)
+ && (rule.getAction().getObjectType() == ObjectType.ALL || rule.getAction().getObjectType() == objectType))
{
controlled = true;
- if (isRelevant(principals,rule))
+ if (rule.getIdentity().equalsIgnoreCase(Rule.ALL)
+ || rule.getIdentity().equalsIgnoreCase(identity)
+ || (_groups.containsKey(rule.getIdentity()) && _groups.get(rule.getIdentity()).contains(identity)))
{
filtered.add(rule);
}
}
}
-
+
// Return null if there are no rules at all for this operation and object type
if (filtered.isEmpty() && controlled == false)
{
filtered = null;
}
-
+
// Save the rules we selected
objects.put(objectType, filtered);
}
-
+
// Return the cached rules
- return objects.get(objectType);
- }
-
-
+ return objects.get(objectType);
+ }
+
public boolean isValidNumber(Integer number)
{
return !_rules.containsKey(number);
}
-
+
public void grant(Integer number, String identity, Permission permission, Operation operation)
{
Action action = new Action(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);
addRule(number, identity, permission, action);
}
-
+
public boolean ruleExists(String identity, Action action)
{
- for (Rule rule : _rules.values())
- {
- if (rule.getIdentity().equals(identity) && rule.getAction().equals(action))
- {
- return true;
- }
- }
- return false;
+ for (Rule rule : _rules.values())
+ {
+ if (rule.getIdentity().equals(identity) && rule.getAction().equals(action))
+ {
+ return true;
+ }
+ }
+ return false;
}
-
+
private Permission noLog(Permission permission)
{
switch (permission)
@@ -192,17 +203,15 @@ public class RuleSet
// 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)
{
- _cache.clear();
-
- if (!action.isAllowed())
- {
- throw new IllegalArgumentException("Action is not allowd: " + action);
- }
+ if (!action.isAllowed())
+ {
+ throw new IllegalArgumentException("Action is not allowd: " + action);
+ }
if (ruleExists(identity, action))
{
return;
}
-
+
// expand actions - possibly multiply number by
if (isSet(EXPAND))
{
@@ -225,8 +234,8 @@ public class RuleSet
return;
}
}
-
- // transitive action dependencies
+
+ // transitive action dependencies
if (isSet(TRANSITIVE))
{
if (action.getOperation() == Operation.CREATE && action.getObjectType() == ObjectType.QUEUE)
@@ -235,10 +244,10 @@ public class RuleSet
exchProperties.setName(ExchangeDefaults.DEFAULT_EXCHANGE_NAME);
exchProperties.put(ObjectProperties.Property.ROUTING_KEY, action.getProperties().get(ObjectProperties.Property.NAME));
addRule(null, identity, noLog(permission), new Action(Operation.BIND, ObjectType.EXCHANGE, exchProperties));
- if (action.getProperties().isSet(ObjectProperties.Property.AUTO_DELETE))
- {
- addRule(null, identity, noLog(permission), new Action(Operation.DELETE, ObjectType.QUEUE, action.getProperties()));
- }
+ if (action.getProperties().isSet(ObjectProperties.Property.AUTO_DELETE))
+ {
+ addRule(null, identity, noLog(permission), new Action(Operation.DELETE, ObjectType.QUEUE, action.getProperties()));
+ }
}
else if (action.getOperation() == Operation.DELETE && action.getObjectType() == ObjectType.QUEUE)
{
@@ -252,9 +261,9 @@ public class RuleSet
addRule(null, identity, noLog(permission), new Action(Operation.ACCESS, ObjectType.VIRTUALHOST));
}
}
-
+
// set rule number if needed
- Rule rule = new Rule(number, identity, action, permission);
+ Rule rule = new Rule(number, identity, action, permission);
if (rule.getNumber() == null)
{
if (_rules.isEmpty())
@@ -266,36 +275,34 @@ public class RuleSet
rule.setNumber(_rules.lastKey() + _increment);
}
}
-
+
// save rule
_cache.remove(identity);
_rules.put(rule.getNumber(), rule);
- }
-
+ }
+
public void enableRule(int ruleNumber)
{
_rules.get(Integer.valueOf(ruleNumber)).enable();
}
-
+
public void disableRule(int ruleNumber)
{
_rules.get(Integer.valueOf(ruleNumber)).disable();
}
-
+
public boolean addGroup(String group, List<String> constituents)
{
- _cache.clear();
-
- if (_aclGroups.containsKey(group))
+ if (_groups.containsKey(group))
{
// cannot redefine
return false;
}
else
{
- _aclGroups.put(group, new ArrayList<String>());
+ _groups.put(group, new ArrayList<String>());
}
-
+
for (String name : constituents)
{
if (name.equalsIgnoreCase(group))
@@ -303,17 +310,17 @@ public class RuleSet
// recursive definition
return false;
}
-
+
if (!checkName(name))
{
// invalid name
return false;
}
-
- if (_aclGroups.containsKey(name))
+
+ if (_groups.containsKey(name))
{
// is a group
- _aclGroups.get(group).addAll(_aclGroups.get(name));
+ _groups.get(group).addAll(_groups.get(name));
}
else
{
@@ -323,12 +330,12 @@ public class RuleSet
// invalid username
return false;
}
- _aclGroups.get(group).add(name);
+ _groups.get(group).add(name);
}
}
return true;
}
-
+
/** Return true if the name is well-formed (contains legal characters). */
protected boolean checkName(String name)
{
@@ -342,79 +349,79 @@ public class RuleSet
}
return true;
}
-
+
/** Returns true if a username has the name[@domain][/realm] format */
protected boolean isvalidUserName(String name)
- {
- // check for '@' and '/' in namne
- int atPos = name.indexOf(AT);
- int slashPos = name.indexOf(SLASH);
- boolean atFound = atPos != StringUtils.INDEX_NOT_FOUND && atPos == name.lastIndexOf(AT);
- boolean slashFound = slashPos != StringUtils.INDEX_NOT_FOUND && slashPos == name.lastIndexOf(SLASH);
-
- // must be at least one character after '@' or '/'
- if (atFound && atPos > name.length() - 2)
- {
- return false;
- }
- if (slashFound && slashPos > name.length() - 2)
- {
- return false;
- }
-
- // must be at least one character between '@' and '/'
- if (atFound && slashFound)
- {
- return (atPos < (slashPos - 1));
- }
-
- // otherwise all good
- return true;
+ {
+ // check for '@' and '/' in namne
+ int atPos = name.indexOf(AT);
+ int slashPos = name.indexOf(SLASH);
+ boolean atFound = atPos != StringUtils.INDEX_NOT_FOUND && atPos == name.lastIndexOf(AT);
+ boolean slashFound = slashPos != StringUtils.INDEX_NOT_FOUND && slashPos == name.lastIndexOf(SLASH);
+
+ // must be at least one character after '@' or '/'
+ if (atFound && atPos > name.length() - 2)
+ {
+ return false;
+ }
+ if (slashFound && slashPos > name.length() - 2)
+ {
+ return false;
+ }
+
+ // must be at least one character between '@' and '/'
+ if (atFound && slashFound)
+ {
+ return (atPos < (slashPos - 1));
+ }
+
+ // otherwise all good
+ return true;
}
- // C++ broker authorise function prototype
+ // C++ 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?
+ // const std::string& name, std::map<Property, std::string>* params=0);
+
+ // Possibly add a String name paramater?
/**
* Check the authorisation granted to a particular identity for an operation on an object type with
* specific properties.
*
- * Looks up the entire ruleset, which may be cached, for the user and operation and goes through the rules
+ * Looks up the entire ruleset, whcih may be cached, for the user and operation and goes through the rules
* in order to find the first one that matches. Either defers if there are no rules, returns the result of
* 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(String identity, Operation operation, ObjectType objectType, ObjectProperties properties)
{
// Create the action to check
Action action = new Action(operation, objectType, properties);
- // get the list of rules relevant for this request
- List<Rule> rules = getRules(subject, operation, objectType);
- if (rules == null)
- {
- if (isSet(CONTROLLED))
- {
- // Abstain if there are no rules for this operation
+ // get the list of rules relevant for this request
+ List<Rule> rules = getRules(identity, operation, objectType);
+ if (rules == null)
+ {
+ if (isSet(CONTROLLED))
+ {
+ // Abstain if there are no rules for this operation
return Result.ABSTAIN;
- }
- else
- {
- return getDefault();
- }
- }
-
- // Iterate through a filtered set of rules dealing with this identity and operation
+ }
+ else
+ {
+ return getDefault();
+ }
+ }
+
+ // Iterate through a filtered set of rules dealing with this identity and operation
for (Rule current : rules)
- {
- // Check if action matches
+ {
+ // Check if action matches
if (action.matches(current.getAction()))
{
Permission permission = current.getPermission();
-
+
switch (permission)
{
case ALLOW_LOG:
@@ -432,15 +439,15 @@ public class RuleSet
return Result.DENIED;
}
}
-
+
// Defer to the next plugin of this type, if it exists
- return Result.DEFER;
+ return Result.DEFER;
}
-
- /** Default deny. */
- public Result getDefault()
- {
- if (isSet(DEFAULT_ALLOW))
+
+ /** Default deny. */
+ public Result getDefault()
+ {
+ if (isSet(DEFAULT_ALLOW))
{
return Result.ALLOWED;
}
@@ -449,19 +456,19 @@ public class RuleSet
return Result.DENIED;
}
return Result.ABSTAIN;
- }
-
- /**
- * Check if a configuration property is set.
- */
- protected boolean isSet(String key)
- {
- return BooleanUtils.isTrue(_config.get(key));
- }
+ }
+
+ /**
+ * Check if a configuration property is set.
+ */
+ protected boolean isSet(String key)
+ {
+ return BooleanUtils.isTrue(_config.get(key));
+ }
/**
* Configure properties for the plugin instance.
- *
+ *
* @param properties
*/
public void configure(Map<String, Boolean> properties)
@@ -471,7 +478,7 @@ public class RuleSet
/**
* Configure a single property for the plugin instance.
- *
+ *
* @param key
* @param value
*/
@@ -479,48 +486,4 @@ public class RuleSet
{
_config.put(key, value);
}
-
- private boolean isRelevant(final Set<Principal> principals, final Rule rule)
- {
- if (rule.getIdentity().equalsIgnoreCase(Rule.ALL))
- {
- return true;
- }
- else
- {
- for (Iterator<Principal> iterator = principals.iterator(); iterator.hasNext();)
- {
- final Principal principal = iterator.next();
-
- if (rule.getIdentity().equalsIgnoreCase(principal.getName())
- || (_aclGroups.containsKey(rule.getIdentity()) && _aclGroups.get(rule.getIdentity()).contains(principal.getName())))
- {
- return true;
- }
- }
- }
-
- return false;
- }
-
- private Map<ObjectType, List<Rule>> getObjectToRuleCache(final Subject subject, final Operation operation)
- {
- // Lookup identity in cache and create empty operation map if required
- Map<Operation, Map<ObjectType, List<Rule>>> operations = _cache.get(subject);
- if (operations == null)
- {
- operations = new EnumMap<Operation, Map<ObjectType, List<Rule>>>(Operation.class);
- _cache.put(subject, operations);
- }
-
- // Lookup operation and create empty object type map if required
- Map<ObjectType, List<Rule>> objects = operations.get(operation);
- if (objects == null)
- {
- objects = new EnumMap<ObjectType, List<Rule>>(ObjectType.class);
- operations.put(operation, objects);
- }
- return objects;
- }
-
}
diff --git a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java
index a7b3059262..69cfa173bd 100644
--- a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java
+++ b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java
@@ -20,7 +20,7 @@
*/
package org.apache.qpid.server.security.access.plugins;
-import javax.security.auth.Subject;
+import java.security.Principal;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
@@ -89,19 +89,20 @@ public class AccessControl extends AbstractPlugin
/**
* 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
+ * control rules granted to the current thread's {@link Principal}. If there is no current
* user the plugin will abstain.
*/
public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
{
- final Subject subject = SecurityManager.getThreadSubject();
- // Abstain if there is no subject/principal associated with this thread
- if (subject == null || subject.getPrincipals().size() == 0)
+ Principal principal = SecurityManager.getThreadPrincipal();
+
+ // Abstain if there is no user associated with this thread
+ if (principal == null)
{
return Result.ABSTAIN;
}
-
- return _ruleSet.check(subject, operation, objectType, properties);
+
+ return _ruleSet.check(principal.getName(), operation, objectType, properties);
}
public void configure(ConfigurationPlugin config)
diff --git a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java
index 09d26e5451..309a3aeb2c 100644
--- a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java
+++ b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java
@@ -1,172 +1,195 @@
/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * 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.util.Arrays;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.PrintWriter;
import junit.framework.TestCase;
-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;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.SecurityManager;
-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.Permission;
-import org.apache.qpid.server.security.access.config.Rule;
+import org.apache.commons.configuration.ConfigurationException;
+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;
-import org.apache.qpid.server.security.auth.sasl.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.
+ * These tests check that the ACL file parsing works correctly.
*
- * @see RuleSetTest
+ * For each message that can be returned in a {@link ConfigurationException}, an ACL file is created that should trigger this
+ * particular message.
*/
public class AccessControlTest extends TestCase
{
- private AccessControl _plugin = null; // Class under test
- private final UnitTestMessageLogger messageLogger = new UnitTestMessageLogger();
-
- protected void setUp() throws Exception
+ public void writeACLConfig(String...aclData) throws Exception
{
- super.setUp();
-
- 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);
- // Catch all rule
- rs.grant(3, Rule.ALL, Permission.DENY_LOG, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
-
- _plugin = (AccessControl) AccessControl.FACTORY.newInstance(createConfiguration(rs));
-
- SecurityManager.setThreadSubject(null);
+ File acl = File.createTempFile(getClass().getName() + getName(), "acl");
+ acl.deleteOnExit();
- CurrentActor.set(new TestLogActor(messageLogger));
+ // Write ACL file
+ PrintWriter aclWriter = new PrintWriter(new FileWriter(acl));
+ for (String line : aclData)
+ {
+ aclWriter.println(line);
+ }
+ aclWriter.close();
+
+ // Load ruleset
+ ConfigurationFile configFile = new PlainConfiguration(acl);
+ RuleSet ruleSet = configFile.load();
}
- protected void tearDown() throws Exception
+ public void testMissingACLConfig() throws Exception
{
- super.tearDown();
- SecurityManager.setThreadSubject(null);
+ try
+ {
+ // Load ruleset
+ ConfigurationFile configFile = new PlainConfiguration(new File("doesnotexist"));
+ RuleSet ruleSet = configFile.load();
+
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.CONFIG_NOT_FOUND_MSG, "doesnotexist"), ce.getMessage());
+ assertTrue(ce.getCause() instanceof FileNotFoundException);
+ assertEquals("doesnotexist (No such file or directory)", ce.getCause().getMessage());
+ }
}
- /**
- * ACL plugin must always abstain if there is no subject attached to the thread.
- */
- public void testNoSubjectAlwaysAbstains()
+ public void testACLFileSyntaxContinuation() throws Exception
{
- SecurityManager.setThreadSubject(null);
-
- final Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.ABSTAIN, result);
+ try
+ {
+ writeACLConfig("ACL ALLOW ALL \\ ALL");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.PREMATURE_CONTINUATION_MSG, 1), ce.getMessage());
+ }
}
- /**
- * Tests that an allow rule expressed with a username allows an operation performed by a thread running
- * with the same username.
- */
- public void testUsernameAllowsOperation()
+ public void testACLFileSyntaxTokens() throws Exception
{
- SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject("user1"));
-
- final Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.ALLOWED, result);
+ try
+ {
+ writeACLConfig("ACL unparsed ALL ALL");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.PARSE_TOKEN_FAILED_MSG, 1), ce.getMessage());
+ assertTrue(ce.getCause() instanceof IllegalArgumentException);
+ assertEquals("Not a valid permission: unparsed", ce.getCause().getMessage());
+ }
}
- /**
- * 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()
+ public void testACLFileSyntaxNotEnoughGroup() throws Exception
{
- SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject("member1"));
+ try
+ {
+ writeACLConfig("GROUP blah");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_GROUP_MSG, 1), ce.getMessage());
+ }
+ }
- final Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.ALLOWED, result);
+ public void testACLFileSyntaxNotEnoughACL() throws Exception
+ {
+ try
+ {
+ writeACLConfig("ACL ALLOW");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_ACL_MSG, 1), ce.getMessage());
+ }
}
- /**
- * Tests that a deny rule expressed with an <b>External groupname</b> denies an operation performed by a thread running
- * by a user who belongs to the same group.
- */
- public void testExternalGroupMembershipDeniesOperation()
+ public void testACLFileSyntaxNotEnoughConfig() throws Exception
{
- SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject("user3", "extGroup1"));
-
- final Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.DENIED, result);
+ try
+ {
+ writeACLConfig("CONFIG");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage());
+ }
}
- /**
- * Tests that the catch all deny denies the operation and logs with the logging actor.
- */
- public void testCatchAllRuleDeniesUnrecognisedUsername()
+ public void testACLFileSyntaxNotEnough() throws Exception
{
- SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject("unknown", "unkgroup1", "unkgroup2"));
-
- assertEquals("Expecting zero messages before test", 0, messageLogger.getLogMessages().size());
- final Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.DENIED, result);
-
- assertEquals("Expecting one message before test", 1, messageLogger.getLogMessages().size());
- assertTrue("Logged message does not contain expected string", messageLogger.messageContains(0, "ACL-1002"));
+ try
+ {
+ writeACLConfig("INVALID");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage());
+ }
}
-
- /**
- * Creates a configuration plugin for the {@link AccessControl} plugin.
- */
- private ConfigurationPlugin createConfiguration(final RuleSet rs)
+
+ public void testACLFileSyntaxPropertyKeyOnly() throws Exception
{
- final ConfigurationPlugin cp = new ConfigurationPlugin()
- {
- public AccessControlConfiguration getConfiguration(final String plugin)
- {
- return new AccessControlConfiguration()
- {
- public RuleSet getRuleSet()
- {
- return rs;
- }
- };
- }
+ try
+ {
+ writeACLConfig("ACL ALLOW adk CREATE QUEUE name");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.PROPERTY_KEY_ONLY_MSG, 1), ce.getMessage());
+ }
+ }
- public String[] getElementsProcessed()
- {
- throw new UnsupportedOperationException();
- }
- };
+ public void testACLFileSyntaxPropertyNoEquals() throws Exception
+ {
+ try
+ {
+ writeACLConfig("ACL ALLOW adk CREATE QUEUE name test");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.PROPERTY_NO_EQUALS_MSG, 1), ce.getMessage());
+ }
+ }
- return cp;
+ public void testACLFileSyntaxPropertyNoValue() throws Exception
+ {
+ try
+ {
+ writeACLConfig("ACL ALLOW adk CREATE QUEUE name =");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.PROPERTY_NO_VALUE_MSG, 1), ce.getMessage());
+ }
}
}
diff --git a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java
deleted file mode 100644
index e16f9943ba..0000000000
--- a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.server.security.access.plugins;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileWriter;
-import java.io.PrintWriter;
-
-import junit.framework.TestCase;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.qpid.server.security.access.config.ConfigurationFile;
-import org.apache.qpid.server.security.access.config.PlainConfiguration;
-
-/**
- * These tests check that the ACL file parsing works correctly.
- *
- * For each message that can be returned in a {@link ConfigurationException}, an ACL file is created that should trigger this
- * particular message.
- */
-public class PlainConfigurationTest extends TestCase
-{
- public void writeACLConfig(String...aclData) throws Exception
- {
- File acl = File.createTempFile(getClass().getName() + getName(), "acl");
- acl.deleteOnExit();
-
- // Write ACL file
- PrintWriter aclWriter = new PrintWriter(new FileWriter(acl));
- for (String line : aclData)
- {
- aclWriter.println(line);
- }
- aclWriter.close();
-
- // Load ruleset
- ConfigurationFile configFile = new PlainConfiguration(acl);
- configFile.load();
- }
-
- public void testMissingACLConfig() throws Exception
- {
- try
- {
- // Load ruleset
- ConfigurationFile configFile = new PlainConfiguration(new File("doesnotexist"));
- configFile.load();
-
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.CONFIG_NOT_FOUND_MSG, "doesnotexist"), ce.getMessage());
- assertTrue(ce.getCause() instanceof FileNotFoundException);
- assertEquals("doesnotexist (No such file or directory)", ce.getCause().getMessage());
- }
- }
-
- public void testACLFileSyntaxContinuation() throws Exception
- {
- try
- {
- writeACLConfig("ACL ALLOW ALL \\ ALL");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.PREMATURE_CONTINUATION_MSG, 1), ce.getMessage());
- }
- }
-
- public void testACLFileSyntaxTokens() throws Exception
- {
- try
- {
- writeACLConfig("ACL unparsed ALL ALL");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.PARSE_TOKEN_FAILED_MSG, 1), ce.getMessage());
- assertTrue(ce.getCause() instanceof IllegalArgumentException);
- assertEquals("Not a valid permission: unparsed", ce.getCause().getMessage());
- }
- }
-
- 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
- {
- writeACLConfig("ACL ALLOW");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_ACL_MSG, 1), ce.getMessage());
- }
- }
-
- public void testACLFileSyntaxNotEnoughConfig() throws Exception
- {
- try
- {
- writeACLConfig("CONFIG");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage());
- }
- }
-
- public void testACLFileSyntaxNotEnough() throws Exception
- {
- try
- {
- writeACLConfig("INVALID");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage());
- }
- }
-
- public void testACLFileSyntaxPropertyKeyOnly() throws Exception
- {
- try
- {
- writeACLConfig("ACL ALLOW adk CREATE QUEUE name");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.PROPERTY_KEY_ONLY_MSG, 1), ce.getMessage());
- }
- }
-
- public void testACLFileSyntaxPropertyNoEquals() throws Exception
- {
- try
- {
- writeACLConfig("ACL ALLOW adk CREATE QUEUE name test");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.PROPERTY_NO_EQUALS_MSG, 1), ce.getMessage());
- }
- }
-
- public void testACLFileSyntaxPropertyNoValue() throws Exception
- {
- try
- {
- writeACLConfig("ACL ALLOW adk CREATE QUEUE name =");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.PROPERTY_NO_VALUE_MSG, 1), ce.getMessage());
- }
- }
-}
diff --git a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
index bd9deac153..aad7290557 100644
--- a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
+++ b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
@@ -21,21 +21,13 @@
package org.apache.qpid.server.security.access.plugins;
-import java.security.Principal;
-import java.util.Arrays;
-
-import javax.security.auth.Subject;
-
import org.apache.qpid.framing.AMQShortString;
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;
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.test.utils.QpidTestCase;
/**
@@ -44,24 +36,16 @@ import org.apache.qpid.test.utils.QpidTestCase;
* The ruleset is configured directly rather than using an external file by adding rules individually, calling the
* {@link RuleSet#grant(Integer, String, Permission, Operation, ObjectType, ObjectProperties)} method. Then, the
* 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).
-
+ * {@link RuleSet#check(String, Operation, ObjectType, ObjectProperties)} method.
*/
public class RuleSetTest extends QpidTestCase
{
- private RuleSet _ruleSet; // Object under test
-
- private static final String TEST_USER = "user";
+ private RuleSet _ruleSet;
// Common things that are passed to frame constructors
private AMQShortString _queueName = new AMQShortString(this.getClass().getName() + "queue");
private AMQShortString _exchangeName = new AMQShortString("amq.direct");
private AMQShortString _exchangeType = new AMQShortString("direct");
- private Subject _testSubject = TestPrincipalUtils.createTestSubject(TEST_USER);
@Override
public void setUp() throws Exception
@@ -79,36 +63,34 @@ public class RuleSetTest extends QpidTestCase
super.tearDown();
}
- public void assertDenyGrantAllow(Subject subject, Operation operation, ObjectType objectType)
+ public void assertDenyGrantAllow(String identity, Operation operation, ObjectType objectType)
{
- assertDenyGrantAllow(subject, operation, objectType, ObjectProperties.EMPTY);
+ assertDenyGrantAllow(identity, operation, objectType, ObjectProperties.EMPTY);
}
- public void assertDenyGrantAllow(Subject subject, Operation operation, ObjectType objectType, ObjectProperties properties)
+ public void assertDenyGrantAllow(String identity, Operation operation, ObjectType objectType, ObjectProperties properties)
{
- final Principal identity = UsernamePrincipal.getUsernamePrincipalFromSubject(subject);
-
- assertEquals(Result.DENIED, _ruleSet.check(subject, operation, objectType, properties));
- _ruleSet.grant(0, identity.getName(), Permission.ALLOW, operation, objectType, properties);
+ assertEquals(Result.DENIED, _ruleSet.check(identity, operation, objectType, properties));
+ _ruleSet.grant(0, identity, Permission.ALLOW, operation, objectType, properties);
assertEquals(1, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(subject, operation, objectType, properties));
+ assertEquals(Result.ALLOWED, _ruleSet.check(identity, operation, objectType, properties));
}
public void testEmptyRuleSet()
{
assertNotNull(_ruleSet);
assertEquals(_ruleSet.getRuleCount(), 0);
- assertEquals(_ruleSet.getDefault(), _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ assertEquals(_ruleSet.getDefault(), _ruleSet.check("user", Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
}
public void testVirtualHostAccess() throws Exception
{
- assertDenyGrantAllow(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST);
+ assertDenyGrantAllow("user", Operation.ACCESS, ObjectType.VIRTUALHOST);
}
public void testQueueCreateNamed() throws Exception
{
- assertDenyGrantAllow(_testSubject, Operation.CREATE, ObjectType.QUEUE, new ObjectProperties(_queueName));
+ assertDenyGrantAllow("user", Operation.CREATE, ObjectType.QUEUE, new ObjectProperties(_queueName));
}
public void testQueueCreatenamedNullRoutingKey()
@@ -116,7 +98,7 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties properties = new ObjectProperties(_queueName);
properties.put(ObjectProperties.Property.ROUTING_KEY, (String) null);
- assertDenyGrantAllow(_testSubject, Operation.CREATE, ObjectType.QUEUE, properties);
+ assertDenyGrantAllow("user", Operation.CREATE, ObjectType.QUEUE, properties);
}
public void testExchangeCreate()
@@ -124,17 +106,17 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties properties = new ObjectProperties(_exchangeName);
properties.put(ObjectProperties.Property.TYPE, _exchangeType.asString());
- assertDenyGrantAllow(_testSubject, Operation.CREATE, ObjectType.EXCHANGE, properties);
+ assertDenyGrantAllow("user", Operation.CREATE, ObjectType.EXCHANGE, properties);
}
public void testConsume()
{
- assertDenyGrantAllow(_testSubject, Operation.CONSUME, ObjectType.QUEUE);
+ assertDenyGrantAllow("user", Operation.CONSUME, ObjectType.QUEUE);
}
public void testPublish()
{
- assertDenyGrantAllow(_testSubject, Operation.PUBLISH, ObjectType.EXCHANGE);
+ assertDenyGrantAllow("user", Operation.PUBLISH, ObjectType.EXCHANGE);
}
/**
@@ -149,13 +131,13 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties normal = new ObjectProperties();
normal.put(ObjectProperties.Property.AUTO_DELETE, Boolean.FALSE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, temporary));
- _ruleSet.grant(0, TEST_USER, Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
+ _ruleSet.grant(0, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
assertEquals(1, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, temporary));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
// defer to global if exists, otherwise default answer - this is handled by the security manager
- assertEquals(Result.DEFER, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, normal));
+ assertEquals(Result.DEFER, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, normal));
}
/**
@@ -169,15 +151,15 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties normal = new ObjectProperties(_queueName);
normal.put(ObjectProperties.Property.AUTO_DELETE, Boolean.FALSE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, temporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
// should not matter if the temporary permission is processed first or last
- _ruleSet.grant(1, TEST_USER, Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, normal);
- _ruleSet.grant(2, TEST_USER, Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, normal);
+ _ruleSet.grant(2, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, normal));
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, temporary));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, normal));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
}
/**
@@ -191,15 +173,15 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties normal = new ObjectProperties(_queueName);
normal.put(ObjectProperties.Property.AUTO_DELETE, Boolean.FALSE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, temporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
// should not matter if the temporary permission is processed first or last
- _ruleSet.grant(1, TEST_USER, Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
- _ruleSet.grant(2, TEST_USER, Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, normal);
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
+ _ruleSet.grant(2, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, normal);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, normal));
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, temporary));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, normal));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
}
/*
@@ -215,15 +197,15 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties namedTemporary = new ObjectProperties(_queueName);
namedTemporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
- _ruleSet.grant(1, TEST_USER, Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
- _ruleSet.grant(2, TEST_USER, Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
+ _ruleSet.grant(2, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
}
/**
@@ -235,15 +217,15 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties namedTemporary = new ObjectProperties(_queueName);
namedTemporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
- _ruleSet.grant(1, TEST_USER, Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
- _ruleSet.grant(2, TEST_USER, Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
+ _ruleSet.grant(1, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ _ruleSet.grant(2, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
}
/**
@@ -257,18 +239,18 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties namedDurable = new ObjectProperties(_queueName);
namedDurable.put(ObjectProperties.Property.DURABLE, Boolean.TRUE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedDurable));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedDurable));
- _ruleSet.grant(1, TEST_USER, Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
- _ruleSet.grant(2, TEST_USER, Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedDurable);
- _ruleSet.grant(3, TEST_USER, Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
+ _ruleSet.grant(1, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ _ruleSet.grant(2, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedDurable);
+ _ruleSet.grant(3, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
assertEquals(3, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedDurable));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedDurable));
}
public void testNamedTemporaryQueueAllowed()
@@ -277,15 +259,15 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties namedTemporary = new ObjectProperties(_queueName);
namedTemporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
- _ruleSet.grant(1, TEST_USER, Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
- _ruleSet.grant(2, TEST_USER, Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ _ruleSet.grant(2, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
}
public void testNamedTemporaryQueueDeniedAllowed()
@@ -294,101 +276,14 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties namedTemporary = new ObjectProperties(_queueName);
namedTemporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
- _ruleSet.grant(1, TEST_USER, Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
- _ruleSet.grant(2, TEST_USER, Permission.DENY, Operation.CREATE, ObjectType.QUEUE, named);
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ _ruleSet.grant(2, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, named);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
- }
-
- /**
- * Tests support for the {@link Rule#ALL} keyword.
- */
- public void testAllowToAll()
- {
- _ruleSet.grant(1, Rule.ALL, 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));
- }
-
- /**
- * Tests support for ACL groups (i.e. inline groups declared in the ACL file itself).
- */
- public void testAclGroupsSupported()
- {
- 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());
-
- 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));
- }
-
- /**
- * 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));
- }
-
- /**
- * 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
- * to which the user belongs is later denied the permission.
- */
- public void testAllowDeterminedByRuleOrder()
- {
- assertTrue(_ruleSet.addGroup("aclgroup", Arrays.asList(new String[] {"usera"})));
-
- _ruleSet.grant(1, "usera", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- _ruleSet.grant(2, "aclgroup", 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));
- }
-
- /**
- * Rule order in the ACL determines the outcome of the check. This tests ensures that a user who is denied
- * access by group, is denied access, despite there being a later rule granting permission to that user.
- */
- public void testDenyDeterminedByRuleOrder()
- {
- assertTrue(_ruleSet.addGroup("aclgroup", Arrays.asList(new String[] {"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);
-
- assertEquals(2, _ruleSet.getRuleCount());
-
- assertEquals(Result.DENIED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
}
}
diff --git a/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/Activator.java b/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/Activator.java
index 21e7be26c1..c7d3fd38ff 100644
--- a/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/Activator.java
+++ b/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/Activator.java
@@ -59,14 +59,7 @@ public class Activator implements BundleActivator
_ctx = ctx;
_service = new InfoServiceImpl();
ctx.registerService(InfoService.class.getName(), _service, null);
-
- new Thread(new Runnable()
- {
- public void run()
- {
- sendInfo("STARTUP");
- }
- }).start();
+ sendInfo("STARTUP");
}
}
diff --git a/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java b/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java
index 9bdd4b9d17..a5d267282b 100644
--- a/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java
+++ b/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java
@@ -74,6 +74,8 @@ public class AppInfo
appInfoMap.put("port", sc.getPorts().toString());
appInfoMap.put("version", QpidProperties.getReleaseVersion());
appInfoMap.put("vhosts", "standalone");
+ appInfoMap.put("JMXPrincipalDatabase", sc
+ .getJMXPrincipalDatabase());
appInfoMap.put("KeystorePath", sc.getKeystorePath());
appInfoMap.put("PluginDirectory", sc.getPluginDirectory());
appInfoMap.put("CertType", sc.getCertType());
diff --git a/qpid/java/broker-plugins/experimental/shutdown/src/main/java/shutdown.bnd b/qpid/java/broker-plugins/experimental/shutdown/src/main/java/shutdown.bnd
index f6ae79536d..6e005f5bdb 100755
--- a/qpid/java/broker-plugins/experimental/shutdown/src/main/java/shutdown.bnd
+++ b/qpid/java/broker-plugins/experimental/shutdown/src/main/java/shutdown.bnd
@@ -17,7 +17,7 @@
# under the License.
#
-ver: 0.13.0
+ver: 0.9.0
Bundle-SymbolicName: qpid-shutdown-plugin
Bundle-Version: ${ver}
diff --git a/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java b/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
index e078675efc..ab8957e7ef 100644
--- a/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
+++ b/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
@@ -28,19 +28,12 @@ import java.net.InetSocketAddress;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
+import org.apache.qpid.server.util.InternalBrokerBaseCase;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
-public class FirewallConfigurationTest extends QpidTestCase
+public class FirewallConfigurationTest extends InternalBrokerBaseCase
{
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- ApplicationRegistry.remove();
- }
-
public void testFirewallConfiguration() throws Exception
{
// Write out config
@@ -50,11 +43,18 @@ public class FirewallConfigurationTest extends QpidTestCase
// Load config
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ try
+ {
+ ApplicationRegistry.initialise(reg, 1);
- // 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)));
+ // 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)));
+ }
+ finally
+ {
+ ApplicationRegistry.remove(1);
+ }
}
public void testCombinedConfigurationFirewall() throws Exception
@@ -80,8 +80,9 @@ public class FirewallConfigurationTest extends QpidTestCase
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<principal-databases>\n");
out.write("\t\t\t<principal-database>\n");
+ out.write("\t\t\t\t<name>passwordfile</name>\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");
@@ -90,7 +91,11 @@ public class FirewallConfigurationTest extends QpidTestCase
out.write("\t\t\t\t\t</attribute>\n");
out.write("\t\t\t\t</attributes>\n");
out.write("\t\t\t</principal-database>\n");
- out.write("\t\t</pd-auth-manager>\n");
+ out.write("\t\t</principal-databases>\n");
+ out.write("\t\t<jmx>\n");
+ out.write("\t\t\t<access>/dev/null</access>\n");
+ out.write("\t\t\t<principal-database>passwordfile</principal-database>\n");
+ out.write("\t\t</jmx>\n");
out.write("\t\t<firewall>\n");
out.write("\t\t\t<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
out.write("\t\t</firewall>\n");
@@ -111,10 +116,17 @@ public class FirewallConfigurationTest extends QpidTestCase
// Load config
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ try
+ {
+ ApplicationRegistry.initialise(reg, 1);
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ // Test config
+ assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ }
+ finally
+ {
+ ApplicationRegistry.remove(1);
+ }
}
public void testConfigurationFirewallReload() throws Exception
@@ -127,17 +139,24 @@ public class FirewallConfigurationTest extends QpidTestCase
// Load config
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ try
+ {
+ ApplicationRegistry.initialise(reg, 1);
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ // Test config
+ assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- // Switch to deny the connection
- writeConfigFile(mainFile, true);
+ // Switch to deny the connection
+ writeConfigFile(mainFile, true);
- reg.getConfiguration().reparseConfigFileSecuritySections();
+ reg.getConfiguration().reparseConfigFileSecuritySections();
- assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ }
+ finally
+ {
+ ApplicationRegistry.remove(1);
+ }
}
public void testCombinedConfigurationFirewallReload() throws Exception
@@ -162,8 +181,9 @@ public class FirewallConfigurationTest extends QpidTestCase
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<principal-databases>\n");
out.write("\t\t\t<principal-database>\n");
+ out.write("\t\t\t\t<name>passwordfile</name>\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");
@@ -172,7 +192,11 @@ public class FirewallConfigurationTest extends QpidTestCase
out.write("\t\t\t\t\t</attribute>\n");
out.write("\t\t\t\t</attributes>\n");
out.write("\t\t\t</principal-database>\n");
- out.write("\t\t</pd-auth-manager>\n");
+ out.write("\t\t</principal-databases>\n");
+ out.write("\t\t<jmx>\n");
+ out.write("\t\t\t<access>/dev/null</access>\n");
+ out.write("\t\t\t<principal-database>passwordfile</principal-database>\n");
+ out.write("\t\t</jmx>\n");
out.write("\t\t<firewall>\n");
out.write("\t\t\t<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
out.write("\t\t</firewall>\n");
@@ -193,40 +217,47 @@ public class FirewallConfigurationTest extends QpidTestCase
// Load config
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ try
+ {
+ ApplicationRegistry.initialise(reg, 1);
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ // 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();
+ 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();
+ 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();
+ reg.getConfiguration().reparseConfigFileSecuritySections();
- assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ 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();
+ 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();
+ 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();
+ reg.getConfiguration().reparseConfigFileSecuritySections();
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ }
+ finally
+ {
+ ApplicationRegistry.remove(1);
+ }
}
private void writeFirewallVhostsFile(File vhostsFile, boolean allow) throws IOException
@@ -260,8 +291,9 @@ public class FirewallConfigurationTest extends QpidTestCase
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<principal-databases>\n");
out.write("\t\t\t<principal-database>\n");
+ out.write("\t\t\t\t<name>passwordfile</name>\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");
@@ -270,7 +302,11 @@ public class FirewallConfigurationTest extends QpidTestCase
out.write("\t\t\t\t\t</attribute>\n");
out.write("\t\t\t\t</attributes>\n");
out.write("\t\t\t</principal-database>\n");
- out.write("\t\t</pd-auth-manager>\n");
+ out.write("\t\t</principal-databases>\n");
+ out.write("\t\t<jmx>\n");
+ out.write("\t\t\t<access>/dev/null</access>\n");
+ out.write("\t\t\t<principal-database>passwordfile</principal-database>\n");
+ out.write("\t\t</jmx>\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");
@@ -310,8 +346,8 @@ public class FirewallConfigurationTest extends QpidTestCase
// Load config
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
+ ApplicationRegistry.initialise(reg, 1);
+
// Test config
VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
diff --git a/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java b/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java
index 00077d9d9c..2b04962c89 100644
--- a/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java
+++ b/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java
@@ -27,15 +27,12 @@ import java.net.SocketAddress;
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 org.apache.qpid.server.util.InternalBrokerBaseCase;
-public class FirewallPluginTest extends QpidTestCase
+public class FirewallPluginTest extends InternalBrokerBaseCase
{
public class RuleInfo
{
@@ -76,23 +73,15 @@ public class FirewallPluginTest extends QpidTestCase
// IP address
private SocketAddress _address;
- private ServerConfiguration _serverConfig;
@Override
- protected void setUp() throws Exception
+ public 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
@@ -119,7 +108,7 @@ public class FirewallPluginTest extends QpidTestCase
}
buf.write("</firewall>");
buf.close();
-
+
// Configure plugin
FirewallConfiguration config = new FirewallConfiguration();
config.setConfiguration("", new XMLConfiguration(confFile));
diff --git a/qpid/java/broker-plugins/simple-xml/MANIFEST.MF b/qpid/java/broker-plugins/simple-xml/MANIFEST.MF
new file mode 100644
index 0000000000..04fe7518df
--- /dev/null
+++ b/qpid/java/broker-plugins/simple-xml/MANIFEST.MF
@@ -0,0 +1,36 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Qpid Broker-Plugins Simple XML
+Bundle-SymbolicName: broker-plugins-simple-xml
+Bundle-Description: Simple XML ACL 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.SimpleXMLActivator
+Bundle-RequiredExecutionEnvironment: JavaSE-1.5
+Bundle-ClassPath: .
+Bundle-ActivationPolicy: lazy
+Import-Package: org.apache.qpid,
+ org.apache.qpid.framing,
+ org.apache.qpid.junit.extensions.util,
+ org.apache.qpid.protocol,
+ org.apache.qpid.server.configuration,
+ org.apache.qpid.server.configuration.plugins,
+ org.apache.qpid.server.exchange,
+ org.apache.qpid.server.management,
+ 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
diff --git a/qpid/java/broker-plugins/simple-xml/build.xml b/qpid/java/broker-plugins/simple-xml/build.xml
new file mode 100644
index 0000000000..d3cd451648
--- /dev/null
+++ b/qpid/java/broker-plugins/simple-xml/build.xml
@@ -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.
+ -->
+<project name="Qpid Broker-Plugins Simple XML" default="build">
+ <property name="module.depends" value="common broker broker-plugins" />
+ <property name="module.test.depends" value="test broker/test common/test management/common systests" />
+
+ <property name="module.manifest" value="MANIFEST.MF" />
+ <property name="module.plugin" value="true" />
+
+ <import file="../../module.xml" />
+
+ <target name="bundle" depends="bundle-tasks" />
+</project>
diff --git a/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/config/PrincipalPermissions.java b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/config/PrincipalPermissions.java
new file mode 100755
index 0000000000..d9fc292f03
--- /dev/null
+++ b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/config/PrincipalPermissions.java
@@ -0,0 +1,687 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * 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.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.security.Result;
+
+@SuppressWarnings("unchecked")
+public class PrincipalPermissions
+{
+ public enum Permission
+ {
+ CONSUME,
+ PUBLISH,
+ CREATEQUEUE,
+ CREATEEXCHANGE,
+ ACCESS,
+ BIND,
+ UNBIND,
+ DELETE,
+ PURGE
+ }
+
+ private static final Logger _logger = Logger.getLogger(PrincipalPermissions.class);
+
+ private static final Object CONSUME_QUEUES_KEY = new Object();
+ private static final Object CONSUME_TEMPORARY_KEY = new Object();
+ private static final Object CONSUME_OWN_QUEUES_ONLY_KEY = new Object();
+
+ private static final Object CREATE_QUEUES_KEY = new Object();
+ private static final Object CREATE_EXCHANGES_KEY = new Object();
+
+
+ private static final Object CREATE_QUEUE_TEMPORARY_KEY = new Object();
+ private static final Object CREATE_QUEUE_QUEUES_KEY = new Object();
+ private static final Object CREATE_QUEUE_EXCHANGES_KEY = new Object();
+
+ private static final Object CREATE_QUEUE_EXCHANGES_ROUTINGKEYS_KEY = new Object();
+
+ private static final int PUBLISH_EXCHANGES_KEY = 0;
+
+ private Map _permissions;
+ private boolean _fullVHostAccess = false;
+
+ private String _user;
+
+
+ public PrincipalPermissions(String user)
+ {
+ _user = user;
+ _permissions = new ConcurrentHashMap();
+ }
+
+ /**
+ *
+ * @param permission the type of permission to check
+ *
+ * @param parameters vararg depending on what permission was passed in
+ * ACCESS: none
+ * BIND: none
+ * CONSUME: AMQShortString queueName, Boolean temporary, Boolean ownQueueOnly
+ * CREATEQUEUE: Boolean temporary, AMQShortString queueName, AMQShortString exchangeName, AMQShortString routingKey
+ * CREATEEXCHANGE: AMQShortString exchangeName, AMQShortString Class
+ * DELETE: none
+ * PUBLISH: Exchange exchange, AMQShortString routingKey
+ * PURGE: none
+ * UNBIND: none
+ */
+ public void grant(Permission permission, Object... parameters)
+ {
+ switch (permission)
+ {
+ case ACCESS:// Parameters : None
+ grantAccess(permission);
+ break;
+ case CONSUME: // Parameters : AMQShortString queueName, Boolean Temporary, Boolean ownQueueOnly
+ grantConsume(permission, parameters);
+ break;
+ case CREATEQUEUE: // Parameters : Boolean temporary, AMQShortString queueName
+ // , AMQShortString exchangeName , AMQShortString routingKey
+ grantCreateQueue(permission, parameters);
+ break;
+ case CREATEEXCHANGE:
+ // Parameters AMQShortString exchangeName , AMQShortString Class
+ grantCreateExchange(permission, parameters);
+ break;
+ case PUBLISH: // Parameters : Exchange exchange, AMQShortString routingKey
+ grantPublish(permission, parameters);
+ break;
+ /* The other cases just fall through to no-op */
+ case DELETE:
+ case BIND: // All the details are currently included in the create setup.
+ case PURGE:
+ case UNBIND:
+ break;
+ }
+
+ }
+
+ private void grantAccess(Permission permission)
+ {
+ _fullVHostAccess = true;
+ }
+
+ private void grantPublish(Permission permission, Object... parameters) {
+ Map publishRights = (Map) _permissions.get(permission);
+
+ if (publishRights == null)
+ {
+ publishRights = new ConcurrentHashMap();
+ _permissions.put(permission, publishRights);
+ }
+
+ if (parameters == null || parameters.length == 0)
+ {
+ //If we have no parameters then allow publish to all destinations
+ // this is signified by having a null value for publish_exchanges
+ }
+ else
+ {
+ Map publish_exchanges = (Map) publishRights.get(PUBLISH_EXCHANGES_KEY);
+
+ if (publish_exchanges == null)
+ {
+ publish_exchanges = new ConcurrentHashMap();
+ publishRights.put(PUBLISH_EXCHANGES_KEY, publish_exchanges);
+ }
+
+
+ HashSet routingKeys = (HashSet) publish_exchanges.get(parameters[0]);
+
+ // Check to see if we have a routing key
+ if (parameters.length == 2)
+ {
+ if (routingKeys == null)
+ {
+ routingKeys = new HashSet<AMQShortString>();
+ }
+ //Add routing key to permitted publish destinations
+ routingKeys.add(parameters[1]);
+ }
+
+ // Add the updated routingkey list or null if all values allowed
+ publish_exchanges.put(parameters[0], routingKeys);
+ }
+ }
+
+ private void grantCreateExchange(Permission permission, Object... parameters) {
+ Map rights = (Map) _permissions.get(permission);
+ if (rights == null)
+ {
+ rights = new ConcurrentHashMap();
+ _permissions.put(permission, rights);
+ }
+
+ Map create_exchanges = (Map) rights.get(CREATE_EXCHANGES_KEY);
+ if (create_exchanges == null)
+ {
+ create_exchanges = new ConcurrentHashMap();
+ rights.put(CREATE_EXCHANGES_KEY, create_exchanges);
+ }
+
+ //Should perhaps error if parameters[0] is null;
+ AMQShortString name = parameters.length > 0 ? (AMQShortString) parameters[0] : null;
+ AMQShortString className = parameters.length > 1 ? (AMQShortString) parameters[1] : new AMQShortString("direct");
+
+ //Store the exchangeName / class mapping if the mapping is null
+ rights.put(name, className);
+ }
+
+ private void grantCreateQueue(Permission permission, Object... parameters)
+ {
+ Map createRights = (Map) _permissions.get(permission);
+
+ if (createRights == null)
+ {
+ createRights = new ConcurrentHashMap();
+ _permissions.put(permission, createRights);
+ }
+
+ //The existence of the empty map mean permission to all.
+ if (parameters.length == 0)
+ {
+ return;
+ }
+
+ // Get the queues map
+ Map create_queues = (Map) createRights.get(CREATE_QUEUES_KEY);
+
+ //Initialiase the queue permissions if not already done
+ if (create_queues == null)
+ {
+ create_queues = new ConcurrentHashMap();
+ //initialise temp queue permission to false and overwrite below if true
+ create_queues.put(CREATE_QUEUE_TEMPORARY_KEY, false);
+ createRights.put(CREATE_QUEUES_KEY, create_queues);
+ }
+
+ //Create empty list of queues
+ Map create_queues_queues = (Map) create_queues.get(CREATE_QUEUE_QUEUES_KEY);
+
+ if (create_queues_queues == null)
+ {
+ create_queues_queues = new ConcurrentHashMap();
+ create_queues.put(CREATE_QUEUE_QUEUES_KEY, create_queues_queues);
+ }
+
+ // If we are initialising and granting CREATE rights to all temporary queues, then that's all we do
+ Boolean temporary = false;
+ if (parameters.length == 1)
+ {
+ temporary = (Boolean) parameters[0];
+ create_queues.put(CREATE_QUEUE_TEMPORARY_KEY, temporary);
+ return;
+ }
+
+ //From here we can be permissioning a variety of things, with varying parameters
+ AMQShortString queueName = parameters.length > 1 ? (AMQShortString) parameters[1] : null;
+ AMQShortString exchangeName = parameters.length > 2 ? (AMQShortString) parameters[2] : null;
+ //Set the routingkey to the specified value or the queueName if present
+ AMQShortString routingKey = (parameters.length > 3 && null != parameters[3]) ? (AMQShortString) parameters[3] : queueName;
+ // if we have a queueName then we need to store any associated exchange / rk bindings
+ if (queueName != null)
+ {
+ Map queue = (Map) create_queues_queues.get(queueName);
+ if (queue == null)
+ {
+ queue = new ConcurrentHashMap();
+ create_queues_queues.put(queueName, queue);
+ }
+
+ if (exchangeName != null)
+ {
+ queue.put(exchangeName, routingKey);
+ }
+
+ //If no exchange is specified then the presence of the queueName in the map says any exchange is ok
+ }
+
+ // Store the exchange that we are being granted rights to. This will be used as part of binding
+
+ //Lookup the list of exchanges
+ Map create_queues_exchanges = (Map) create_queues.get(CREATE_QUEUE_EXCHANGES_KEY);
+
+ if (create_queues_exchanges == null)
+ {
+ create_queues_exchanges = new ConcurrentHashMap();
+ create_queues.put(CREATE_QUEUE_EXCHANGES_KEY, create_queues_exchanges);
+ }
+
+ //if we have an exchange
+ if (exchangeName != null)
+ {
+ //Retrieve the list of permitted exchanges.
+ Map exchanges = (Map) create_queues_exchanges.get(exchangeName);
+
+ if (exchanges == null)
+ {
+ exchanges = new ConcurrentHashMap();
+ create_queues_exchanges.put(exchangeName, exchanges);
+ }
+
+ //Store the binding details of queue/rk for this exchange.
+ if (queueName != null)
+ {
+ //Retrieve the list of permitted routingKeys.
+ Map rKeys = (Map) exchanges.get(exchangeName);
+
+ if (rKeys == null)
+ {
+ rKeys = new ConcurrentHashMap();
+ exchanges.put(CREATE_QUEUE_EXCHANGES_ROUTINGKEYS_KEY, rKeys);
+ }
+
+ rKeys.put(queueName, routingKey);
+ }
+ }
+ }
+
+ /**
+ * Grant consume permissions
+ */
+ private void grantConsume(Permission permission, Object... parameters)
+ {
+ Map consumeRights = (Map) _permissions.get(permission);
+
+ if (consumeRights == null)
+ {
+ consumeRights = new ConcurrentHashMap();
+ _permissions.put(permission, consumeRights);
+
+ //initialise own and temporary rights to false to be overwritten below if set
+ consumeRights.put(CONSUME_TEMPORARY_KEY, false);
+ consumeRights.put(CONSUME_OWN_QUEUES_ONLY_KEY, false);
+ }
+
+
+ //if we only have one param then we're permissioning temporary queues and topics
+ if (parameters.length == 1)
+ {
+ Boolean temporary = (Boolean) parameters[0];
+
+ if (temporary)
+ {
+ consumeRights.put(CONSUME_TEMPORARY_KEY, true);
+ }
+ }
+
+ //if we have 2 parameters - should be a contract for this, but for now we'll handle it as is
+ if (parameters.length == 2)
+ {
+ AMQShortString queueName = (AMQShortString) parameters[0];
+ Boolean ownQueueOnly = (Boolean) parameters[1];
+
+ if (ownQueueOnly)
+ {
+ consumeRights.put(CONSUME_OWN_QUEUES_ONLY_KEY, true);
+ }
+
+ LinkedList queues = (LinkedList) consumeRights.get(CONSUME_QUEUES_KEY);
+ if (queues == null)
+ {
+ queues = new LinkedList();
+ consumeRights.put(CONSUME_QUEUES_KEY, queues);
+ }
+
+ if (queueName != null)
+ {
+ queues.add(queueName);
+ }
+ }
+ }
+
+ /**
+ *
+ * @param permission the type of permission to check
+ *
+ * @param parameters vararg depending on what permission was passed in
+ * ACCESS: none
+ * BIND: QueueBindBody bindmethod, Exchange exchange, AMQQueue queue, AMQShortString routingKey
+ * CONSUME: AMQQueue queue
+ * CREATEQUEUE: Boolean autodelete, AMQShortString name
+ * CREATEEXCHANGE: AMQShortString exchangeName
+ * DELETE: none
+ * PUBLISH: Exchange exchange, AMQShortString routingKey
+ * PURGE: none
+ * UNBIND: none
+ */
+ public Result authorise(Permission permission, String... parameters)
+ {
+
+ switch (permission)
+ {
+ case ACCESS://No Parameters
+ return Result.ALLOWED; // The existence of this user-specific PP infers some level of access is authorised
+ case BIND: // Parameters : QueueBindMethod , exhangeName , queueName, routingKey
+ return authoriseBind(parameters);
+ case CREATEQUEUE:// Parameters : autoDelete, queueName
+ return authoriseCreateQueue(permission, parameters);
+ case CREATEEXCHANGE: //Parameters: exchangeName
+ return authoriseCreateExchange(permission, parameters);
+ case CONSUME: // Parameters : queueName, autoDelete, owner
+ return authoriseConsume(permission, parameters);
+ case PUBLISH: // Parameters : exchangeName, routingKey
+ return authorisePublish(permission, parameters);
+ /* Fall through */
+ case DELETE:
+ case PURGE:
+ case UNBIND:
+ default:
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return Result.ALLOWED;
+ }
+ else
+ {
+ //SimpleXML ACL does not implement these permissions and should abstain
+ return Result.ABSTAIN;
+ }
+ }
+
+ }
+
+ private Result authoriseConsume(Permission permission, String... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return Result.ALLOWED;
+ }
+
+ if (parameters.length == 3)
+ {
+ AMQShortString queueName = new AMQShortString(parameters[0]);
+ Boolean autoDelete = Boolean.valueOf(parameters[1]);
+ AMQShortString owner = new AMQShortString(parameters[2]);
+ Map queuePermissions = (Map) _permissions.get(permission);
+
+ _logger.error("auth consume on " + StringUtils.join(parameters, ", "));
+
+ if (queuePermissions == null)
+ {
+ //we have a problem - we've never granted this type of permission .....
+ return Result.DENIED;
+ }
+
+ List queues = (List) queuePermissions.get(CONSUME_QUEUES_KEY);
+
+ Boolean temporaryQueues = (Boolean) queuePermissions.get(CONSUME_TEMPORARY_KEY);
+ Boolean ownQueuesOnly = (Boolean) queuePermissions.get(CONSUME_OWN_QUEUES_ONLY_KEY);
+
+
+ // If user is allowed to consume from temporary queues and this is a temp queue then allow it.
+ if (temporaryQueues && autoDelete)
+ {
+ // This will allow consumption from any temporary queue including ones not owned by this user.
+ // Of course the exclusivity will not be broken.
+ {
+
+ // if not limited to ownQueuesOnly then ok else check queue Owner.
+ return (!ownQueuesOnly || owner.equals(_user)) ? Result.ALLOWED : Result.DENIED;
+ }
+ }
+ //if this is a temporary queue and the user does not have permissions for temporary queues then deny
+ else if (!temporaryQueues && autoDelete)
+ {
+ return Result.DENIED;
+ }
+
+ // if queues are white listed then ensure it is ok
+ if (queues != null)
+ {
+ // if no queues are listed then ALL are ok othereise it must be specified.
+ if (ownQueuesOnly)
+ {
+ if (owner.equals(_user))
+ {
+ return (queues.size() == 0 || queues.contains(queueName)) ? Result.ALLOWED : Result.DENIED;
+ }
+ else
+ {
+ return Result.DENIED;
+ }
+ }
+
+ // If we are
+ return (queues.size() == 0 || queues.contains(queueName)) ? Result.ALLOWED : Result.DENIED;
+ }
+ }
+
+ // Can't authenticate without the right parameters
+ return Result.DENIED;
+ }
+
+ private Result authorisePublish(Permission permission, String... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return Result.ALLOWED;
+ }
+
+ Map publishRights = (Map) _permissions.get(permission);
+
+ if (publishRights == null)
+ {
+ return Result.DENIED;
+ }
+
+ Map exchanges = (Map) publishRights.get(PUBLISH_EXCHANGES_KEY);
+
+ // Having no exchanges listed gives full publish rights to all exchanges
+ if (exchanges == null)
+ {
+ return Result.ALLOWED;
+ }
+ // Otherwise exchange must be listed in the white list
+
+ // If the map doesn't have the exchange then it isn't allowed
+ AMQShortString exchangeName = new AMQShortString(parameters[0]);
+ if (!exchanges.containsKey(exchangeName))
+ {
+ return Result.DENIED;
+ }
+ else
+ {
+ // Get valid routing keys
+ HashSet routingKeys = (HashSet) exchanges.get(exchangeName);
+
+ // Having no routingKeys in the map then all are allowed.
+ if (routingKeys == null)
+ {
+ return Result.ALLOWED;
+ }
+ else
+ {
+ // We have routingKeys so a match must be found to allowed binding
+ Iterator keys = routingKeys.iterator();
+
+ AMQShortString publishRKey = new AMQShortString(parameters[1]);
+
+ boolean matched = false;
+ while (keys.hasNext() && !matched)
+ {
+ AMQShortString rkey = (AMQShortString) keys.next();
+
+ if (rkey.endsWith("*"))
+ {
+ matched = publishRKey.startsWith(rkey.subSequence(0, rkey.length() - 1));
+ }
+ else
+ {
+ matched = publishRKey.equals(rkey);
+ }
+ }
+ return (matched) ? Result.ALLOWED : Result.DENIED;
+ }
+ }
+ }
+
+ private Result authoriseCreateExchange(Permission permission, String... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return Result.ALLOWED;
+ }
+
+ Map rights = (Map) _permissions.get(permission);
+
+ AMQShortString exchangeName = new AMQShortString(parameters[0]);
+
+ // If the exchange list is doesn't exist then all is allowed else
+ // check the valid exchanges
+ if (rights == null || rights.containsKey(exchangeName))
+ {
+ return Result.ALLOWED;
+ }
+ else
+ {
+ return Result.DENIED;
+ }
+ }
+
+ private Result authoriseCreateQueue(Permission permission, String... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return Result.ALLOWED;
+ }
+
+ Map createRights = (Map) _permissions.get(permission);
+
+ // If there are no create rights then deny request
+ if (createRights == null)
+ {
+ return Result.DENIED;
+ }
+
+ //Look up the Queue Creation Rights
+ Map create_queues = (Map) createRights.get(CREATE_QUEUES_KEY);
+
+ //Lookup the list of queues allowed to be created
+ Map create_queues_queues = (Map) create_queues.get(CREATE_QUEUE_QUEUES_KEY);
+
+
+ Boolean autoDelete = Boolean.valueOf(parameters[0]);
+ AMQShortString queueName = new AMQShortString(parameters[1]);
+
+ if (autoDelete)// we have a temporary queue
+ {
+ return ((Boolean) create_queues.get(CREATE_QUEUE_TEMPORARY_KEY)) ? Result.ALLOWED : Result.DENIED;
+ }
+ else
+ {
+ // If there is a white list then check
+ if (create_queues_queues == null || create_queues_queues.containsKey(queueName))
+ {
+ return Result.ALLOWED;
+ }
+ else
+ {
+ return Result.DENIED;
+ }
+
+ }
+ }
+
+ private Result authoriseBind(String... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return Result.ALLOWED;
+ }
+
+ AMQShortString exchangeName = new AMQShortString(parameters[1]);
+ AMQShortString bind_queueName = new AMQShortString(parameters[2]);
+ AMQShortString routingKey = new AMQShortString(parameters[3]);
+
+ //Get all Create Rights for this user
+ Map bindCreateRights = (Map) _permissions.get(Permission.CREATEQUEUE);
+
+ //Lookup the list of queues
+ Map bind_create_queues_queues = (Map) bindCreateRights.get(CREATE_QUEUE_QUEUES_KEY);
+
+ // Check and see if we have a queue white list to check
+ if (bind_create_queues_queues != null)
+ {
+ //There a white list for queues
+ Map exchangeDetails = (Map) bind_create_queues_queues.get(bind_queueName);
+
+ if (exchangeDetails == null) //Then all queue can be bound to all exchanges.
+ {
+ return Result.ALLOWED;
+ }
+
+ // Check to see if we have a white list of routingkeys to check
+ Map rkeys = (Map) exchangeDetails.get(exchangeName);
+
+ // if keys is null then any rkey is allowed on this exchange
+ if (rkeys == null)
+ {
+ // There is no routingkey white list
+ return Result.ALLOWED;
+ }
+ else
+ {
+ // We have routingKeys so a match must be found to allowed binding
+ Iterator keys = rkeys.keySet().iterator();
+
+ boolean matched = false;
+ while (keys.hasNext() && !matched)
+ {
+ AMQShortString rkey = (AMQShortString) keys.next();
+ if (rkey.endsWith("*"))
+ {
+ matched = routingKey.startsWith(rkey.subSequence(0, rkey.length() - 1).toString());
+ }
+ else
+ {
+ matched = routingKey.equals(rkey);
+ }
+ }
+
+
+ return (matched) ? Result.ALLOWED : Result.DENIED;
+ }
+
+
+ }
+ else
+ {
+ //no white list so all allowed.
+ return Result.ALLOWED;
+ }
+ }
+}
diff --git a/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java
new file mode 100644
index 0000000000..ab43653122
--- /dev/null
+++ b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java
@@ -0,0 +1,427 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * 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 static org.apache.qpid.server.security.access.ObjectProperties.Property.*;
+
+import java.security.Principal;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+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.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.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.PrincipalPermissions;
+import org.apache.qpid.server.security.access.config.PrincipalPermissions.Permission;
+
+/**
+ * This uses the default
+ */
+public class SimpleXML extends AbstractPlugin
+{
+ public static final Logger _logger = Logger.getLogger(SimpleXML.class);
+
+ private Map<String, PrincipalPermissions> _users;
+
+ public static final SecurityPluginFactory<SimpleXML> FACTORY = new SecurityPluginFactory<SimpleXML>()
+ {
+ public SimpleXML newInstance(ConfigurationPlugin config) throws ConfigurationException
+ {
+ SimpleXMLConfiguration configuration = config.getConfiguration(SimpleXMLConfiguration.class.getName());
+
+ // If there is no configuration for this plugin then don't load it.
+ if (configuration == null)
+ {
+ return null;
+ }
+
+ SimpleXML plugin = new SimpleXML();
+ plugin.configure(configuration);
+ return plugin;
+ }
+
+ public String getPluginName()
+ {
+ return SimpleXML.class.getName();
+ }
+
+ public Class<SimpleXML> getPluginClass()
+ {
+ return SimpleXML.class;
+ }
+ };
+
+ public void configure(ConfigurationPlugin config)
+ {
+ super.configure(config);
+
+ SimpleXMLConfiguration configuration = (SimpleXMLConfiguration) _config;
+
+ _users = new ConcurrentHashMap<String, PrincipalPermissions>();
+
+ processConfig(configuration.getConfiguration());
+ }
+
+ private void processConfig(Configuration config)
+ {
+ processPublish(config);
+ processConsume(config);
+ processCreate(config);
+ processAccess(config);
+ }
+
+ /**
+ * @param config XML Configuration
+ */
+ private void processAccess(Configuration config)
+ {
+ Configuration accessConfig = config.subset("access");
+
+ if (accessConfig.isEmpty())
+ {
+ //there is no access configuration to process
+ return;
+ }
+
+ // Process users that have full access permission
+ String[] users = accessConfig.getStringArray("users.user");
+
+ for (String user : users)
+ {
+ grant(Permission.ACCESS, user);
+ }
+ }
+
+ /**
+ * Publish format takes Exchange + Routing Key Pairs
+ *
+ * @param config XML Configuration
+ */
+ private void processPublish(Configuration config)
+ {
+ Configuration publishConfig = config.subset("publish");
+
+ // Process users that have full publish permission
+ String[] users = publishConfig.getStringArray("users.user");
+
+ for (String user : users)
+ {
+ grant(Permission.PUBLISH, user);
+ }
+
+ // Process exchange limited users
+ int exchangeCount = 0;
+ Configuration exchangeConfig = publishConfig.subset("exchanges.exchange(" + exchangeCount + ")");
+
+ while (!exchangeConfig.isEmpty())
+ {
+ // Get Exchange Name
+ AMQShortString exchangeName = new AMQShortString(exchangeConfig.getString("name"));
+
+ // Get Routing Keys
+ int keyCount = 0;
+ Configuration routingkeyConfig = exchangeConfig.subset("routing_keys.routing_key(" + keyCount + ")");
+
+ while (!routingkeyConfig.isEmpty())
+ {
+ // Get RoutingKey Value
+ AMQShortString routingKeyValue = new AMQShortString(routingkeyConfig.getString("value"));
+
+ // Apply Exchange + RoutingKey permissions to Users
+ users = routingkeyConfig.getStringArray("users.user");
+ for (String user : users)
+ {
+ grant(Permission.PUBLISH, user, exchangeName, routingKeyValue);
+ }
+
+ // Apply permissions to Groups
+
+ // Check for more configs
+ keyCount++;
+ routingkeyConfig = exchangeConfig.subset("routing_keys.routing_key(" + keyCount + ")");
+ }
+
+ // Apply Exchange wide permissions to Users
+ users = exchangeConfig.getStringArray("exchange(" + exchangeCount + ").users.user");
+
+ for (String user : users)
+ {
+ grant(Permission.PUBLISH, user, exchangeName);
+ }
+
+ // Apply permissions to Groups
+ exchangeCount++;
+ exchangeConfig = publishConfig.subset("exchanges.exchange(" + exchangeCount + ")");
+ }
+ }
+
+ private void grant(Permission permission, String user, Object... parameters)
+ {
+ PrincipalPermissions permissions = _users.get(user);
+
+ if (permissions == null)
+ {
+ permissions = new PrincipalPermissions(user);
+ }
+
+ _users.put(user, permissions);
+ permissions.grant(permission, parameters);
+ }
+
+ /**
+ * @param config XML Configuration
+ */
+ private void processConsume(Configuration config)
+ {
+ boolean temporary = false;
+ Configuration tempConfig = null;
+ Configuration consumeConfig = config.subset("consume");
+
+ tempConfig = consumeConfig.subset("queues.temporary(0)");
+ if (tempConfig != null)
+ {
+ temporary = true;
+ }
+
+ //Permission all users who have rights to temp queues and topics
+ if (tempConfig != null && !tempConfig.isEmpty())
+ {
+ String[] tempUsers = tempConfig.getStringArray("users.user");
+ for (String user : tempUsers)
+ {
+ grant(Permission.CONSUME, user, temporary);
+ }
+ }
+
+ // Process queue limited users
+ int queueCount = 0;
+ Configuration queueConfig = consumeConfig.subset("queues.queue(" + queueCount + ")");
+
+ while (!queueConfig.isEmpty())
+ {
+ // Get queue Name
+ AMQShortString queueName = new AMQShortString(queueConfig.getString("name"));
+ // if there is no name then there may be a temporary element
+
+ boolean ownQueues = queueConfig.containsKey("own_queues");
+
+ // Process permissions for this queue
+ String[] users = queueConfig.getStringArray("users.user");
+ for (String user : users)
+ {
+ grant(Permission.CONSUME, user, queueName, ownQueues);
+ }
+
+ // See if we have another config
+ queueCount++;
+ queueConfig = consumeConfig.subset("queues.queue(" + queueCount + ")");
+ }
+
+ // Process users that have full consume permission
+ String[] users = consumeConfig.getStringArray("users.user");
+
+ for (String user : users)
+ {
+ //NOTE: this call does not appear to do anything inside the grant section for consume
+ grant(Permission.CONSUME, user);
+ }
+ }
+
+ /**
+ * @param config XML Configuration
+ */
+ private void processCreate(Configuration config)
+ {
+ boolean temporary = false;
+ Configuration tempConfig = null;
+
+ Configuration createConfig = config.subset("create");
+
+ tempConfig = createConfig.subset("queues.temporary(0)");
+ if (tempConfig != null)
+ {
+ temporary = true;
+ }
+
+ //Permission all users who have rights to temp queues and topics
+ if (tempConfig != null && !tempConfig.isEmpty())
+ {
+ String[] tempUsers = tempConfig.getStringArray("users.user");
+ for (String user : tempUsers)
+ {
+ grant(Permission.CREATEQUEUE, user, temporary);
+ }
+ }
+ // Process create permissions for queue creation
+ int queueCount = 0;
+ Configuration queueConfig = createConfig.subset("queues.queue(" + queueCount + ")");
+
+ while (!queueConfig.isEmpty())
+ {
+ // Get queue Name
+ AMQShortString queueName = new AMQShortString(queueConfig.getString("name"));
+
+ int exchangeCount = 0;
+ Configuration exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")");
+
+ while (!exchangeConfig.isEmpty())
+ {
+
+ AMQShortString exchange = new AMQShortString(exchangeConfig.getString("name"));
+ AMQShortString routingKey = new AMQShortString(exchangeConfig.getString("routing_key"));
+
+ // Process permissions for this queue
+ String[] users = exchangeConfig.getStringArray("users.user");
+ for (String user : users)
+ {
+ //This is broken as the user name is not stored
+ grant(Permission.CREATEEXCHANGE, user, exchange);
+
+ //This call could be cleaned up as temporary is now being set earlier (above)
+ grant(Permission.CREATEQUEUE, user, temporary, (queueName.equals("") ? null : queueName), (exchange
+ .equals("") ? null : exchange), (routingKey.equals("") ? null : routingKey));
+ }
+
+ // See if we have another config
+ exchangeCount++;
+ exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")");
+ }
+
+ // Process users that are not bound to an exchange
+ String[] users = queueConfig.getStringArray("users.user");
+
+ for (String user : users)
+ {
+ grant(Permission.CREATEQUEUE, user, temporary, queueName);
+ }
+
+ // See if we have another config
+ queueCount++;
+ queueConfig = createConfig.subset("queues.queue(" + queueCount + ")");
+ }
+
+ // Process create permissions for exchange creation
+ int exchangeCount = 0;
+ Configuration exchangeConfig = createConfig.subset("exchanges.exchange(" + exchangeCount + ")");
+
+ while (!exchangeConfig.isEmpty())
+ {
+ AMQShortString exchange = new AMQShortString(exchangeConfig.getString("name"));
+ AMQShortString clazz = new AMQShortString(exchangeConfig.getString("class"));
+
+ // Process permissions for this queue
+ String[] users = exchangeConfig.getStringArray("users.user");
+ for (String user : users)
+ {
+ //And this is broken too
+ grant(Permission.CREATEEXCHANGE, user, exchange, clazz);
+ }
+
+ // See if we have another config
+ exchangeCount++;
+ exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")");
+ }
+
+ // Process users that have full create permission
+ String[] users = createConfig.getStringArray("users.user");
+
+ for (String user : users)
+ {
+ grant(Permission.CREATEEXCHANGE, user);
+ grant(Permission.CREATEQUEUE, user);
+ }
+ }
+
+ public Result access(ObjectType objectType, Object instance)
+ {
+ Principal principal = SecurityManager.getThreadPrincipal();
+ if (principal == null)
+ {
+ return getDefault(); // Default if there is no user associated with the thread
+ }
+ PrincipalPermissions principalPermissions = _users.get(principal.getName());
+ if (principalPermissions == null)
+ {
+ return Result.DENIED;
+ }
+
+ // Authorise object access
+ if (objectType == ObjectType.VIRTUALHOST)
+ {
+ return principalPermissions.authorise(Permission.ACCESS);
+ }
+
+ // Default
+ return getDefault();
+ }
+
+ public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
+ {
+ Principal principal = SecurityManager.getThreadPrincipal();
+ if (principal == null)
+ {
+ return getDefault(); // Default if there is no user associated with the thread
+ }
+ PrincipalPermissions principalPermissions = _users.get(principal.getName());
+ if (principalPermissions == null)
+ {
+ return Result.DENIED;
+ }
+
+ // Authorise operation
+ switch (operation)
+ {
+ case CONSUME:
+ return principalPermissions.authorise(Permission.CONSUME, properties.get(NAME), properties.get(AUTO_DELETE), properties.get(OWNER));
+ case PUBLISH:
+ return principalPermissions.authorise(Permission.PUBLISH, properties.get(NAME), properties.get(ROUTING_KEY));
+ case CREATE:
+ if (objectType == ObjectType.EXCHANGE)
+ {
+ return principalPermissions.authorise(Permission.CREATEEXCHANGE, properties.get(NAME));
+ }
+ else if (objectType == ObjectType.QUEUE)
+ {
+ return principalPermissions.authorise(Permission.CREATEQUEUE, properties.get(AUTO_DELETE), properties.get(NAME));
+ }
+ case ACCESS:
+ return principalPermissions.authorise(Permission.ACCESS);
+ case BIND:
+ return principalPermissions.authorise(Permission.BIND, null, properties.get(NAME), properties.get(QUEUE_NAME), properties.get(ROUTING_KEY));
+ case UNBIND:
+ return principalPermissions.authorise(Permission.UNBIND);
+ case DELETE:
+ return principalPermissions.authorise(Permission.DELETE);
+ case PURGE:
+ return principalPermissions.authorise(Permission.PURGE);
+ }
+
+ // Default
+ return getDefault();
+ }
+}
diff --git a/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLActivator.java b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLActivator.java
new file mode 100644
index 0000000000..c09a9da0d8
--- /dev/null
+++ b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLActivator.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.access.plugins;
+
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import org.apache.qpid.server.security.SecurityPluginActivator;
+import org.apache.qpid.server.security.SecurityPluginFactory;
+import org.osgi.framework.BundleActivator;
+
+/**
+ * The OSGi {@link BundleActivator} for {@link SimpleXML}.
+ */
+public class SimpleXMLActivator extends SecurityPluginActivator
+{
+ public SecurityPluginFactory getFactory()
+ {
+ return SimpleXML.FACTORY;
+ }
+
+ public ConfigurationPluginFactory getConfigurationFactory()
+ {
+ return SimpleXMLConfiguration.FACTORY;
+ }
+}
diff --git a/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLConfiguration.java b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLConfiguration.java
new file mode 100644
index 0000000000..e95c21b590
--- /dev/null
+++ b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLConfiguration.java
@@ -0,0 +1,57 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * 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.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;
+
+public class SimpleXMLConfiguration extends ConfigurationPlugin
+{
+ public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
+ {
+ public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
+ {
+ ConfigurationPlugin instance = new SimpleXMLConfiguration();
+ instance.setConfiguration(path, config);
+ return instance;
+ }
+
+ public List<String> getParentPaths()
+ {
+ return Arrays.asList("security.access_control_list", "virtualhosts.virtualhost.security.access_control_list");
+ }
+ };
+
+ public String[] getElementsProcessed()
+ {
+ return new String[] { "" };
+ }
+
+ public Configuration getConfiguration()
+ {
+ return _configuration;
+ }
+}
diff --git a/qpid/java/broker-plugins/simple-xml/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java b/qpid/java/broker-plugins/simple-xml/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java
new file mode 100644
index 0000000000..65ab12a095
--- /dev/null
+++ b/qpid/java/broker-plugins/simple-xml/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.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.security.access;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.security.Result;
+import org.apache.qpid.server.security.access.config.PrincipalPermissions;
+import org.apache.qpid.server.security.access.config.PrincipalPermissions.Permission;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class PrincipalPermissionsTest extends QpidTestCase
+{
+ private String _user = "user";
+ private PrincipalPermissions _perms;
+
+ // Common things that are passed to frame constructors
+ private AMQShortString _queueName = new AMQShortString(this.getClass().getName() + "queue");
+ private AMQShortString _tempQueueName = new AMQShortString(this.getClass().getName() + "tempqueue");
+ private AMQShortString _exchangeName = new AMQShortString("amq.direct");
+ private AMQShortString _routingKey = new AMQShortString(this.getClass().getName() + "route");
+ private boolean _autoDelete = false;
+ private AMQShortString _exchangeType = new AMQShortString("direct");
+ private Boolean _temporary = false;
+ private Boolean _ownQueue = false;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ _perms = new PrincipalPermissions(_user);
+ }
+
+
+ public void testPrincipalPermissions()
+ {
+ assertNotNull(_perms);
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.ACCESS, (String[]) null));
+ }
+
+ // FIXME: test has been disabled since the permissions assume that the user has tried to create
+ // the queue first. QPID-1597
+ public void disableTestBind() throws Exception
+ {
+ String[] args = new String[]{null, _exchangeName.asString(), _queueName.asString(), _routingKey.asString()};
+
+ assertEquals(Result.DENIED, _perms.authorise(Permission.BIND, args));
+ _perms.grant(Permission.BIND, (Object[]) null);
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.BIND, args));
+ }
+
+ public void testQueueCreate()
+ {
+ Object[] grantArgs = new Object[]{_temporary , _queueName, _exchangeName, _routingKey};
+ String[] authArgs = new String[]{Boolean.toString(_autoDelete), _queueName.asString()};
+
+ assertEquals(Result.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgs));
+ _perms.grant(Permission.CREATEQUEUE, grantArgs);
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgs));
+ }
+
+ public void testQueueCreateWithNullRoutingKey()
+ {
+ Object[] grantArgs = new Object[]{_temporary , _queueName, _exchangeName, null};
+ String[] authArgs = new String[]{Boolean.toString(_autoDelete), _queueName.asString()};
+
+ assertEquals(Result.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgs));
+ _perms.grant(Permission.CREATEQUEUE, grantArgs);
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgs));
+ }
+
+ // FIXME disabled, this fails due to grant putting the grant into the wrong map QPID-1598
+ public void disableTestExchangeCreate()
+ {
+ String[] authArgs = new String[]{_exchangeName.asString()};
+ Object[] grantArgs = new Object[]{_exchangeName, _exchangeType};
+
+ assertEquals(Result.DENIED, _perms.authorise(Permission.CREATEEXCHANGE, authArgs));
+ _perms.grant(Permission.CREATEEXCHANGE, grantArgs);
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgs));
+ }
+
+ public void testConsume()
+ {
+ String[] authArgs = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user};
+ Object[] grantArgs = new Object[]{_queueName, _ownQueue};
+
+ // FIXME: This throws a null pointer exception QPID-1599
+ // assertFalse(_perms.authorise(Permission.CONSUME, authArgs));
+ _perms.grant(Permission.CONSUME, grantArgs);
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authArgs));
+ }
+
+ public void testPublish() throws AMQException
+ {
+ String[] authArgs = new String[]{_exchangeName.asString(), _routingKey.asString()};
+ Object[] grantArgs = new Object[]{_exchangeName, _routingKey};
+
+ assertEquals(Result.DENIED, _perms.authorise(Permission.PUBLISH, authArgs));
+ _perms.grant(Permission.PUBLISH, grantArgs);
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.PUBLISH, authArgs));
+ }
+
+ public void testVhostAccess()
+ {
+ //Tests that granting a user Virtualhost level access allows all authorisation requests
+ //where previously they would be denied
+
+ //QPID-2133 createExchange rights currently allow all exchange creation unless rights for creating some
+ //specific exchanges are granted. Grant a specific exchange creation to cause all others to be denied.
+ Object[] createArgsCreateExchange = new Object[]{new AMQShortString("madeup"), _exchangeType};
+ String[] authArgsCreateExchange = new String[]{_exchangeName.asString()};
+ assertEquals("Exchange creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange));
+ _perms.grant(Permission.CREATEEXCHANGE, createArgsCreateExchange);
+
+ String[] authArgsPublish = new String[]{_exchangeName.asString(), _routingKey.asString()};
+ String[] authArgsConsume = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user};
+ String[] authArgsCreateQueue = new String[]{Boolean.toString(_autoDelete), _queueName.asString()};
+// QueueBindBodyImpl bind = new QueueBindBodyImpl(_ticket, _queueName, _exchangeName, _routingKey, _nowait, _arguments);
+ String[] authArgsBind = new String[]{ null, _exchangeName.asString(), _queueName.asString(), _routingKey.asString()};
+
+ assertEquals("Exchange creation was not denied", Result.DENIED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange));
+ assertEquals("Publish was not denied", Result.DENIED, _perms.authorise(Permission.PUBLISH, authArgsPublish));
+ assertEquals("Consume creation was not denied", Result.DENIED, _perms.authorise(Permission.CONSUME, authArgsConsume));
+ assertEquals("Queue creation was not denied", Result.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgsCreateQueue));
+ //BIND pre-grant authorise check disabled due to QPID-1597
+ //assertEquals("Binding creation was not denied", Result.DENIED, _perms.authorise(Permission.BIND, authArgsBind));
+
+ _perms.grant(Permission.ACCESS);
+
+ assertEquals("Exchange creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange));
+ assertEquals("Publish was not allowed", Result.ALLOWED, _perms.authorise(Permission.PUBLISH, authArgsPublish));
+ assertEquals("Consume creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.CONSUME, authArgsConsume));
+ assertEquals("Queue creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgsCreateQueue));
+ assertEquals("Binding creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.BIND, authArgsBind));
+ }
+
+ /**
+ * If the consume permission for temporary queues is for an unnamed queue then is should
+ * be global for any temporary queue but not for any non-temporary queue
+ */
+ public void testTemporaryUnnamedQueueConsume()
+ {
+ String[] authNonTempQArgs = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user};
+ String[] authTempQArgs = new String[]{_tempQueueName.asString(), Boolean.TRUE.toString(), _user};
+ Object[] grantArgs = new Object[]{true};
+
+ _perms.grant(Permission.CONSUME, grantArgs);
+
+ //Next line shows up bug - non temp queue should be denied
+ assertEquals(Result.DENIED, _perms.authorise(Permission.CONSUME, authNonTempQArgs));
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs));
+ }
+
+ /**
+ * Test that temporary queue permissions before queue perms in the ACL config work correctly
+ */
+ public void testTemporaryQueueFirstConsume()
+ {
+ String[] authNonTempQArgs = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user};
+ String[] authTempQArgs = new String[]{_tempQueueName.asString(), Boolean.TRUE.toString(), _user};
+ Object[] grantArgs = new Object[]{true};
+ Object[] grantNonTempQArgs = new Object[]{_queueName, _ownQueue};
+
+ //should not matter if the temporary permission is processed first or last
+ _perms.grant(Permission.CONSUME, grantNonTempQArgs);
+ _perms.grant(Permission.CONSUME, grantArgs);
+
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authNonTempQArgs));
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs));
+ }
+
+ /**
+ * Test that temporary queue permissions after queue perms in the ACL config work correctly
+ */
+ public void testTemporaryQueueLastConsume()
+ {
+ String[] authNonTempQArgs = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user};
+ String[] authTempQArgs = new String[]{_tempQueueName.asString(), Boolean.TRUE.toString(), _user};
+ Object[] grantArgs = new Object[]{true};
+ Object[] grantNonTempQArgs = new Object[]{_queueName, _ownQueue};
+
+ //should not matter if the temporary permission is processed first or last
+ _perms.grant(Permission.CONSUME, grantArgs);
+ _perms.grant(Permission.CONSUME, grantNonTempQArgs);
+
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authNonTempQArgs));
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs));
+ }
+}
diff --git a/qpid/java/broker/bin/qpid-server.bat b/qpid/java/broker/bin/qpid-server.bat
index af543decb3..c81f5fc3e7 100644
--- a/qpid/java/broker/bin/qpid-server.bat
+++ b/qpid/java/broker/bin/qpid-server.bat
@@ -108,13 +108,13 @@ goto beforeRunShift
:runJdpa
REM USAGE: adds debugging options to the java command, use
-REM USAGE: JPDA_TRANSPORT and JPDA_ADDRESS to customize the debugging
+REM USAGE: JDPA_TRANSPORT and JPDA_ADDRESS to customize the debugging
REM USAGE: behavior and use JPDA_OPTS to override it entirely
-if not "%JPDA_OPTS%" == "" goto beforeRunShift
-if "%JPDA_TRANSPORT%" == "" set JPDA_TRANSPORT=dt_socket
+if "%JPDA_OPTS%" == "" goto beforeRunShift
+if "%JPDA_TRANSPORT%" == "" set JPDA_TRANSPORT=-dt_socket
if "%JPDA_ADDRESS%" == "" set JPDA_ADDRESS=8000
-set JPDA_OPTS=-Xdebug -Xrunjdwp:transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=n
-REM set QPID_OPTS="%QPID_OPTS% %JPDA_OPTS%"
+set JPDA_OPTS="-Xdebug -Xrunjdwp:transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=n"
+set QPID_OPTS="%QPID_OPTS% %JPDA_OPTS%"
goto beforeRunShift
:runExternalClasspath
@@ -192,7 +192,7 @@ rem QPID_OPTS intended to hold any -D props for use
rem user must enclose any value for QPID_OPTS in double quotes
:runCommand
set MODULE_JARS=%QPID_MODULE_JARS%
-set COMMAND="%JAVA_HOME%\bin\java" %JAVA_VM% %JAVA_MEM% %JAVA_GC% %QPID_OPTS% %JPDA_OPTS% %SYSTEM_PROPS% -cp "%CLASSPATH%;%MODULE_JARS%" org.apache.qpid.server.Main %QPID_ARGS%
+set COMMAND="%JAVA_HOME%\bin\java" %JAVA_VM% %JAVA_MEM% %JAVA_GC% %QPID_OPTS% %SYSTEM_PROPS% -cp "%CLASSPATH%;%MODULE_JARS%" org.apache.qpid.server.Main %QPID_ARGS%
if "%debug%" == "true" echo %CLASSPATH%;%LAUNCH_JAR%;%MODULE_JARS%
if "%debug%" == "true" echo %COMMAND%
diff --git a/qpid/java/broker/etc/access b/qpid/java/broker/etc/access
new file mode 100644
index 0000000000..58b7443fa9
--- /dev/null
+++ b/qpid/java/broker/etc/access
@@ -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.
+
+guest:localhost(rw),test(rw) \ No newline at end of file
diff --git a/qpid/java/broker/etc/config.xml b/qpid/java/broker/etc/config.xml
index 61f1c832b1..14b9456067 100644
--- a/qpid/java/broker/etc/config.xml
+++ b/qpid/java/broker/etc/config.xml
@@ -37,10 +37,17 @@
<keystorePath>/path/to/keystore.ks</keystorePath>
<keystorePassword>keystorepass</keystorePassword>
</ssl>
+ <qpidnio>false</qpidnio>
+ <protectio>
+ <enabled>false</enabled>
+ <readBufferLimitSize>262144</readBufferLimitSize>
+ <writeBufferLimitSize>262144</writeBufferLimitSize>
+ </protectio>
+ <transport>nio</transport>
<port>5672</port>
<sslport>8672</sslport>
- <socketReceiveBuffer>262144</socketReceiveBuffer>
- <socketSendBuffer>262144</socketSendBuffer>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
</connector>
<management>
<enabled>true</enabled>
@@ -62,8 +69,10 @@
</advanced>
<security>
- <pd-auth-manager>
+ <principal-databases>
+ <!-- Example use of Base64 encoded MD5 hashes for authentication via CRAM-MD5-Hashed -->
<principal-database>
+ <name>passwordfile</name>
<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
<attributes>
<attribute>
@@ -72,11 +81,16 @@
</attribute>
</attributes>
</principal-database>
- </pd-auth-manager>
+ </principal-databases>
<allow-all />
<msg-auth>false</msg-auth>
+
+ <jmx>
+ <access>${conf}/jmxremote.access</access>
+ <principal-database>passwordfile</principal-database>
+ </jmx>
</security>
<virtualhosts>${conf}/virtualhosts.xml</virtualhosts>
diff --git a/qpid/java/broker/etc/jmxremote.access b/qpid/java/broker/etc/jmxremote.access
new file mode 100644
index 0000000000..1a51a6991b
--- /dev/null
+++ b/qpid/java/broker/etc/jmxremote.access
@@ -0,0 +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.
+
+#Generated by JMX Console : Last edited by user:admin
+#Tue Jun 12 16:46:39 BST 2007
+admin=admin
+guest=readonly
+user=readwrite
diff --git a/qpid/java/broker/etc/passwdVhost b/qpid/java/broker/etc/passwdVhost
new file mode 100644
index 0000000000..48ce8299b6
--- /dev/null
+++ b/qpid/java/broker/etc/passwdVhost
@@ -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.
+#
+guest:guest:localhost,test
diff --git a/qpid/java/broker/etc/qpid-server.conf.jpp b/qpid/java/broker/etc/qpid-server.conf.jpp
index 0378c82fd9..3ed2431ef3 100644
--- a/qpid/java/broker/etc/qpid-server.conf.jpp
+++ b/qpid/java/broker/etc/qpid-server.conf.jpp
@@ -17,7 +17,8 @@
# under the License.
#
-QPID_LIBS=$(build-classpath commons-beanutils \
+QPID_LIBS=$(build-classpath backport-util-concurrent \
+ commons-beanutils \
commons-beanutils-core \
commons-cli \
commons-codec \
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
index f0f7678cd9..a6f319cb1f 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
@@ -1096,11 +1096,6 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return Boolean.FALSE;
}
- public Long getFlowStoppedCount()
- {
- return 0L;
- }
-
public BrokerSchema.QueueClass.PurgeMethodResponseCommand purge(final BrokerSchema.QueueClass.PurgeMethodResponseCommandFactory factory,
final Long request)
{
@@ -1311,12 +1306,6 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
{
return _obj.isShadow();
}
-
- public Boolean getUserProxyAuth()
- {
- // TODO
- return false;
- }
}
private class SessionDelegate implements BrokerSchema.SessionDelegate
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
index d1ea5dba69..a612f280d6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
@@ -327,74 +327,4 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
{
return getObjectNameForSingleInstanceMBean();
}
-
- public void resetStatistics() throws Exception
- {
- getVirtualHost().resetStatistics();
- }
-
- public double getPeakMessageDeliveryRate()
- {
- return getVirtualHost().getMessageDeliveryStatistics().getPeak();
- }
-
- public double getPeakDataDeliveryRate()
- {
- return getVirtualHost().getDataDeliveryStatistics().getPeak();
- }
-
- public double getMessageDeliveryRate()
- {
- return getVirtualHost().getMessageDeliveryStatistics().getRate();
- }
-
- public double getDataDeliveryRate()
- {
- return getVirtualHost().getDataDeliveryStatistics().getRate();
- }
-
- public long getTotalMessagesDelivered()
- {
- return getVirtualHost().getMessageDeliveryStatistics().getTotal();
- }
-
- public long getTotalDataDelivered()
- {
- return getVirtualHost().getDataDeliveryStatistics().getTotal();
- }
-
- public double getPeakMessageReceiptRate()
- {
- return getVirtualHost().getMessageReceiptStatistics().getPeak();
- }
-
- public double getPeakDataReceiptRate()
- {
- return getVirtualHost().getDataReceiptStatistics().getPeak();
- }
-
- public double getMessageReceiptRate()
- {
- return getVirtualHost().getMessageReceiptStatistics().getRate();
- }
-
- public double getDataReceiptRate()
- {
- return getVirtualHost().getDataReceiptStatistics().getRate();
- }
-
- public long getTotalMessagesReceived()
- {
- return getVirtualHost().getMessageReceiptStatistics().getTotal();
- }
-
- public long getTotalDataReceived()
- {
- return getVirtualHost().getDataReceiptStatistics().getTotal();
- }
-
- public boolean isStatisticsEnabled()
- {
- return getVirtualHost().isStatisticsEnabled();
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
index 8141533045..4f86c82578 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
@@ -22,7 +22,6 @@ package org.apache.qpid.server;
import org.apache.log4j.Logger;
-import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.framing.AMQMethodBody;
@@ -142,7 +141,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
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);
@@ -202,11 +200,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
return !(_transaction instanceof AutoCommitTransaction);
}
- public boolean inTransaction()
- {
- return isTransactional() && _txnUpdateTime.get() > 0 && _transaction.getTransactionStartTime() > 0;
- }
-
private void incrementOutstandingTxnsIfNecessary()
{
if(isTransactional())
@@ -302,6 +295,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
});
deliverCurrentMessageIfComplete();
+
}
}
@@ -339,15 +333,11 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
{
_transaction.enqueue(destinationQueues, _currentMessage, new MessageDeliveryAction(_currentMessage, destinationQueues, isTransactional()));
incrementOutstandingTxnsIfNecessary();
- updateTransactionalActivity();
}
}
}
finally
{
- long bodySize = _currentMessage.getSize();
- long timestamp = ((BasicContentHeaderProperties) _currentMessage.getContentHeader().getProperties()).getTimestamp();
- _session.registerMessageReceived(bodySize, timestamp);
_currentMessage = null;
}
}
@@ -804,7 +794,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
{
Collection<QueueEntry> ackedMessages = getAckedMessages(deliveryTag, multiple);
_transaction.dequeue(ackedMessages, new MessageAcknowledgeAction(ackedMessages));
- updateTransactionalActivity();
}
private Collection<QueueEntry> getAckedMessages(long deliveryTag, boolean multiple)
@@ -979,17 +968,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
}
- /**
- * Update last transaction activity timestamp
- */
- private void updateTransactionalActivity()
- {
- if (isTransactional())
- {
- _txnUpdateTime.set(System.currentTimeMillis());
- }
- }
-
public String toString()
{
return "["+_session.toString()+":"+_channelId+"]";
@@ -1040,7 +1018,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
{
getProtocolSession().getProtocolOutputConverter().writeDeliver(entry, getChannelId(),
deliveryTag, sub.getConsumerTag());
- _session.registerMessageDelivered(entry.getMessage().getSize());
}
};
@@ -1079,11 +1056,11 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
private boolean checkMessageUserId(ContentHeaderBody header)
{
AMQShortString userID =
- header.getProperties() instanceof BasicContentHeaderProperties
- ? ((BasicContentHeaderProperties) header.getProperties()).getUserId()
+ header.properties instanceof BasicContentHeaderProperties
+ ? ((BasicContentHeaderProperties) header.properties).getUserId()
: null;
- return (!MSG_AUTH || _session.getAuthorizedPrincipal().getName().equals(userID == null? "" : userID.toString()));
+ return (!MSG_AUTH || _session.getPrincipal().getName().equals(userID == null? "" : userID.toString()));
}
@@ -1430,36 +1407,4 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
{
_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();
-
- // Log a warning on idle or open transactions
- if (idleWarn > 0L && idleTime > idleWarn)
- {
- CurrentActor.get().message(_logSubject, ChannelMessages.IDLE_TXN(idleTime));
- _logger.warn("IDLE TRANSACTION ALERT " + _logSubject.toString() + " " + idleTime + " ms");
- }
- else if (openWarn > 0L && openTime > openWarn)
- {
- CurrentActor.get().message(_logSubject, ChannelMessages.OPEN_TXN(openTime));
- _logger.warn("OPEN TRANSACTION ALERT " + _logSubject.toString() + " " + openTime + " ms");
- }
-
- // Close connection for idle or open transactions that have timed out
- if (idleClose > 0L && idleTime > idleClose)
- {
- getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Idle transaction timed out");
- }
- else if (openClose > 0L && openTime > openClose)
- {
- getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Open transaction timed out");
- }
- }
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java
deleted file mode 100644
index ffc323a23b..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java
+++ /dev/null
@@ -1,420 +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 static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-
-import org.apache.log4j.PropertyConfigurator;
-import org.apache.log4j.xml.QpidLog4JConfigurator;
-import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.configuration.ServerNetworkTransportConfiguration;
-import org.apache.qpid.server.configuration.management.ConfigurationManagementMBean;
-import org.apache.qpid.server.information.management.ServerInformationMBean;
-import org.apache.qpid.server.logging.SystemOutMessageLogger;
-import org.apache.qpid.server.logging.actors.BrokerActor;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.GenericActor;
-import org.apache.qpid.server.logging.management.LoggingManagementMBean;
-import org.apache.qpid.server.logging.messages.BrokerMessages;
-import org.apache.qpid.server.protocol.AMQProtocolEngineFactory;
-import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory;
-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.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 org.apache.qpid.transport.network.mina.MinaNetworkTransport;
-
-public class Broker
-{
- private static final int IPV4_ADDRESS_LENGTH = 4;
- private static final char IPV4_LITERAL_SEPARATOR = '.';
-
- protected static class InitException extends RuntimeException
- {
- private static final long serialVersionUID = 1L;
-
- InitException(String msg, Throwable cause)
- {
- super(msg, cause);
- }
- }
-
- public void shutdown()
- {
- ApplicationRegistry.remove();
- }
-
- public void startup() throws Exception
- {
- startup(new BrokerOptions());
- }
-
- public void startup(BrokerOptions options) throws Exception
- {
- try
- {
- CurrentActor.set(new BrokerActor(new SystemOutMessageLogger()));
- startupImpl(options);
- }
- finally
- {
- CurrentActor.remove();
- }
- }
-
- 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());
-
- ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(configFile);
- ServerConfiguration serverConfig = config.getConfiguration();
- updateManagementPort(serverConfig, options.getJmxPort());
-
- 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
- {
- configureLoggingManagementMBean(logConfigFile, options.getLogWatchFrequency());
-
- ConfigurationManagementMBean configMBean = new ConfigurationManagementMBean();
- configMBean.register();
-
- ServerInformationMBean sysInfoMBean = new ServerInformationMBean(config);
- sysInfoMBean.register();
-
- Set<Integer> ports = new HashSet<Integer>(options.getPorts());
- if(ports.isEmpty())
- {
- parsePortList(ports, serverConfig.getPorts());
- }
-
- Set<Integer> sslPorts = new HashSet<Integer>(options.getSSLPorts());
- if(sslPorts.isEmpty())
- {
- parsePortList(sslPorts, serverConfig.getSSLPorts());
- }
-
- 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> 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> exclude_0_9 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_9));
- if(exclude_0_9.isEmpty())
- {
- parsePortList(exclude_0_9, serverConfig.getPortExclude09());
- }
-
- Set<Integer> exclude_0_8 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_8));
- if(exclude_0_8.isEmpty())
- {
- parsePortList(exclude_0_8, serverConfig.getPortExclude08());
- }
-
- String bindAddr = options.getBind();
- if (bindAddr == null)
- {
- bindAddr = serverConfig.getBind();
- }
-
- InetAddress bindAddress = null;
- if (bindAddr.equals(WILDCARD_ADDRESS))
- {
- bindAddress = new InetSocketAddress(0).getAddress();
- }
- else
- {
- bindAddress = InetAddress.getByAddress(parseIP(bindAddr));
- }
- String hostName = bindAddress.getCanonicalHostName();
-
- if (!serverConfig.getSSLOnly())
- {
- for(int port : ports)
- {
- Set<AmqpProtocolVersion> supported = EnumSet.allOf(AmqpProtocolVersion.class);
-
- if(exclude_0_10.contains(port))
- {
- supported.remove(AmqpProtocolVersion.v0_10);
- }
-
- if(exclude_0_9_1.contains(port))
- {
- supported.remove(AmqpProtocolVersion.v0_9_1);
- }
- if(exclude_0_9.contains(port))
- {
- supported.remove(AmqpProtocolVersion.v0_9);
- }
- if(exclude_0_8.contains(port))
- {
- supported.remove(AmqpProtocolVersion.v0_8);
- }
-
- NetworkTransportConfiguration settings =
- new ServerNetworkTransportConfiguration(serverConfig, port, bindAddress.getHostName(), Transport.TCP);
-
- IncomingNetworkTransport transport = Transport.getIncomingTransportInstance();
- MultiVersionProtocolEngineFactory protocolEngineFactory =
- new MultiVersionProtocolEngineFactory(hostName, supported);
-
- transport.accept(settings, protocolEngineFactory, null);
- ApplicationRegistry.getInstance().addAcceptor(new InetSocketAddress(bindAddress, port),
- new QpidAcceptor(transport,"TCP"));
- CurrentActor.get().message(BrokerMessages.LISTENING("TCP", port));
- }
- }
-
- if (serverConfig.getEnableSSL())
- {
- String keystorePath = serverConfig.getKeystorePath();
- String keystorePassword = serverConfig.getKeystorePassword();
- String certType = serverConfig.getCertType();
- SSLContextFactory sslFactory =
- new SSLContextFactory(keystorePath, keystorePassword, certType);
-
- for(int sslPort : sslPorts)
- {
- NetworkTransportConfiguration settings =
- new ServerNetworkTransportConfiguration(serverConfig, sslPort, bindAddress.getHostName(), Transport.TCP);
-
- IncomingNetworkTransport transport = new MinaNetworkTransport();
-
- transport.accept(settings, new AMQProtocolEngineFactory(), sslFactory);
-
- ApplicationRegistry.getInstance().addAcceptor(new InetSocketAddress(bindAddress, sslPort),
- new QpidAcceptor(transport,"TCP"));
- CurrentActor.get().message(BrokerMessages.LISTENING("TCP/SSL", sslPort));
- }
- }
-
- CurrentActor.get().message(BrokerMessages.READY());
- }
- finally
- {
- // Startup is complete so remove the AR initialised Startup actor
- CurrentActor.remove();
- }
- }
-
- private File getConfigFile(final String fileName,
- final String defaultFileName,
- final String qpidHome, boolean throwOnFileNotFound) throws InitException
- {
- File configFile = null;
- if (fileName != null)
- {
- configFile = new File(fileName);
- }
- else
- {
- configFile = new File(qpidHome, defaultFileName);
- }
-
- if (!configFile.exists() && throwOnFileNotFound)
- {
- String error = "File " + fileName + " could not be found. Check the file exists and is readable.";
-
- if (qpidHome == null)
- {
- error = error + "\nNote: " + BrokerOptions.QPID_HOME + " is not set.";
- }
-
- throw new InitException(error, null);
- }
-
- return configFile;
- }
-
- public static void parsePortList(Set<Integer> output, List<?> ports) throws InitException
- {
- if(ports != null)
- {
- for(Object o : ports)
- {
- try
- {
- output.add(Integer.parseInt(String.valueOf(o)));
- }
- catch (NumberFormatException e)
- {
- throw new InitException("Invalid port: " + o, e);
- }
- }
- }
- }
-
- /**
- * Update the configuration data with the management port.
- * @param configuration
- * @param managementPort The string from the command line
- */
- private void updateManagementPort(ServerConfiguration configuration, Integer managementPort)
- {
- if (managementPort != null)
- {
- try
- {
- configuration.setJMXManagementPort(managementPort);
- }
- catch (NumberFormatException e)
- {
- throw new InitException("Invalid management port: " + managementPort, null);
- }
- }
- }
-
- private byte[] parseIP(String address) throws Exception
- {
- char[] literalBuffer = address.toCharArray();
- int byteCount = 0;
- int currByte = 0;
- byte[] ip = new byte[IPV4_ADDRESS_LENGTH];
- for (int i = 0; i < literalBuffer.length; i++)
- {
- char currChar = literalBuffer[i];
- if ((currChar >= '0') && (currChar <= '9'))
- {
- currByte = (currByte * 10) + (Character.digit(currChar, 10) & 0xFF);
- }
-
- if (currChar == IPV4_LITERAL_SEPARATOR || (i + 1 == literalBuffer.length))
- {
- ip[byteCount++] = (byte) currByte;
- currByte = 0;
- }
- }
-
- if (byteCount != 4)
- {
- throw new Exception("Invalid IP address: " + address);
- }
- return ip;
- }
-
- private void configureLogging(File logConfigFile, long logWatchTime) throws InitException, IOException
- {
- if (logConfigFile.exists() && logConfigFile.canRead())
- {
- CurrentActor.get().message(BrokerMessages.LOG_CONFIG(logConfigFile.getAbsolutePath()));
-
- if (logWatchTime > 0)
- {
- System.out.println("log file " + logConfigFile.getAbsolutePath() + " will be checked for changes every "
- + logWatchTime + " seconds");
- // log4j expects the watch interval in milliseconds
- try
- {
- QpidLog4JConfigurator.configureAndWatch(logConfigFile.getPath(), logWatchTime * 1000);
- }
- catch (Exception e)
- {
- throw new InitException(e.getMessage(),e);
- }
- }
- else
- {
- try
- {
- QpidLog4JConfigurator.configure(logConfigFile.getPath());
- }
- catch (Exception e)
- {
- throw new InitException(e.getMessage(),e);
- }
- }
- }
- else
- {
- System.err.println("Logging configuration error: unable to read file " + logConfigFile.getAbsolutePath());
- System.err.println("Using the fallback internal log4j.properties configuration");
-
- InputStream propsFile = this.getClass().getResourceAsStream("/log4j.properties");
- if(propsFile == null)
- {
- throw new IOException("Unable to load the fallback internal log4j.properties configuration file");
- }
- else
- {
- try
- {
- Properties fallbackProps = new Properties();
- fallbackProps.load(propsFile);
- PropertyConfigurator.configure(fallbackProps);
- }
- finally
- {
- propsFile.close();
- }
- }
- }
- }
-
- private void configureLoggingManagementMBean(File logConfigFile, int logWatchTime) throws Exception
- {
- LoggingManagementMBean blm = new LoggingManagementMBean(logConfigFile.getPath(),logWatchTime);
-
- blm.register();
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java
deleted file mode 100644
index b83da92660..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java
+++ /dev/null
@@ -1,152 +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.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-public class BrokerOptions
-{
- /** serialVersionUID */
- private static final long serialVersionUID = 8051825964945442234L;
-
- public static final String DEFAULT_CONFIG_FILE = "etc/config.xml";
- public static final String DEFAULT_LOG_CONFIG_FILE = "etc/log4j.xml";
- public static final String QPID_HOME = "QPID_HOME";
-
- public static final String PORTS = "p";
- public static final String SSL_PORTS = "s";
- public static final String BIND = "b";
- public static final String MANAGEMENT = "m";
- public static final String LOG_CONFIG = "l";
- public static final String WATCH = "w";
- public static final String CONFIG = "c";
-
- 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 String _configFile;
- private String _logConfigFile;
- private String _bind;
- private Integer _jmxPort;
-
- private Integer _logWatchFrequency = 0;
-
- public void addPort(final int port)
- {
- _ports.add(port);
- }
-
- public void addSSLPort(final int sslPort)
- {
- _sslPorts.add(sslPort);
- }
-
- 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;
- }
-
- public String getLogConfigFile()
- {
- return _logConfigFile;
- }
-
- public void setLogConfigFile(final String logConfigFile)
- {
- _logConfigFile = logConfigFile;
- }
-
- public Integer getJmxPort()
- {
- return _jmxPort;
- }
-
- public void setJmxPort(final int jmxPort)
- {
- _jmxPort = jmxPort;
- }
-
- public String getQpidHome()
- {
- return System.getProperty(QPID_HOME);
- }
-
- public Set<Integer> getExcludedPorts(final ProtocolExclusion excludeProtocol)
- {
- final Set<Integer> excludedPorts = _exclusionMap.get(excludeProtocol);
- return excludedPorts == null ? Collections.<Integer>emptySet() : excludedPorts;
- }
-
- public void addExcludedPort(final ProtocolExclusion excludeProtocol, final int port)
- {
- if (!_exclusionMap.containsKey(excludeProtocol))
- {
- _exclusionMap.put(excludeProtocol, new HashSet<Integer>());
- }
-
- Set<Integer> ports = _exclusionMap.get(excludeProtocol);
- ports.add(port);
- }
-
- public String getBind()
- {
- return _bind;
- }
-
- public void setBind(final String bind)
- {
- _bind = bind;
- }
-
- public int getLogWatchFrequency()
- {
- return _logWatchFrequency;
- }
-
- /**
- * 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)
- {
- _logWatchFrequency = logWatchFrequency;
- }
-} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java
index 449b52d737..71cf17ed60 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java
@@ -20,6 +20,17 @@
*/
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.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
@@ -28,9 +39,28 @@ import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.Broker.InitException;
+import org.apache.log4j.PropertyConfigurator;
+import org.apache.log4j.xml.QpidLog4JConfigurator;
+import org.apache.qpid.common.QpidProperties;
+import org.apache.qpid.framing.ProtocolVersion;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.management.ConfigurationManagementMBean;
+import org.apache.qpid.server.information.management.ServerInformationMBean;
+import org.apache.qpid.server.logging.SystemOutMessageLogger;
+import org.apache.qpid.server.logging.actors.BrokerActor;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.GenericActor;
+import org.apache.qpid.server.logging.management.LoggingManagementMBean;
+import org.apache.qpid.server.logging.messages.BrokerMessages;
+import org.apache.qpid.server.protocol.AMQProtocolEngineFactory;
+import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory;
+import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory.VERSION;
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.NetworkDriver;
+import org.apache.qpid.transport.network.mina.MINANetworkDriver;
/**
* Main entry point for AMQPD.
@@ -38,41 +68,37 @@ import org.apache.qpid.server.registry.ApplicationRegistry;
*/
public class Main
{
- private final Options options = new Options();
- private CommandLine commandLine;
+ private static Logger _logger;
- public static void main(String[] args)
+ private static final String DEFAULT_CONFIG_FILE = "etc/config.xml";
+
+ public static final String DEFAULT_LOG_CONFIG_FILENAME = "log4j.xml";
+ public static final String QPID_HOME = "QPID_HOME";
+ private static final int IPV4_ADDRESS_LENGTH = 4;
+
+ private static final char IPV4_LITERAL_SEPARATOR = '.';
+
+ protected static class InitException extends Exception
{
- //if the -Dlog4j.configuration property has not been set, enable the init override
- //to stop Log4J wondering off and picking up the first log4j.xml/properties file it
- //finds from the classpath when we get the first Loggers
- if(System.getProperty("log4j.configuration") == null)
+ InitException(String msg, Throwable cause)
{
- System.setProperty("log4j.defaultInitOverride", "true");
+ super(msg, cause);
}
-
- new Main(args);
}
- public Main(final String[] args)
+ protected final Options options = new Options();
+ protected CommandLine commandLine;
+
+ protected Main(String[] args)
{
setOptions(options);
if (parseCommandline(args))
{
- try
- {
- execute();
- }
- catch(Exception e)
- {
- System.err.println("Exception during startup: " + e);
- e.printStackTrace();
- shutdown(1);
- }
+ execute();
}
}
- protected boolean parseCommandline(final String[] args)
+ protected boolean parseCommandline(String[] args)
{
try
{
@@ -90,7 +116,8 @@ public class Main
}
}
- protected void setOptions(final Options options)
+ @SuppressWarnings("static-access")
+ protected void setOptions(Options options)
{
Option help = new Option("h", "help", false, "print this message");
Option version = new Option("v", "version", false, "print the version information and exit");
@@ -134,21 +161,16 @@ public class Main
Option bind =
OptionBuilder.withArgName("bind").hasArg()
.withDescription("bind to the specified address. Overrides any value in the config file")
- .withLongOpt("bind").create(BrokerOptions.BIND);
+ .withLongOpt("bind").create("b");
Option logconfig =
OptionBuilder.withArgName("logconfig").hasArg()
.withDescription("use the specified log4j xml configuration file. By "
- + "default looks for a file named " + BrokerOptions.DEFAULT_LOG_CONFIG_FILE
- + " in the same directory as the configuration file").withLongOpt("logconfig").create(BrokerOptions.LOG_CONFIG);
+ + "default looks for a file named " + DEFAULT_LOG_CONFIG_FILENAME
+ + " in the same directory as the configuration file").withLongOpt("logconfig").create("l");
Option logwatchconfig =
OptionBuilder.withArgName("logwatch").hasArg()
.withDescription("monitor the log file configuration file for changes. Units are seconds. "
- + "Zero means do not check for changes.").withLongOpt("logwatch").create(BrokerOptions.WATCH);
-
- Option sslport =
- OptionBuilder.withArgName("sslport").hasArg()
- .withDescription("SSL port. Overrides any value in the config file")
- .withLongOpt("sslport").create(BrokerOptions.SSL_PORTS);
+ + "Zero means do not check for changes.").withLongOpt("logwatch").create("w");
options.addOption(help);
options.addOption(version);
@@ -162,120 +184,435 @@ public class Main
options.addOption(exclude0_8);
options.addOption(mport);
options.addOption(bind);
- options.addOption(sslport);
}
- protected void execute() throws Exception
+ protected void execute()
{
- BrokerOptions options = new BrokerOptions();
- String configFile = commandLine.getOptionValue(BrokerOptions.CONFIG);
- if(configFile != null)
+ // note this understands either --help or -h. If an option only has a long name you can use that but if
+ // an option has a short name and a long name you must use the short name here.
+ if (commandLine.hasOption("h"))
{
- options.setConfigFile(configFile);
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp("Qpid", options, true);
}
+ else if (commandLine.hasOption("v"))
+ {
+ String ver = QpidProperties.getVersionString();
+
+ StringBuilder protocol = new StringBuilder("AMQP version(s) [major.minor]: ");
- String logWatchConfig = commandLine.getOptionValue(BrokerOptions.WATCH);
- if(logWatchConfig != null)
+ boolean first = true;
+ for (ProtocolVersion pv : ProtocolVersion.getSupportedProtocolVersions())
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ protocol.append(", ");
+ }
+
+ protocol.append(pv.getMajorVersion()).append('-').append(pv.getMinorVersion());
+
+ }
+
+ System.out.println(ver + " (" + protocol + ")");
+ }
+ else
{
- options.setLogWatchFrequency(Integer.parseInt(logWatchConfig));
+ try
+ {
+ CurrentActor.set(new BrokerActor(new SystemOutMessageLogger()));
+ startup();
+ CurrentActor.remove();
+ }
+ catch (InitException e)
+ {
+ System.out.println("Initialisation Error : " + e.getMessage());
+ shutdown(1);
+ }
+ catch (Throwable e)
+ {
+ System.out.println("Error initialising message broker: " + e);
+ e.printStackTrace();
+ shutdown(1);
+ }
}
+ }
- String logConfig = commandLine.getOptionValue(BrokerOptions.LOG_CONFIG);
- if(logConfig != null)
+ protected void shutdown(int status)
+ {
+ ApplicationRegistry.removeAll();
+ System.exit(status);
+ }
+
+ protected void startup() throws Exception
+ {
+ final String QpidHome = System.getProperty(QPID_HOME);
+ final File defaultConfigFile = new File(QpidHome, DEFAULT_CONFIG_FILE);
+ final File configFile = new File(commandLine.getOptionValue("c", defaultConfigFile.getPath()));
+ if (!configFile.exists())
{
- options.setLogConfigFile(logConfig);
+ String error = "File " + configFile + " could not be found. Check the file exists and is readable.";
+
+ if (QpidHome == null)
+ {
+ error = error + "\nNote: " + QPID_HOME + " is not set.";
+ }
+
+ throw new InitException(error, null);
}
+ else
+ {
+ CurrentActor.get().message(BrokerMessages.CONFIG(configFile.getAbsolutePath()));
+ }
+
+ String logConfig = commandLine.getOptionValue("l");
+ String logWatchConfig = commandLine.getOptionValue("w", "0");
- String jmxPort = commandLine.getOptionValue(BrokerOptions.MANAGEMENT);
- if(jmxPort != null)
+ int logWatchTime = 0;
+ try
{
- options.setJmxPort(Integer.parseInt(jmxPort));
+ logWatchTime = Integer.parseInt(logWatchConfig);
+ }
+ catch (NumberFormatException e)
+ {
+ System.err.println("Log watch configuration value of " + logWatchConfig + " is invalid. Must be "
+ + "a non-negative integer. Using default of zero (no watching configured");
}
- String bindAddr = commandLine.getOptionValue(BrokerOptions.BIND);
- if (bindAddr != null)
+ File logConfigFile;
+ if (logConfig != null)
+ {
+ logConfigFile = new File(logConfig);
+ configureLogging(logConfigFile, logWatchTime);
+ }
+ else
{
- options.setBind(bindAddr);
+ File configFileDirectory = configFile.getParentFile();
+ logConfigFile = new File(configFileDirectory, DEFAULT_LOG_CONFIG_FILENAME);
+ configureLogging(logConfigFile, logWatchTime);
}
- String[] portStr = commandLine.getOptionValues(BrokerOptions.PORTS);
+ ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(configFile);
+ ServerConfiguration serverConfig = config.getConfiguration();
+ updateManagementPort(serverConfig, commandLine.getOptionValue("m"));
+
+ 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
+ {
+ configureLoggingManagementMBean(logConfigFile, logWatchTime);
+
+ ConfigurationManagementMBean configMBean = new ConfigurationManagementMBean();
+ configMBean.register();
+
+ ServerInformationMBean sysInfoMBean =
+ new ServerInformationMBean(QpidProperties.getBuildVersion(), QpidProperties.getReleaseVersion());
+ sysInfoMBean.register();
+
+
+ String[] portStr = commandLine.getOptionValues("p");
+
+ Set<Integer> ports = new HashSet<Integer>();
+ Set<Integer> exclude_0_10 = new HashSet<Integer>();
+ Set<Integer> exclude_0_9_1 = new HashSet<Integer>();
+ Set<Integer> exclude_0_9 = new HashSet<Integer>();
+ Set<Integer> exclude_0_8 = new HashSet<Integer>();
+
+ if(portStr == null || portStr.length == 0)
+ {
+
+ parsePortList(ports, serverConfig.getPorts());
+ parsePortList(exclude_0_10, serverConfig.getPortExclude010());
+ parsePortList(exclude_0_9_1, serverConfig.getPortExclude091());
+ parsePortList(exclude_0_9, serverConfig.getPortExclude09());
+ parsePortList(exclude_0_8, serverConfig.getPortExclude08());
+
+ }
+ else
+ {
+ parsePortArray(ports, portStr);
+ parsePortArray(exclude_0_10, commandLine.getOptionValues("exclude-0-10"));
+ parsePortArray(exclude_0_9_1, commandLine.getOptionValues("exclude-0-9-1"));
+ parsePortArray(exclude_0_9, commandLine.getOptionValues("exclude-0-9"));
+ parsePortArray(exclude_0_8, commandLine.getOptionValues("exclude-0-8"));
+
+ }
+
+
+
+
+ String bindAddr = commandLine.getOptionValue("b");
+ if (bindAddr == null)
+ {
+ bindAddr = serverConfig.getBind();
+ }
+ InetAddress bindAddress = null;
+
+
+
+ if (bindAddr.equals("wildcard"))
+ {
+ bindAddress = new InetSocketAddress(0).getAddress();
+ }
+ else
+ {
+ bindAddress = InetAddress.getByAddress(parseIP(bindAddr));
+ }
+
+ String hostName = bindAddress.getCanonicalHostName();
+
+
+ String keystorePath = serverConfig.getKeystorePath();
+ String keystorePassword = serverConfig.getKeystorePassword();
+ String certType = serverConfig.getCertType();
+ SSLContextFactory sslFactory = null;
+
+ if (!serverConfig.getSSLOnly())
+ {
+
+ for(int port : ports)
+ {
+
+ NetworkDriver driver = new MINANetworkDriver();
+
+ Set<VERSION> supported = EnumSet.allOf(VERSION.class);
+
+ if(exclude_0_10.contains(port))
+ {
+ supported.remove(VERSION.v0_10);
+ }
+
+ if(exclude_0_9_1.contains(port))
+ {
+ supported.remove(VERSION.v0_9_1);
+ }
+ if(exclude_0_9.contains(port))
+ {
+ supported.remove(VERSION.v0_9);
+ }
+ if(exclude_0_8.contains(port))
+ {
+ supported.remove(VERSION.v0_8);
+ }
+
+ MultiVersionProtocolEngineFactory protocolEngineFactory =
+ new MultiVersionProtocolEngineFactory(hostName, supported);
+
+
+
+ driver.bind(port, new InetAddress[]{bindAddress}, protocolEngineFactory,
+ serverConfig.getNetworkConfiguration(), null);
+ ApplicationRegistry.getInstance().addAcceptor(new InetSocketAddress(bindAddress, port),
+ new QpidAcceptor(driver,"TCP"));
+ CurrentActor.get().message(BrokerMessages.LISTENING("TCP", port));
+
+ }
+
+ }
+
+ if (serverConfig.getEnableSSL())
+ {
+ sslFactory = new SSLContextFactory(keystorePath, keystorePassword, certType);
+ NetworkDriver driver = new MINANetworkDriver();
+ driver.bind(serverConfig.getSSLPort(), new InetAddress[]{bindAddress},
+ new AMQProtocolEngineFactory(), serverConfig.getNetworkConfiguration(), sslFactory);
+ ApplicationRegistry.getInstance().addAcceptor(new InetSocketAddress(bindAddress, serverConfig.getSSLPort()),
+ new QpidAcceptor(driver,"TCP"));
+ CurrentActor.get().message(BrokerMessages.LISTENING("TCP/SSL", serverConfig.getSSLPort()));
+ }
+
+ CurrentActor.get().message(BrokerMessages.READY());
+
+ }
+ finally
+ {
+ // Startup is complete so remove the AR initialised Startup actor
+ CurrentActor.remove();
+ }
+
+
+
+ }
+
+ private void parsePortArray(Set<Integer> ports, String[] portStr)
+ throws InitException
+ {
if(portStr != null)
{
- parsePortArray(options, portStr, false);
- for(ProtocolExclusion pe : ProtocolExclusion.values())
+ for(int i = 0; i < portStr.length; i++)
{
- parsePortArray(options, commandLine.getOptionValues(pe.getExcludeName()), pe);
+ try
+ {
+ ports.add(Integer.parseInt(portStr[i]));
+ }
+ catch (NumberFormatException e)
+ {
+ throw new InitException("Invalid port: " + portStr[i], e);
+ }
}
}
+ }
- String[] sslPortStr = commandLine.getOptionValues(BrokerOptions.SSL_PORTS);
- if(sslPortStr != null)
+ private void parsePortList(Set<Integer> output, List input)
+ throws InitException
+ {
+ if(input != null)
{
- parsePortArray(options, sslPortStr, true);
- for(ProtocolExclusion pe : ProtocolExclusion.values())
+ for(Object port : input)
{
- parsePortArray(options, commandLine.getOptionValues(pe.getExcludeName()), pe);
+ try
+ {
+ output.add(Integer.parseInt(String.valueOf(port)));
+ }
+ catch (NumberFormatException e)
+ {
+ throw new InitException("Invalid port: " + port, e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Update the configuration data with the management port.
+ * @param configuration
+ * @param managementPort The string from the command line
+ */
+ private void updateManagementPort(ServerConfiguration configuration, String managementPort)
+ {
+ if (managementPort != null)
+ {
+ try
+ {
+ configuration.setJMXManagementPort(Integer.parseInt(managementPort));
+ }
+ catch (NumberFormatException e)
+ {
+ _logger.warn("Invalid management port: " + managementPort + " will use:" + configuration.getJMXManagementPort(), e);
}
}
-
- startBroker(options);
}
- protected void startBroker(final BrokerOptions options) throws Exception
+ public static void main(String[] args)
{
- Broker broker = new Broker();
- broker.startup(options);
+ //if the -Dlog4j.configuration property has not been set, enable the init override
+ //to stop Log4J wondering off and picking up the first log4j.xml/properties file it
+ //finds from the classpath when we get the first Loggers
+ if(System.getProperty("log4j.configuration") == null)
+ {
+ System.setProperty("log4j.defaultInitOverride", "true");
+ }
+
+ //now that the override status is know, we can instantiate the Loggers
+ _logger = Logger.getLogger(Main.class);
+
+ new Main(args);
}
- protected void shutdown(final int status)
+ private byte[] parseIP(String address) throws Exception
{
- ApplicationRegistry.remove();
- System.exit(status);
+ char[] literalBuffer = address.toCharArray();
+ int byteCount = 0;
+ int currByte = 0;
+ byte[] ip = new byte[IPV4_ADDRESS_LENGTH];
+ for (int i = 0; i < literalBuffer.length; i++)
+ {
+ char currChar = literalBuffer[i];
+ if ((currChar >= '0') && (currChar <= '9'))
+ {
+ currByte = (currByte * 10) + (Character.digit(currChar, 10) & 0xFF);
+ }
+
+ if (currChar == IPV4_LITERAL_SEPARATOR || (i + 1 == literalBuffer.length))
+ {
+ ip[byteCount++] = (byte) currByte;
+ currByte = 0;
+ }
+ }
+
+ if (byteCount != 4)
+ {
+ throw new Exception("Invalid IP address: " + address);
+ }
+ return ip;
}
- private static void parsePortArray(final BrokerOptions options,final Object[] ports,
- final boolean ssl) throws InitException
+ private void configureLogging(File logConfigFile, int logWatchTime) throws InitException, IOException
{
- if(ports != null)
+ if (logConfigFile.exists() && logConfigFile.canRead())
{
- for(int i = 0; i < ports.length; i++)
+ CurrentActor.get().message(BrokerMessages.LOG_CONFIG(logConfigFile.getAbsolutePath()));
+
+ if (logWatchTime > 0)
{
+ System.out.println("log file " + logConfigFile.getAbsolutePath() + " will be checked for changes every "
+ + logWatchTime + " seconds");
+ // log4j expects the watch interval in milliseconds
try
{
- if(ssl)
- {
- options.addSSLPort(Integer.parseInt(String.valueOf(ports[i])));
- }
- else
- {
- options.addPort(Integer.parseInt(String.valueOf(ports[i])));
- }
+ QpidLog4JConfigurator.configureAndWatch(logConfigFile.getPath(), logWatchTime * 1000);
}
- catch (NumberFormatException e)
+ catch (Exception e)
+ {
+ throw new InitException(e.getMessage(),e);
+ }
+ }
+ else
+ {
+ try
{
- throw new InitException("Invalid port: " + ports[i], e);
+ QpidLog4JConfigurator.configure(logConfigFile.getPath());
+ }
+ catch (Exception e)
+ {
+ throw new InitException(e.getMessage(),e);
}
}
}
- }
-
- private static void parsePortArray(final BrokerOptions options, final Object[] ports,
- final ProtocolExclusion excludedProtocol) throws InitException
- {
- if(ports != null)
+ else
{
- for(int i = 0; i < ports.length; i++)
+ System.err.println("Logging configuration error: unable to read file " + logConfigFile.getAbsolutePath());
+ System.err.println("Using the fallback internal log4j.properties configuration");
+
+ InputStream propsFile = this.getClass().getResourceAsStream("/log4j.properties");
+ if(propsFile == null)
+ {
+ throw new IOException("Unable to load the fallback internal log4j.properties configuration file");
+ }
+ else
{
try
{
- options.addExcludedPort(excludedProtocol,
- Integer.parseInt(String.valueOf(ports[i])));
+ Properties fallbackProps = new Properties();
+ fallbackProps.load(propsFile);
+ PropertyConfigurator.configure(fallbackProps);
}
- catch (NumberFormatException e)
+ finally
{
- throw new InitException("Invalid port for exclusion: " + ports[i], e);
+ propsFile.close();
}
}
}
}
+
+ private void configureLoggingManagementMBean(File logConfigFile, int logWatchTime) throws Exception
+ {
+ LoggingManagementMBean blm = new LoggingManagementMBean(logConfigFile.getPath(),logWatchTime);
+
+ blm.register();
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java
deleted file mode 100644
index 22d97d36dd..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.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;
-
-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");
-
- 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/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
index 0621b87f0a..7197ec8cdc 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
@@ -20,8 +20,6 @@
package org.apache.qpid.server.configuration;
-import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
@@ -44,7 +42,7 @@ import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.transport.NetworkTransportConfiguration;
+import org.apache.qpid.transport.NetworkDriverConfiguration;
import sun.misc.Signal;
import sun.misc.SignalHandler;
@@ -54,7 +52,9 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
protected static final Logger _logger = Logger.getLogger(ServerConfiguration.class);
// Default Configuration values
- public static final int DEFAULT_BUFFER_SIZE = 262144;
+ public static final int DEFAULT_BUFFER_READ_LIMIT_SIZE = 262144;
+ public static final int DEFAULT_BUFFER_WRITE_LIMIT_SIZE = 262144;
+ public static final boolean DEFAULT_BROKER_CONNECTOR_PROTECTIO_ENABLED = false;
public static final String DEFAULT_STATUS_UPDATES = "on";
public static final String SECURITY_CONFIG_RELOADED = "SECURITY CONFIGURATION RELOADED";
@@ -63,7 +63,7 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
public static final int DEFAULT_SSL_PORT = 8672;
public static final long DEFAULT_HOUSEKEEPING_PERIOD = 30000L;
public static final int DEFAULT_JMXPORT = 8999;
-
+
public static final String QPID_HOME = "QPID_HOME";
public static final String QPID_WORK = "QPID_WORK";
public static final String LIB_DIR = "lib";
@@ -84,6 +84,9 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
// 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 CONNECTOR_PROTECTIO_ENABLED = "connector.protectio.enabled";
+ public static final String CONNECTOR_PROTECTIO_READ_BUFFER_LIMIT_SIZE = "connector.protectio.readBufferLimitSize";
+ public static final String CONNECTOR_PROTECTIO_WRITE_BUFFER_LIMIT_SIZE = "connector.protectio.writeBufferLimitSize";
public static final String MGMT_CUSTOM_REGISTRY_SOCKET = "management.custom-registry-socket";
public static final String STATUS_UPDATES = "status-updates";
public static final String ADVANCED_LOCALE = "advanced.locale";
@@ -92,6 +95,7 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
envVarMap.put("QPID_PORT", "connector.port");
envVarMap.put("QPID_ENABLEDIRECTBUFFERS", "advanced.enableDirectBuffers");
envVarMap.put("QPID_SSLPORT", "connector.ssl.port");
+ envVarMap.put("QPID_NIO", "connector.qpidnio");
envVarMap.put("QPID_WRITEBIASED", "advanced.useWriteBiasedPool");
envVarMap.put("QPID_JMXPORT", "management.jmxport");
envVarMap.put("QPID_FRAMESIZE", "advanced.framesize");
@@ -144,7 +148,7 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
}
catch (Exception e)
{
- _logger.info("Signal HUP not supported for OS: " + System.getProperty("os.name"));
+ _logger.error("Signal HUP not supported for OS: " + System.getProperty("os.name"));
// We're on something that doesn't handle SIGHUP, how sad, Windows.
}
}
@@ -201,29 +205,7 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
@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);
- }
+ //Currently doesn't do validation
}
/*
@@ -521,11 +503,58 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
_virtualHosts.put(config.getName(), config);
}
+ public List<String> getPrincipalDatabaseNames()
+ {
+ return getListValue("security.principal-databases.principal-database.name");
+ }
+
+ public List<String> getPrincipalDatabaseClass()
+ {
+ return getListValue("security.principal-databases.principal-database.class");
+ }
+
+ public List<String> getPrincipalDatabaseAttributeNames(int index)
+ {
+ String name = "security.principal-databases.principal-database(" + index + ")." + "attributes.attribute.name";
+ return getListValue(name);
+ }
+
+ public List<String> getPrincipalDatabaseAttributeValues(int index)
+ {
+ String name = "security.principal-databases.principal-database(" + index + ")." + "attributes.attribute.value";
+ return getListValue(name);
+ }
+
+ public List<String> getManagementPrincipalDBs()
+ {
+ return getListValue("security.jmx.principal-database");
+ }
+
+ public List<String> getManagementAccessList()
+ {
+ return getListValue("security.jmx.access");
+ }
+
public int getFrameSize()
{
return getIntValue("advanced.framesize", DEFAULT_FRAME_SIZE);
}
+ public boolean getProtectIOEnabled()
+ {
+ return getBooleanValue(CONNECTOR_PROTECTIO_ENABLED, DEFAULT_BROKER_CONNECTOR_PROTECTIO_ENABLED);
+ }
+
+ public int getBufferReadLimit()
+ {
+ return getIntValue(CONNECTOR_PROTECTIO_READ_BUFFER_LIMIT_SIZE, DEFAULT_BUFFER_READ_LIMIT_SIZE);
+ }
+
+ public int getBufferWriteLimit()
+ {
+ return getIntValue(CONNECTOR_PROTECTIO_WRITE_BUFFER_LIMIT_SIZE, DEFAULT_BUFFER_WRITE_LIMIT_SIZE);
+ }
+
public boolean getSynchedClocks()
{
return getBooleanValue("advanced.synced-clocks");
@@ -536,6 +565,11 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
return getBooleanValue("security.msg-auth");
}
+ public String getJMXPrincipalDatabase()
+ {
+ return getStringValue("security.jmx.principal-database");
+ }
+
public String getManagementKeyStorePath()
{
return getStringValue("management.ssl.keyStorePath");
@@ -616,14 +650,14 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
return getLongValue("flowResumeCapacity", getCapacity());
}
- public int getConnectorProcessors()
+ public int getProcessors()
{
return getIntValue("connector.processors", 4);
}
public List getPorts()
{
- return getListValue("connector.port", Collections.<Integer>singletonList(DEFAULT_PORT));
+ return getListValue("connector.port", Collections.singletonList(DEFAULT_PORT));
}
public List getPortExclude010()
@@ -648,17 +682,17 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
public String getBind()
{
- return getStringValue("connector.bind", WILDCARD_ADDRESS);
+ return getStringValue("connector.bind", "wildcard");
}
public int getReceiveBufferSize()
{
- return getIntValue("connector.socketReceiveBuffer", DEFAULT_BUFFER_SIZE);
+ return getIntValue("connector.socketReceiveBuffer", 32767);
}
public int getWriteBufferSize()
{
- return getIntValue("connector.socketWriteBuffer", DEFAULT_BUFFER_SIZE);
+ return getIntValue("connector.socketWriteBuffer", 32767);
}
public boolean getTcpNoDelay()
@@ -681,9 +715,9 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
return getBooleanValue("connector.ssl.sslOnly");
}
- public List getSSLPorts()
+ public int getSSLPort()
{
- return getListValue("connector.ssl.port", Collections.<Integer>singletonList(DEFAULT_SSL_PORT));
+ return getIntValue("connector.ssl.port", DEFAULT_SSL_PORT);
}
public String getKeystorePath()
@@ -701,6 +735,11 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
return getStringValue("connector.ssl.certType", "SunX509");
}
+ public boolean getQpidNIO()
+ {
+ return getBooleanValue("connector.qpidnio");
+ }
+
public boolean getUseBiasedWrites()
{
return getBooleanValue("advanced.useWriteBiasedPool");
@@ -728,34 +767,57 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
DEFAULT_HOUSEKEEPING_PERIOD));
}
- public long getStatisticsSamplePeriod()
+ public NetworkDriverConfiguration getNetworkConfiguration()
{
- return getConfig().getLong("statistics.sample.period", 5000L);
- }
+ return new NetworkDriverConfiguration()
+ {
- public boolean isStatisticsGenerationBrokerEnabled()
- {
- return getConfig().getBoolean("statistics.generation.broker", false);
- }
+ public Integer getTrafficClass()
+ {
+ return null;
+ }
- public boolean isStatisticsGenerationVirtualhostsEnabled()
- {
- return getConfig().getBoolean("statistics.generation.virtualhosts", false);
- }
+ public Boolean getTcpNoDelay()
+ {
+ // Can't call parent getTcpNoDelay since it just calls this one
+ return getBooleanValue("connector.tcpNoDelay", true);
+ }
- public boolean isStatisticsGenerationConnectionsEnabled()
- {
- return getConfig().getBoolean("statistics.generation.connections", false);
- }
+ public Integer getSoTimeout()
+ {
+ return null;
+ }
- public long getStatisticsReportingPeriod()
- {
- return getConfig().getLong("statistics.reporting.period", 0L);
- }
+ public Integer getSoLinger()
+ {
+ return null;
+ }
- public boolean isStatisticsReportResetEnabled()
- {
- return getConfig().getBoolean("statistics.reporting.reset", false);
+ public Integer getSendBufferSize()
+ {
+ return getBufferWriteLimit();
+ }
+
+ public Boolean getReuseAddress()
+ {
+ return null;
+ }
+
+ public Integer getReceiveBufferSize()
+ {
+ return getBufferReadLimit();
+ }
+
+ public Boolean getOOBInline()
+ {
+ return null;
+ }
+
+ public Boolean getKeepAlive()
+ {
+ return null;
+ }
+ };
}
public int getMaxChannelCount()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java
deleted file mode 100644
index 81dfcb4465..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.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.qpid.transport.NetworkTransportConfiguration;
-
-public class ServerNetworkTransportConfiguration implements NetworkTransportConfiguration
-{
- private final ServerConfiguration _serverConfig;
- private final int _port;
- private final String _host;
- private final String _transport;
-
- public ServerNetworkTransportConfiguration(final ServerConfiguration serverConfig,
- final int port, final String host,
- final String transport)
- {
- _serverConfig = serverConfig;
- _port = port;
- _host = host;
- _transport = transport;
- }
-
- public Boolean getTcpNoDelay()
- {
- return _serverConfig.getTcpNoDelay();
- }
-
- public Integer getSendBufferSize()
- {
- return _serverConfig.getWriteBufferSize();
- }
-
- public Integer getReceiveBufferSize()
- {
- return _serverConfig.getReceiveBufferSize();
- }
-
- public Integer getPort()
- {
- return _port;
- }
-
- public String getHost()
- {
- return _host;
- }
-
- public String getTransport()
- {
- return _transport;
- }
-
- public Integer getConnectorProcessors()
- {
- return _serverConfig.getConnectorProcessors();
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java
index a710230616..d9d7083543 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java
@@ -306,37 +306,11 @@ public class VirtualHostConfiguration extends ConfigurationPlugin
@Override
public void validateConfiguration() throws ConfigurationException
{
- // QPID-3249. Support for specifying authentication name at vhost level is no longer supported.
- if (getListValue("security.authentication.name").size() > 0)
- {
- String message = "Validation error : security/authentication/name is no longer a supported element within the configuration xml."
- + " It appears in virtual host definition : " + _name;
- throw new ConfigurationException(message);
- }
+ //Currently doesn't do validation
}
public int getHouseKeepingThreadCount()
{
return getIntValue("housekeeping.poolSize", Runtime.getRuntime().availableProcessors());
}
-
- public long getTransactionTimeoutOpenWarn()
- {
- return getLongValue("transactionTimeout.openWarn", 0L);
- }
-
- public long getTransactionTimeoutOpenClose()
- {
- return getLongValue("transactionTimeout.openClose", 0L);
- }
-
- public long getTransactionTimeoutIdleWarn()
- {
- return getLongValue("transactionTimeout.idleWarn", 0L);
- }
-
- public long getTransactionTimeoutIdleClose()
- {
- return getLongValue("transactionTimeout.idleClose", 0L);
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java
index b4f82649b0..82b576ea51 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java
@@ -24,7 +24,6 @@ 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;
@@ -139,28 +138,10 @@ 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)
{
+ ConfigurationManager configurationManager = ApplicationRegistry.getInstance().getConfigurationManager();
Configuration handled = element.length() == 0 ? configuration : configuration.subset(element);
String configurationElement = element;
@@ -181,18 +162,8 @@ public abstract class ConfigurationPlugin
_pluginConfiguration.put(plugin.getClass().getName(), plugin);
}
}
- }
- private IApplicationRegistry safeGetApplicationRegistryInstance()
- {
- try
- {
- return ApplicationRegistry.getInstance();
- }
- catch (IllegalStateException ise)
- {
- return null;
- }
+ validateConfiguration();
}
/** Helper method to print out list of keys in a {@link Configuration}. */
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java
index 3786c2020c..bac751e0c8 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java
@@ -20,19 +20,19 @@
*/
package org.apache.qpid.server.connection;
-import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.log4j.Logger;
+import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.AMQException;
import org.apache.qpid.common.Closeable;
import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.server.protocol.AMQConnectionModel;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
public class ConnectionRegistry implements IConnectionRegistry, Closeable
{
- private List<AMQConnectionModel> _registry = new CopyOnWriteArrayList<AMQConnectionModel>();
+ private List<AMQProtocolSession> _registry = new CopyOnWriteArrayList<AMQProtocolSession>();
private Logger _logger = Logger.getLogger(ConnectionRegistry.class);
@@ -40,41 +40,44 @@ public class ConnectionRegistry implements IConnectionRegistry, Closeable
{
// None required
}
-
- /** Close all of the currently open connections. */
- public void close()
+
+ public void expireClosedChannels()
{
- while (!_registry.isEmpty())
+ for (AMQProtocolSession connection : _registry)
{
- AMQConnectionModel connection = _registry.get(0);
- closeConnection(connection, AMQConstant.INTERNAL_ERROR, "Broker is shutting down");
+ connection.closeIfLingeringClosedChannels();
}
}
-
- public void closeConnection(AMQConnectionModel connection, AMQConstant cause, String message)
+
+ /** Close all of the currently open connections. */
+ public void close()
{
- try
- {
- connection.close(cause, message);
- }
- catch (AMQException e)
+ while (!_registry.isEmpty())
{
- _logger.warn("Error closing connection:" + e.getMessage());
+ AMQProtocolSession connection = _registry.get(0);
+
+ try
+ {
+ connection.closeConnection(0, new AMQConnectionException(AMQConstant.INTERNAL_ERROR, "Broker is shutting down",
+ 0, 0,
+ connection.getProtocolOutputConverter().getProtocolMajorVersion(),
+ connection.getProtocolOutputConverter().getProtocolMinorVersion(),
+ (Throwable) null), true);
+ }
+ catch (AMQException e)
+ {
+ _logger.warn("Error closing connection:" + e.getMessage());
+ }
}
}
- public void registerConnection(AMQConnectionModel connnection)
+ public void registerConnection(AMQProtocolSession connnection)
{
_registry.add(connnection);
}
- public void deregisterConnection(AMQConnectionModel connnection)
+ public void deregisterConnection(AMQProtocolSession connnection)
{
_registry.remove(connnection);
}
-
- public List<AMQConnectionModel> getConnections()
- {
- return new ArrayList<AMQConnectionModel>(_registry);
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java
index b4f5bffa57..002269bbaa 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java
@@ -20,23 +20,18 @@
*/
package org.apache.qpid.server.connection;
-import java.util.List;
-
+import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.AMQException;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.server.protocol.AMQConnectionModel;
public interface IConnectionRegistry
{
+
public void initialise();
public void close() throws AMQException;
-
- public void closeConnection(AMQConnectionModel connection, AMQConstant cause, String message);
-
- public List<AMQConnectionModel> getConnections();
- public void registerConnection(AMQConnectionModel connnection);
+ public void registerConnection(AMQProtocolSession connnection);
+
+ public void deregisterConnection(AMQProtocolSession connnection);
- public void deregisterConnection(AMQConnectionModel connnection);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java
index 0f1b709475..7aeff2561e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java
@@ -90,12 +90,12 @@ public abstract class AbstractExchangeMBean<T extends AbstractExchange> extends
public String getObjectInstanceName()
{
- return ObjectName.quote(_exchange.getName());
+ return _exchange.getNameShortString().toString();
}
public String getName()
{
- return _exchange.getName();
+ return _exchange.getNameShortString().toString();
}
public String getExchangeType()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
index f21158cd0c..fa2fb9ead1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
@@ -258,6 +258,7 @@ public class BrokerLink implements LinkConfig, ConnectionListener
_remoteFederationTag = UUID.fromString(_transport+":"+_host+":"+_port).toString();
}
_qpidConnection.setSessionFactory(new SessionFactory());
+ _qpidConnection.setAuthorizationID(_username == null ? "" : _username);
updateState(State.ESTABLISHING, State.OPERATIONAL);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java
index 9848f90ea9..11fdeae2b1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java
@@ -37,8 +37,8 @@ import org.apache.qpid.server.queue.Filterable;
public class PropertyExpression implements Expression
{
// Constants - defined the same as JMS
- private static enum JMSDeliveryMode { NON_PERSISTENT, PERSISTENT }
-
+ private static final int NON_PERSISTENT = 1;
+ private static final int PERSISTENT = 2;
private static final int DEFAULT_PRIORITY = 4;
private static final Logger _logger = org.apache.log4j.Logger.getLogger(PropertyExpression.class);
@@ -172,14 +172,13 @@ public class PropertyExpression implements Expression
{
public Object evaluate(Filterable message)
{
- JMSDeliveryMode mode = message.isPersistent() ? JMSDeliveryMode.PERSISTENT :
- JMSDeliveryMode.NON_PERSISTENT;
+ int mode = message.isPersistent() ? PERSISTENT : NON_PERSISTENT;
if (_logger.isDebugEnabled())
{
_logger.debug("JMSDeliveryMode is :" + mode);
}
- return mode.toString();
+ return mode;
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
index 09f35da41d..d4b79134a2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
@@ -20,9 +20,9 @@
*/
package org.apache.qpid.server.handler;
-
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
+
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.ConnectionCloseBody;
@@ -68,7 +68,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
}
MethodRegistry methodRegistry = session.getMethodRegistry();
AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse());
- switch (authResult.getStatus())
+ switch (authResult.status)
{
case ERROR:
Exception cause = authResult.getCause();
@@ -88,10 +88,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
disposeSaslServer(session);
break;
case SUCCESS:
- if (_logger.isInfoEnabled())
- {
- _logger.info("Connected as: " + UsernamePrincipal.getUsernamePrincipalFromSubject(authResult.getSubject()));
- }
+ _logger.info("Connected as: " + ss.getAuthorizationID());
stateManager.changeState(AMQState.CONNECTION_NOT_TUNED);
ConnectionTuneBody tuneBody =
@@ -99,13 +96,13 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
ConnectionStartOkMethodHandler.getConfiguredFrameSize(),
ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay());
session.writeFrame(tuneBody.generateFrame(0));
- session.setAuthorizedSubject(authResult.getSubject());
+ session.setAuthorizedID(new UsernamePrincipal(ss.getAuthorizationID()));
disposeSaslServer(session);
break;
case CONTINUE:
stateManager.changeState(AMQState.CONNECTION_NOT_AUTH);
- ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.getChallenge());
+ ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.challenge);
session.writeFrame(secureBody.generateFrame(0));
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
index 2dd9a63540..4442f969c4 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
@@ -65,6 +65,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
_logger.info("Locale selected: " + body.getLocale());
AuthenticationManager authMgr = ApplicationRegistry.getInstance().getAuthenticationManager();
+
SaslServer ss = null;
try
{
@@ -77,7 +78,8 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
session.setSaslServer(ss);
- final AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse());
+ AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse());
+
//save clientProperties
if (session.getClientProperties() == null)
{
@@ -86,7 +88,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
MethodRegistry methodRegistry = session.getMethodRegistry();
- switch (authResult.getStatus())
+ switch (authResult.status)
{
case ERROR:
Exception cause = authResult.getCause();
@@ -106,11 +108,8 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
break;
case SUCCESS:
- if (_logger.isInfoEnabled())
- {
- _logger.info("Connected as: " + UsernamePrincipal.getUsernamePrincipalFromSubject(authResult.getSubject()));
- }
- session.setAuthorizedSubject(authResult.getSubject());
+ _logger.info("Connected as: " + ss.getAuthorizationID());
+ session.setAuthorizedID(new UsernamePrincipal(ss.getAuthorizationID()));
stateManager.changeState(AMQState.CONNECTION_NOT_TUNED);
@@ -122,7 +121,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
case CONTINUE:
stateManager.changeState(AMQState.CONNECTION_NOT_AUTH);
- ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.getChallenge());
+ ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.challenge);
session.writeFrame(secureBody.generateFrame(0));
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
index 0cfed77f2e..8939cfa334 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
@@ -106,7 +106,7 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
else
{
queue = createQueue(queueName, body, virtualHost, protocolConnection);
- queue.setAuthorizationHolder(protocolConnection);
+ queue.setPrincipalHolder(protocolConnection);
if (queue.isDurable() && !queue.isAutoDelete())
{
store.createQueue(queue, body.getArguments());
@@ -119,7 +119,7 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
if (body.getExclusive())
{
queue.setExclusiveOwningSession(protocolConnection.getChannel(channelId));
- queue.setAuthorizationHolder(protocolConnection);
+ queue.setPrincipalHolder(protocolConnection);
if(!body.getDurable())
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java
index 5e6a143d52..db2cc970b2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java
@@ -22,11 +22,9 @@ package org.apache.qpid.server.information.management;
import java.io.IOException;
-import org.apache.qpid.common.QpidProperties;
import org.apache.qpid.management.common.mbeans.ServerInformation;
import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import javax.management.JMException;
@@ -36,15 +34,12 @@ public class ServerInformationMBean extends AMQManagedObject implements ServerIn
{
private String buildVersion;
private String productVersion;
- private ApplicationRegistry registry;
- public ServerInformationMBean(ApplicationRegistry applicationRegistry) throws JMException
+ public ServerInformationMBean(String buildVersion, String productVersion) throws JMException
{
super(ServerInformation.class, ServerInformation.TYPE);
-
- registry = applicationRegistry;
- buildVersion = QpidProperties.getBuildVersion();
- productVersion = QpidProperties.getReleaseVersion();
+ this.buildVersion = buildVersion;
+ this.productVersion = productVersion;
}
public String getObjectInstanceName()
@@ -72,75 +67,5 @@ public class ServerInformationMBean extends AMQManagedObject implements ServerIn
return productVersion;
}
-
- public void resetStatistics() throws Exception
- {
- registry.resetStatistics();
- }
-
- public double getPeakMessageDeliveryRate()
- {
- return registry.getMessageDeliveryStatistics().getPeak();
- }
-
- public double getPeakDataDeliveryRate()
- {
- return registry.getDataDeliveryStatistics().getPeak();
- }
-
- public double getMessageDeliveryRate()
- {
- return registry.getMessageDeliveryStatistics().getRate();
- }
-
- public double getDataDeliveryRate()
- {
- return registry.getDataDeliveryStatistics().getRate();
- }
-
- public long getTotalMessagesDelivered()
- {
- return registry.getMessageDeliveryStatistics().getTotal();
- }
-
- public long getTotalDataDelivered()
- {
- return registry.getDataDeliveryStatistics().getTotal();
- }
-
- public double getPeakMessageReceiptRate()
- {
- return registry.getMessageReceiptStatistics().getPeak();
- }
-
- public double getPeakDataReceiptRate()
- {
- return registry.getDataReceiptStatistics().getPeak();
- }
-
- public double getMessageReceiptRate()
- {
- return registry.getMessageReceiptStatistics().getRate();
- }
-
- public double getDataReceiptRate()
- {
- return registry.getDataReceiptStatistics().getRate();
- }
-
- public long getTotalMessagesReceived()
- {
- return registry.getMessageReceiptStatistics().getTotal();
- }
-
- public long getTotalDataReceived()
- {
- return registry.getDataReceiptStatistics().getTotal();
- }
-
- public boolean isStatisticsEnabled()
- {
- return registry.isStatisticsEnabled();
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties
index 5d1e85fe41..6b83a7e7a5 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties
@@ -32,7 +32,4 @@ STOPPED = BRK-1005 : Stopped
# 0 - path
CONFIG = BRK-1006 : Using configuration : {0}
# 0 - path
-LOG_CONFIG = BRK-1007 : Using logging configuration : {0}
-
-STATS_DATA = BRK-1008 : {0,choice,0#delivered|1#received} : {1,number,#.###} kB/s peak : {2,number,#} bytes total
-STATS_MSGS = BRK-1009 : {0,choice,0#delivered|1#received} : {1,number,#.###} msg/s peak : {2,number,#} msgs total \ No newline at end of file
+LOG_CONFIG = BRK-1007 : Using logging configuration : {0} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Channel_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Channel_logmessages.properties
index ed8c0d0ce9..53bcd712f2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Channel_logmessages.properties
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Channel_logmessages.properties
@@ -28,7 +28,3 @@ PREFETCH_SIZE = CHN-1004 : Prefetch Size (bytes) {0,number} : Count {1,number}
# 0 - queue causing flow control
FLOW_ENFORCED = CHN-1005 : Flow Control Enforced (Queue {0})
FLOW_REMOVED = CHN-1006 : Flow Control Removed
-# Channel Transactions
-# 0 - time in milliseconds
-OPEN_TXN = CHN-1007 : Open Transaction : {0,number} ms
-IDLE_TXN = CHN-1008 : Idle Transaction : {0,number} ms
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties
index 3e640c7929..66bbefacb0 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties
@@ -20,7 +20,4 @@
#
# 0 - name
CREATED = VHT-1001 : Created : {0}
-CLOSED = VHT-1002 : Closed
-
-STATS_DATA = VHT-1003 : {0} : {1,choice,0#delivered|1#received} : {2,number,#.###} kB/s peak : {3,number,#} bytes total
-STATS_MSGS = VHT-1004 : {0} : {1,choice,0#delivered|1#received} : {2,number,#.###} msg/s peak : {3,number,#} msgs total` \ No newline at end of file
+CLOSED = VHT-1002 : Closed \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java
index 9b357403a8..f28873940b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java
@@ -47,7 +47,7 @@ public class ChannelLogSubject extends AbstractLogSubject
*/
setLogStringWithFormat(CHANNEL_FORMAT,
session.getSessionID(),
- session.getAuthorizedPrincipal().getName(),
+ session.getPrincipal().getName(),
session.getRemoteAddress(),
session.getVirtualHost().getName(),
channel.getChannelId());
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java
index c1c836f9b4..a697029d24 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java
@@ -56,7 +56,7 @@ public class ConnectionLogSubject extends AbstractLogSubject
{
if (!_upToDate)
{
- if (_session.getAuthorizedPrincipal() != null)
+ if (_session.getPrincipal() != null)
{
if (_session.getVirtualHost() != null)
{
@@ -72,7 +72,7 @@ public class ConnectionLogSubject extends AbstractLogSubject
*/
_logString = "[" + MessageFormat.format(CONNECTION_FORMAT,
_session.getSessionID(),
- _session.getAuthorizedPrincipal().getName(),
+ _session.getPrincipal().getName(),
_session.getRemoteAddress(),
_session.getVirtualHost().getName())
+ "] ";
@@ -83,7 +83,7 @@ public class ConnectionLogSubject extends AbstractLogSubject
{
_logString = "[" + MessageFormat.format(USER_FORMAT,
_session.getSessionID(),
- _session.getAuthorizedPrincipal().getName(),
+ _session.getPrincipal().getName(),
_session.getRemoteAddress())
+ "] ";
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java
index e44b8c41cb..0a739af695 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java
@@ -26,9 +26,8 @@ import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import javax.management.StandardMBean;
-import org.apache.log4j.Logger;
+import org.apache.qpid.AMQException;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
/**
* Provides implementation of the boilerplate ManagedObject interface. Most managed objects should find it useful
@@ -37,14 +36,10 @@ import org.apache.qpid.server.registry.IApplicationRegistry;
*/
public abstract class DefaultManagedObject extends StandardMBean implements ManagedObject
{
- private static final Logger LOGGER = Logger.getLogger(ApplicationRegistry.class);
-
private Class<?> _managementInterface;
private String _typeName;
- private ManagedObjectRegistry _registry;
-
protected DefaultManagedObject(Class<?> managementInterface, String typeName)
throws NotCompliantMBeanException
{
@@ -70,26 +65,23 @@ public abstract class DefaultManagedObject extends StandardMBean implements Mana
public void register() throws JMException
{
- _registry = ApplicationRegistry.getInstance().getManagedObjectRegistry();
- _registry.registerObject(this);
+ getManagedObjectRegistry().registerObject(this);
}
- public void unregister()
+ protected ManagedObjectRegistry getManagedObjectRegistry()
+ {
+ return ApplicationRegistry.getInstance().getManagedObjectRegistry();
+ }
+
+ public void unregister() throws AMQException
{
try
{
- if(_registry != null)
- {
- _registry.unregisterObject(this);
- }
+ getManagedObjectRegistry().unregisterObject(this);
}
catch (JMException e)
{
- LOGGER.error("Error unregistering managed object: " + this + ": " + e, e);
- }
- finally
- {
- _registry = null;
+ throw new AMQException("Error unregistering managed object: " + this + ": " + e, e);
}
}
@@ -161,4 +153,32 @@ public abstract class DefaultManagedObject extends StandardMBean implements Mana
return "";
}
+ protected static StringBuffer jmxEncode(StringBuffer jmxName, int attrPos)
+ {
+ for (int i = attrPos; i < jmxName.length(); i++)
+ {
+ if (jmxName.charAt(i) == ',')
+ {
+ jmxName.setCharAt(i, ';');
+ }
+ else if (jmxName.charAt(i) == ':')
+ {
+ jmxName.setCharAt(i, '-');
+ }
+ else if (jmxName.charAt(i) == '?' ||
+ jmxName.charAt(i) == '*' ||
+ jmxName.charAt(i) == '\\')
+ {
+ jmxName.insert(i, '\\');
+ i++;
+ }
+ else if (jmxName.charAt(i) == '\n')
+ {
+ jmxName.insert(i, '\\');
+ i++;
+ jmxName.setCharAt(i, 'n');
+ }
+ }
+ return jmxName;
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
index 6a34ff4a26..0334a856c1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
@@ -20,6 +20,32 @@
*/
package org.apache.qpid.server.management;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.log4j.Logger;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.rmi.RMIPasswordAuthenticator;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
+
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.ObjectName;
+import javax.management.NotificationListener;
+import javax.management.NotificationFilterSupport;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.MBeanServerForwarder;
+import javax.management.remote.JMXConnectionNotification;
+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 java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -38,31 +64,7 @@ import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
-
-import javax.management.JMException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-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.RMIConnectorServer;
-import javax.management.remote.rmi.RMIJRMPServerImpl;
-import javax.management.remote.rmi.RMIServerImpl;
-import javax.rmi.ssl.SslRMIClientSocketFactory;
-import javax.rmi.ssl.SslRMIServerSocketFactory;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.security.auth.rmi.RMIPasswordAuthenticator;
+import java.util.Map;
/**
* This class starts up an MBeanserver. If out of the box agent has been enabled then there are no
@@ -111,6 +113,12 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
int port = appRegistry.getConfiguration().getJMXManagementPort();
+ //retrieve the Principal Database assigned to JMX authentication duties
+ String jmxDatabaseName = appRegistry.getConfiguration().getJMXPrincipalDatabase();
+ Map<String, PrincipalDatabase> map = appRegistry.getDatabaseManager().getDatabases();
+ PrincipalDatabase db = map.get(jmxDatabaseName);
+
+ HashMap<String,Object> env = new HashMap<String,Object>();
//Socket factories for the RMIConnectorServer, either default or SLL depending on configuration
RMIClientSocketFactory csf;
@@ -192,8 +200,7 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
//add a JMXAuthenticator implementation the env map to authenticate the RMI based JMX connector server
RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator();
- rmipa.setAuthenticationManager(appRegistry.getAuthenticationManager());
- HashMap<String,Object> env = new HashMap<String,Object>();
+ rmipa.setPrincipalDatabase(db);
env.put(JMXConnectorServer.AUTHENTICATOR, rmipa);
/*
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
index 68f7689283..964b5ed5a0 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
@@ -26,6 +26,8 @@ import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.security.AccessControlContext;
import java.security.AccessController;
+import java.security.Principal;
+import java.util.Properties;
import java.util.Set;
import javax.management.Attribute;
@@ -42,6 +44,7 @@ import javax.management.remote.MBeanServerForwarder;
import javax.security.auth.Subject;
import org.apache.log4j.Logger;
+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;
@@ -49,15 +52,20 @@ import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.access.Operation;
/**
- * This class can be used by the JMXConnectorServer as an InvocationHandler for the mbean operations. It delegates
- * JMX access decisions to the SecurityPlugin.
+ * This class can be used by the JMXConnectorServer as an InvocationHandler for the mbean operations. This implements
+ * the logic for allowing the users to invoke MBean operations and implements the restrictions for readOnly, readWrite
+ * and admin users.
*/
public class MBeanInvocationHandlerImpl implements InvocationHandler, NotificationListener
{
private static final Logger _logger = Logger.getLogger(MBeanInvocationHandlerImpl.class);
+ public final static String ADMIN = "admin";
+ public final static String READWRITE = "readwrite";
+ public final static String READONLY = "readonly";
private final static String DELEGATE = "JMImplementation:type=MBeanServerDelegate";
private MBeanServer _mbs;
+ private static Properties _userRoles = new Properties();
private static ManagementActor _logActor;
public static MBeanServerForwarder newProxyInstance()
@@ -129,13 +137,14 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
if (principals == null || principals.isEmpty())
{
- throw new SecurityException("Access denied: no JMX principal");
+ throw new SecurityException("Access denied: no principal");
}
-
- // Save the subject
- SecurityManager.setThreadSubject(subject);
-
- // Get the component, type and impact, which may be null
+
+ // Save the principal
+ Principal principal = principals.iterator().next();
+ SecurityManager.setThreadPrincipal(principal);
+
+ // Get the component, type and impact, which may be null
String type = getType(method, args);
String vhost = getVirtualHost(method, args);
int impact = getImpact(method, args);
@@ -204,20 +213,6 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
ObjectName object = (ObjectName) args[0];
String vhost = object.getKeyProperty("VirtualHost");
- if(vhost != null)
- {
- try
- {
- //if the name is quoted in the ObjectName, unquote it
- vhost = ObjectName.unquote(vhost);
- }
- catch(IllegalArgumentException e)
- {
- //ignore, this just means the name is not quoted
- //and can be left unchanged
- }
- }
-
return vhost;
}
return null;
@@ -277,7 +272,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
}
catch (JMException ex)
{
- _logger.error("Unable to determine mbean impact for method : " + mbeanMethod, ex);
+ ex.printStackTrace();
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java
index 84a1642578..194835ac02 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java
@@ -37,7 +37,7 @@ public class ContentHeaderBodyAdapter implements AMQMessageHeader
private BasicContentHeaderProperties getProperties()
{
- return (BasicContentHeaderProperties) _contentHeaderBody.getProperties();
+ return (BasicContentHeaderProperties) _contentHeaderBody.properties;
}
public String getCorrelationId()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
index 66cb7ed83b..30bea7b6e6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
@@ -161,7 +161,7 @@ public class MessageMetaData implements StorableMessageMetaData
public boolean isPersistent()
{
- BasicContentHeaderProperties properties = (BasicContentHeaderProperties) (_contentHeaderBody.getProperties());
+ BasicContentHeaderProperties properties = (BasicContentHeaderProperties) (_contentHeaderBody.properties);
return properties.getDeliveryMode() == BasicContentHeaderProperties.PERSISTENT;
}
@@ -229,7 +229,7 @@ public class MessageMetaData implements StorableMessageMetaData
{
private BasicContentHeaderProperties getProperties()
{
- return (BasicContentHeaderProperties) getContentHeaderBody().getProperties();
+ return (BasicContentHeaderProperties) getContentHeaderBody().properties;
}
public String getCorrelationId()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java
index 804a9d5027..e7f9983fff 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java
@@ -27,5 +27,5 @@ public interface Plugin
/**
* Provide Configuration to this plugin
*/
- public void configure(ConfigurationPlugin config) throws ConfigurationException;
+ public void configure(ConfigurationPlugin config);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java
index c8a7b56ccb..a6bab017a1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java
@@ -18,16 +18,8 @@
*/
package org.apache.qpid.server.plugins;
-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;
+import static org.apache.felix.framework.util.FelixConstants.*;
+import static org.apache.felix.main.AutoProcessor.*;
import java.io.File;
import java.util.ArrayList;
@@ -43,20 +35,18 @@ import org.apache.felix.framework.util.StringMap;
import org.apache.log4j.Logger;
import org.apache.qpid.common.Closeable;
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.configuration.plugins.ConfigurationPluginFactory;
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.AllowAll;
import org.apache.qpid.server.security.access.plugins.DenyAll;
import org.apache.qpid.server.security.access.plugins.LegacyAccess;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManagerPluginFactory;
-import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
-import org.apache.qpid.server.virtualhost.plugins.SlowConsumerDetection;
import org.apache.qpid.server.virtualhost.plugins.VirtualHostPluginFactory;
+import org.apache.qpid.server.virtualhost.plugins.SlowConsumerDetection;
import org.apache.qpid.server.virtualhost.plugins.policies.TopicDeletePolicy;
import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPluginFactory;
import org.osgi.framework.BundleActivator;
@@ -73,7 +63,7 @@ public class PluginManager implements Closeable
private static final Logger _logger = Logger.getLogger(PluginManager.class);
private static final int FELIX_STOP_TIMEOUT = 30000;
- private static final String QPID_VER_SUFFIX = "version=0.13,";
+ private static final String QPID_VER_SUFFIX = "version=0.9,";
private Framework _felix;
@@ -82,7 +72,6 @@ public class PluginManager implements Closeable
private ServiceTracker _configTracker = null;
private ServiceTracker _virtualHostTracker = null;
private ServiceTracker _policyTracker = null;
- private ServiceTracker _authenticationManagerTracker = null;
private Activator _activator;
@@ -90,7 +79,6 @@ public class PluginManager implements Closeable
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>>();
public PluginManager(String pluginPath, String cachePath) throws Exception
{
@@ -109,8 +97,7 @@ public class PluginManager implements Closeable
LegacyAccess.LegacyAccessConfiguration.FACTORY,
new SlowConsumerDetectionConfigurationFactory(),
new SlowConsumerDetectionPolicyConfigurationFactory(),
- new SlowConsumerDetectionQueueConfigurationFactory(),
- PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration.FACTORY))
+ new SlowConsumerDetectionQueueConfigurationFactory()))
{
_configPlugins.put(configFactory.getParentPaths(), configFactory);
}
@@ -125,12 +112,6 @@ public class PluginManager implements Closeable
_vhostPlugins.put(pluginFactory.getClass().getName(), pluginFactory);
}
- for (AuthenticationManagerPluginFactory<? extends Plugin> pluginFactory : Arrays.asList(
- PrincipalDatabaseAuthenticationManager.FACTORY))
- {
- _authenticationManagerPlugins.put(pluginFactory.getPluginName(), pluginFactory);
- }
-
// Check the plugin directory path is set and exist
if (pluginPath == null)
{
@@ -186,8 +167,7 @@ public class PluginManager implements Closeable
"org.apache.commons.logging; version=1.0.0," +
"org.apache.log4j; version=1.2.12," +
"javax.management.openmbean; version=1.0.0," +
- "javax.management; version=1.0.0," +
- "javax.security.auth; version=1.0.0"
+ "javax.management; version=1.0.0"
);
// No automatic shutdown hook
@@ -251,9 +231,6 @@ public class PluginManager implements Closeable
_policyTracker = new ServiceTracker(_activator.getContext(), SlowConsumerPolicyPluginFactory.class.getName(), null);
_policyTracker.open();
- _authenticationManagerTracker = new ServiceTracker(_activator.getContext(), AuthenticationManagerPluginFactory.class.getName(), null);
- _authenticationManagerTracker.open();
-
_logger.info("Opened service trackers");
}
@@ -324,11 +301,6 @@ public class PluginManager implements Closeable
return getServices(_securityTracker, _securityPlugins);
}
- public Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> getAuthenticationManagerPlugins()
- {
- return getServices(_authenticationManagerTracker, _authenticationManagerPlugins);
- }
-
public void close()
{
if (_felix != null)
@@ -341,7 +313,6 @@ public class PluginManager implements Closeable
_configTracker.close();
_virtualHostTracker.close();
_policyTracker.close();
- _authenticationManagerTracker.close();
}
finally
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java
index 061ebf50cd..bcda385f64 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java
@@ -20,35 +20,14 @@
*/
package org.apache.qpid.server.protocol;
-import java.util.List;
-import java.util.UUID;
-
-import org.apache.qpid.AMQException;
import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.server.logging.LogSubject;
-import org.apache.qpid.server.stats.StatisticsGatherer;
+import org.apache.qpid.AMQException;
-public interface AMQConnectionModel extends StatisticsGatherer
+public interface AMQConnectionModel
{
- /**
- * get a unique id for this connection.
- *
- * @return a {@link UUID} representing the connection
- */
- public UUID getId();
-
- /**
- * Close the underlying Connection
- *
- * @param cause
- * @param message
- * @throws org.apache.qpid.AMQException
- */
- public void close(AMQConstant cause, String message) throws AMQException;
/**
* Close the given requested Session
- *
* @param session
* @param cause
* @param message
@@ -57,16 +36,4 @@ public interface AMQConnectionModel extends StatisticsGatherer
public void closeSession(AMQSessionModel session, AMQConstant cause, String message) throws AMQException;
public long getConnectionId();
-
- /**
- * Get a list of all sessions using this connection.
- *
- * @return a list of {@link AMQSessionModel}s
- */
- public List<AMQSessionModel> getSessionModels();
-
- /**
- * Return a {@link LogSubject} for the connection.
- */
- public LogSubject getLogSubject();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
index d6201f7cf6..a1ffe272fd 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
@@ -30,6 +30,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
+import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -37,10 +38,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import javax.management.JMException;
-import javax.security.auth.Subject;
import javax.security.sasl.SaslServer;
import org.apache.log4j.Logger;
+import org.apache.mina.transport.vmpipe.VmPipeAddress;
import org.apache.qpid.AMQChannelException;
import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.AMQException;
@@ -89,14 +90,12 @@ import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.output.ProtocolOutputConverter;
import org.apache.qpid.server.output.ProtocolOutputConverterRegistry;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.state.AMQStateManager;
-import org.apache.qpid.server.stats.StatisticsCounter;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+import org.apache.qpid.transport.NetworkDriver;
import org.apache.qpid.transport.Sender;
-import org.apache.qpid.transport.network.NetworkConnection;
public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocolSession, ConnectionConfig
{
@@ -147,7 +146,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
private Map<Integer, Long> _closingChannelsList = new ConcurrentHashMap<Integer, Long>();
private ProtocolOutputConverter _protocolOutputConverter;
- private Subject _authorizedSubject;
+ private Principal _authorizedID;
private MethodDispatcher _dispatcher;
private ProtocolSessionIdentifier _sessionIdentifier;
@@ -157,6 +156,8 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
private AMQPConnectionActor _actor;
private LogSubject _logSubject;
+ private NetworkDriver _networkDriver;
+
private long _lastIoTime;
private long _writtenBytes;
@@ -171,28 +172,21 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
private final UUID _id;
private final ConfigStore _configStore;
private long _createTime = System.currentTimeMillis();
-
- private ApplicationRegistry _registry;
- private boolean _statisticsEnabled = false;
- private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
-
- private final NetworkConnection _network;
- private final Sender<ByteBuffer> _sender;
public ManagedObject getManagedObject()
{
return _managedObject;
}
- public AMQProtocolEngine(VirtualHostRegistry virtualHostRegistry, NetworkConnection network)
+ public AMQProtocolEngine(VirtualHostRegistry virtualHostRegistry, NetworkDriver driver)
{
_stateManager = new AMQStateManager(virtualHostRegistry, this);
+ _networkDriver = driver;
+
_codecFactory = new AMQCodecFactory(true, this);
_poolReference.acquireExecutorService();
_readJob = new Job(_poolReference, Job.MAX_JOB_EVENTS, true);
_writeJob = new Job(_poolReference, Job.MAX_JOB_EVENTS, false);
- _network = network;
- _sender = _network.getSender();
_actor = new AMQPConnectionActor(this, virtualHostRegistry.getApplicationRegistry().getRootMessageLogger());
@@ -201,10 +195,9 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
_configStore = virtualHostRegistry.getConfigStore();
_id = _configStore.createId();
+
_actor.message(ConnectionMessages.OPEN(null, null, false, false));
- _registry = virtualHostRegistry.getApplicationRegistry();
- initialiseStatistics();
}
private AMQProtocolSessionMBean createMBean() throws JMException
@@ -370,14 +363,14 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
null,
mechanisms.getBytes(),
locales.getBytes());
- _sender.send(responseBody.generateFrame(0).toNioByteBuffer());
+ _networkDriver.send(responseBody.generateFrame(0).toNioByteBuffer());
}
catch (AMQException e)
{
_logger.info("Received unsupported protocol initiation for protocol version: " + getProtocolVersion());
- _sender.send(new ProtocolInitiation(ProtocolVersion.getLatestSupportedVersion()).toNioByteBuffer());
+ _networkDriver.send(new ProtocolInitiation(ProtocolVersion.getLatestSupportedVersion()).toNioByteBuffer());
}
}
@@ -498,7 +491,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
{
public void run()
{
- _sender.send(buf);
+ _networkDriver.send(buf);
}
});
}
@@ -690,8 +683,8 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
{
if (delay > 0)
{
- _network.setMaxWriteIdle(delay);
- _network.setMaxReadIdle((int) (ApplicationRegistry.getInstance().getConfiguration().getHeartBeatTimeout() * delay));
+ _networkDriver.setMaxWriteIdle(delay);
+ _networkDriver.setMaxReadIdle((int) (ApplicationRegistry.getInstance().getConfiguration().getHeartBeatTimeout() * delay));
}
}
@@ -795,7 +788,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
public void closeProtocolSession()
{
- _sender.close();
+ _networkDriver.close();
try
{
_stateManager.changeState(AMQState.CONNECTION_CLOSED);
@@ -808,7 +801,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
public String toString()
{
- return getRemoteAddress() + "(" + (getAuthorizedPrincipal() == null ? "?" : getAuthorizedPrincipal().getName() + ")");
+ return getRemoteAddress() + "(" + (getAuthorizedID() == null ? "?" : getAuthorizedID().getName() + ")");
}
public String dump()
@@ -830,11 +823,17 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
*/
public String getLocalFQDN()
{
- SocketAddress address = _network.getLocalAddress();
+ SocketAddress address = _networkDriver.getLocalAddress();
+ // we use the vmpipe address in some tests hence the need for this rather ugly test. The host
+ // information is used by SASL primary.
if (address instanceof InetSocketAddress)
{
return ((InetSocketAddress) address).getHostName();
}
+ else if (address instanceof VmPipeAddress)
+ {
+ return "vmpipe:" + ((VmPipeAddress) address).getPort();
+ }
else
{
throw new IllegalArgumentException("Unsupported socket address class: " + address);
@@ -913,7 +912,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
public Object getClientIdentifier()
{
- return _network.getRemoteAddress();
+ return (_networkDriver != null) ? _networkDriver.getRemoteAddress() : null;
}
public VirtualHost getVirtualHost()
@@ -955,33 +954,29 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
return _protocolOutputConverter;
}
- public void setAuthorizedSubject(final Subject authorizedSubject)
+ public void setAuthorizedID(Principal authorizedID)
{
- if (authorizedSubject == null)
- {
- throw new IllegalArgumentException("authorizedSubject cannot be null");
- }
- _authorizedSubject = authorizedSubject;
+ _authorizedID = authorizedID;
}
-
- public Subject getAuthorizedSubject()
+
+ public Principal getAuthorizedID()
{
- return _authorizedSubject;
+ return _authorizedID;
}
-
- public Principal getAuthorizedPrincipal()
+
+ public Principal getPrincipal()
{
- return _authorizedSubject == null ? null : UsernamePrincipal.getUsernamePrincipalFromSubject(_authorizedSubject);
+ return _authorizedID;
}
public SocketAddress getRemoteAddress()
{
- return _network.getRemoteAddress();
+ return _networkDriver.getRemoteAddress();
}
public SocketAddress getLocalAddress()
{
- return _network.getLocalAddress();
+ return _networkDriver.getLocalAddress();
}
public MethodRegistry getMethodRegistry()
@@ -1011,9 +1006,14 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
// Nothing
}
+ public void setNetworkDriver(NetworkDriver driver)
+ {
+ _networkDriver = driver;
+ }
+
public void writerIdle()
{
- _sender.send(HeartbeatBody.FRAME.toNioByteBuffer());
+ _networkDriver.send(HeartbeatBody.FRAME.toNioByteBuffer());
}
public void exception(Throwable throwable)
@@ -1021,7 +1021,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
if (throwable instanceof AMQProtocolHeaderException)
{
writeFrame(new ProtocolInitiation(ProtocolVersion.getLatestSupportedVersion()));
- _sender.close();
+ _networkDriver.close();
_logger.error("Error in protocol initiation " + this + ":" + getRemoteAddress() + " :" + throwable.getMessage(), throwable);
}
@@ -1039,7 +1039,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
writeFrame(closeBody.generateFrame(0));
- _sender.close();
+ _networkDriver.close();
}
}
@@ -1078,6 +1078,19 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
return (_clientVersion == null) ? null : _clientVersion.toString();
}
+ public void closeIfLingeringClosedChannels()
+ {
+ for (Entry<Integer, Long>id : _closingChannelsList.entrySet())
+ {
+ if (id.getValue() + 30000 > System.currentTimeMillis())
+ {
+ // We have a channel that we closed 30 seconds ago. Client's dead, kill the connection
+ _logger.error("Closing connection as channel was closed more than 30 seconds ago and no ChannelCloseOk has been processed");
+ closeProtocolSession();
+ }
+ }
+ }
+
public Boolean isIncoming()
{
return true;
@@ -1095,7 +1108,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
public String getAuthId()
{
- return getAuthorizedPrincipal().getName();
+ return getAuthorizedID().getName();
}
public Integer getRemotePID()
@@ -1250,6 +1263,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
public void closeSession(AMQSessionModel session, AMQConstant cause, String message) throws AMQException
{
+
closeChannel((Integer)session.getID());
MethodRegistry methodRegistry = getMethodRegistry();
@@ -1260,97 +1274,5 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
0,0);
writeFrame(responseBody.generateFrame((Integer)session.getID()));
- }
-
- public void close(AMQConstant cause, String message) throws AMQException
- {
- closeConnection(0, new AMQConnectionException(cause, message, 0, 0,
- getProtocolOutputConverter().getProtocolMajorVersion(),
- getProtocolOutputConverter().getProtocolMinorVersion(),
- (Throwable) null), true);
- }
-
- public List<AMQSessionModel> getSessionModels()
- {
- List<AMQSessionModel> sessions = new ArrayList<AMQSessionModel>();
- for (AMQChannel channel : getChannels())
- {
- sessions.add((AMQSessionModel) channel);
- }
- return sessions;
- }
-
- public LogSubject getLogSubject()
- {
- return _logSubject;
- }
-
- public void registerMessageDelivered(long messageSize)
- {
- if (isStatisticsEnabled())
- {
- _messagesDelivered.registerEvent(1L);
- _dataDelivered.registerEvent(messageSize);
- }
- _virtualHost.registerMessageDelivered(messageSize);
- }
-
- public void registerMessageReceived(long messageSize, long timestamp)
- {
- if (isStatisticsEnabled())
- {
- _messagesReceived.registerEvent(1L, timestamp);
- _dataReceived.registerEvent(messageSize, timestamp);
- }
- _virtualHost.registerMessageReceived(messageSize, timestamp);
- }
-
- public StatisticsCounter getMessageReceiptStatistics()
- {
- return _messagesReceived;
- }
-
- public StatisticsCounter getDataReceiptStatistics()
- {
- return _dataReceived;
- }
-
- public StatisticsCounter getMessageDeliveryStatistics()
- {
- return _messagesDelivered;
- }
-
- public StatisticsCounter getDataDeliveryStatistics()
- {
- return _dataDelivered;
- }
-
- public void resetStatistics()
- {
- _messagesDelivered.reset();
- _dataDelivered.reset();
- _messagesReceived.reset();
- _dataReceived.reset();
- }
-
- public void initialiseStatistics()
- {
- setStatisticsEnabled(!StatisticsCounter.DISABLE_STATISTICS &&
- _registry.getConfiguration().isStatisticsGenerationConnectionsEnabled());
-
- _messagesDelivered = new StatisticsCounter("messages-delivered-" + getSessionID());
- _dataDelivered = new StatisticsCounter("data-delivered-" + getSessionID());
- _messagesReceived = new StatisticsCounter("messages-received-" + getSessionID());
- _dataReceived = new StatisticsCounter("data-received-" + getSessionID());
- }
-
- public boolean isStatisticsEnabled()
- {
- return _statisticsEnabled;
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
- _statisticsEnabled = enabled;
- }
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngineFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngineFactory.java
index 94870c98bd..0e4444725e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngineFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngineFactory.java
@@ -25,7 +25,7 @@ import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.protocol.ProtocolEngineFactory;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.transport.network.NetworkConnection;
+import org.apache.qpid.transport.NetworkDriver;
public class AMQProtocolEngineFactory implements ProtocolEngineFactory
{
@@ -38,12 +38,13 @@ public class AMQProtocolEngineFactory implements ProtocolEngineFactory
public AMQProtocolEngineFactory(Integer port)
{
- _vhosts = ApplicationRegistry.getInstance().getVirtualHostRegistry();
+ _vhosts = ApplicationRegistry.getInstance(port).getVirtualHostRegistry();
}
- public ProtocolEngine newProtocolEngine(NetworkConnection network)
+ public ProtocolEngine newProtocolEngine(NetworkDriver networkDriver)
{
- return new AMQProtocolEngine(_vhosts, network);
+ return new AMQProtocolEngine(_vhosts, networkDriver);
}
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
index 9116bf2767..f48a214933 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.server.protocol;
-import javax.security.auth.Subject;
import javax.security.sasl.SaslServer;
import org.apache.qpid.AMQException;
@@ -29,15 +28,16 @@ import org.apache.qpid.framing.*;
import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.security.AuthorizationHolder;
+import org.apache.qpid.server.security.PrincipalHolder;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.output.ProtocolOutputConverter;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import java.security.Principal;
import java.util.List;
-public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, AuthorizationHolder, AMQConnectionModel
+public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, PrincipalHolder, AMQConnectionModel
{
long getSessionID();
@@ -205,7 +205,7 @@ public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, Auth
public ProtocolOutputConverter getProtocolOutputConverter();
- void setAuthorizedSubject(Subject authorizedSubject);
+ void setAuthorizedID(Principal authorizedID);
public java.net.SocketAddress getRemoteAddress();
@@ -231,5 +231,7 @@ public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, Auth
List<AMQChannel> getChannels();
+ void closeIfLingeringClosedChannels();
+
void mgmtCloseChannel(int channelId);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
index 16d99de492..f4f2cab2c2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
@@ -37,15 +37,25 @@
*/
package org.apache.qpid.server.protocol;
-import java.util.Date;
-import java.util.List;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.ConnectionCloseBody;
+import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.management.common.mbeans.ManagedConnection;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
+import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.ManagementActor;
+import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.server.management.ManagedObject;
import javax.management.JMException;
import javax.management.MBeanException;
import javax.management.MBeanNotificationInfo;
import javax.management.NotCompliantMBeanException;
import javax.management.Notification;
-import javax.management.ObjectName;
import javax.management.monitor.MonitorNotification;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
@@ -56,20 +66,8 @@ import javax.management.openmbean.SimpleType;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.ConnectionCloseBody;
-import org.apache.qpid.framing.MethodRegistry;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.ManagementActor;
-import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.management.ManagedObject;
+import java.util.Date;
+import java.util.List;
/**
* This MBean class implements the management interface. In order to make more attributes, operations and notifications
@@ -96,7 +94,8 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
super(ManagedConnection.class, ManagedConnection.TYPE);
_protocolSession = amqProtocolSession;
String remote = getRemoteAddress();
- _name = "anonymous".equals(remote) ? (remote + hashCode()) : remote;
+ remote = "anonymous".equals(remote) ? (remote + hashCode()) : remote;
+ _name = jmxEncode(new StringBuffer(remote), 0).toString();
init();
}
@@ -131,7 +130,7 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
public String getAuthorizedId()
{
- return (_protocolSession.getAuthorizedPrincipal() != null ) ? _protocolSession.getAuthorizedPrincipal().getName() : null;
+ return (_protocolSession.getPrincipal() != null ) ? _protocolSession.getPrincipal().getName() : null;
}
public String getVersion()
@@ -176,7 +175,7 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
public String getObjectInstanceName()
{
- return ObjectName.quote(_name);
+ return _name;
}
/**
@@ -340,78 +339,4 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
_broadcaster.sendNotification(n);
}
- public void resetStatistics() throws Exception
- {
- _protocolSession.resetStatistics();
- }
-
- public double getPeakMessageDeliveryRate()
- {
- return _protocolSession.getMessageDeliveryStatistics().getPeak();
- }
-
- public double getPeakDataDeliveryRate()
- {
- return _protocolSession.getDataDeliveryStatistics().getPeak();
- }
-
- public double getMessageDeliveryRate()
- {
- return _protocolSession.getMessageDeliveryStatistics().getRate();
- }
-
- public double getDataDeliveryRate()
- {
- return _protocolSession.getDataDeliveryStatistics().getRate();
- }
-
- public long getTotalMessagesDelivered()
- {
- return _protocolSession.getMessageDeliveryStatistics().getTotal();
- }
-
- public long getTotalDataDelivered()
- {
- return _protocolSession.getDataDeliveryStatistics().getTotal();
- }
-
- public double getPeakMessageReceiptRate()
- {
- return _protocolSession.getMessageReceiptStatistics().getPeak();
- }
-
- public double getPeakDataReceiptRate()
- {
- return _protocolSession.getDataReceiptStatistics().getPeak();
- }
-
- public double getMessageReceiptRate()
- {
- return _protocolSession.getMessageReceiptStatistics().getRate();
- }
-
- public double getDataReceiptRate()
- {
- return _protocolSession.getDataReceiptStatistics().getRate();
- }
-
- public long getTotalMessagesReceived()
- {
- return _protocolSession.getMessageReceiptStatistics().getTotal();
- }
-
- public long getTotalDataReceived()
- {
- return _protocolSession.getDataReceiptStatistics().getTotal();
- }
-
- public boolean isStatisticsEnabled()
- {
- return _protocolSession.isStatisticsEnabled();
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
- _protocolSession.setStatisticsEnabled(enabled);
- }
-}
+} // End of MBean class
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
index bc63403a86..a9b2354d75 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
@@ -20,35 +20,15 @@
*/
package org.apache.qpid.server.protocol;
-import org.apache.qpid.AMQException;
import org.apache.qpid.server.logging.LogSubject;
public interface AMQSessionModel
{
- public Object getID();
+ Object getID();
- public AMQConnectionModel getConnectionModel();
+ AMQConnectionModel getConnectionModel();
- public String getClientID();
-
- public void close() throws AMQException;
+ String getClientID();
- public LogSubject getLogSubject();
-
- /**
- * This method is called from the housekeeping thread to check the status of
- * transactions on this session and react appropriately.
- *
- * If a transaction is open for too long or idle for too long then a warning
- * is logged or the connection is closed, depending on the configuration. An open
- * transaction is one that has recent activity. The transaction age is counted
- * from the time the transaction was started. An idle transaction is one that
- * has had no activity, such as publishing or acknowledgeing messages.
- *
- * @param openWarn time in milliseconds before alerting on open transaction
- * @param openClose time in milliseconds before closing connection with open transaction
- * @param idleWarn time in milliseconds before alerting on idle transaction
- * @param idleClose time in milliseconds before closing connection with idle transaction
- */
- public void checkTransactionStatus(long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException;
+ LogSubject getLogSubject();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
index 01b12b44ce..eb957ee33c 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
@@ -23,11 +23,11 @@ package org.apache.qpid.server.protocol;
import org.apache.log4j.Logger;
import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory.VERSION;
import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.transport.ServerConnection;
import org.apache.qpid.transport.ConnectionDelegate;
-import org.apache.qpid.transport.Sender;
-import org.apache.qpid.transport.network.NetworkConnection;
+import org.apache.qpid.transport.NetworkDriver;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
@@ -37,24 +37,28 @@ public class MultiVersionProtocolEngine implements ProtocolEngine
{
private static final Logger _logger = Logger.getLogger(MultiVersionProtocolEngine.class);
- private Set<AmqpProtocolVersion> _supported;
+
+
+ private NetworkDriver _networkDriver;
+ private Set<VERSION> _supported;
private String _fqdn;
private IApplicationRegistry _appRegistry;
- private NetworkConnection _network;
- private Sender<ByteBuffer> _sender;
-
+
private volatile ProtocolEngine _delegate = new SelfDelegateProtocolEngine();
public MultiVersionProtocolEngine(IApplicationRegistry appRegistry,
String fqdn,
- Set<AmqpProtocolVersion> supported,
- NetworkConnection network)
+ Set<VERSION> supported, NetworkDriver networkDriver)
{
_appRegistry = appRegistry;
_fqdn = fqdn;
_supported = supported;
- _network = network;
- _sender = _network.getSender();
+ _networkDriver = networkDriver;
+ }
+
+ public void setNetworkDriver(NetworkDriver driver)
+ {
+ _delegate.setNetworkDriver(driver);
}
public SocketAddress getRemoteAddress()
@@ -151,7 +155,7 @@ private static final byte[] AMQP_0_9_1_HEADER =
private static interface DelegateCreator
{
- AmqpProtocolVersion getVersion();
+ VERSION getVersion();
byte[] getHeaderIdentifier();
ProtocolEngine getProtocolEngine();
}
@@ -159,9 +163,9 @@ private static final byte[] AMQP_0_9_1_HEADER =
private DelegateCreator creator_0_8 = new DelegateCreator()
{
- public AmqpProtocolVersion getVersion()
+ public VERSION getVersion()
{
- return AmqpProtocolVersion.v0_8;
+ return VERSION.v0_8;
}
public byte[] getHeaderIdentifier()
@@ -171,16 +175,16 @@ private static final byte[] AMQP_0_9_1_HEADER =
public ProtocolEngine getProtocolEngine()
{
- return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network);
+ return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _networkDriver);
}
};
private DelegateCreator creator_0_9 = new DelegateCreator()
{
- public AmqpProtocolVersion getVersion()
+ public VERSION getVersion()
{
- return AmqpProtocolVersion.v0_9;
+ return VERSION.v0_9;
}
@@ -191,16 +195,16 @@ private static final byte[] AMQP_0_9_1_HEADER =
public ProtocolEngine getProtocolEngine()
{
- return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network);
+ return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _networkDriver);
}
};
private DelegateCreator creator_0_9_1 = new DelegateCreator()
{
- public AmqpProtocolVersion getVersion()
+ public VERSION getVersion()
{
- return AmqpProtocolVersion.v0_9_1;
+ return VERSION.v0_9_1;
}
@@ -211,7 +215,7 @@ private static final byte[] AMQP_0_9_1_HEADER =
public ProtocolEngine getProtocolEngine()
{
- return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network);
+ return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _networkDriver);
}
};
@@ -219,9 +223,9 @@ private static final byte[] AMQP_0_9_1_HEADER =
private DelegateCreator creator_0_10 = new DelegateCreator()
{
- public AmqpProtocolVersion getVersion()
+ public VERSION getVersion()
{
- return AmqpProtocolVersion.v0_10;
+ return VERSION.v0_10;
}
@@ -238,7 +242,7 @@ private static final byte[] AMQP_0_9_1_HEADER =
ServerConnection conn = new ServerConnection();
conn.setConnectionDelegate(connDelegate);
- return new ProtocolEngine_0_10( conn, _network, _appRegistry);
+ return new ProtocolEngine_0_10( conn, _networkDriver, _appRegistry);
}
};
@@ -248,14 +252,19 @@ private static final byte[] AMQP_0_9_1_HEADER =
private class ClosedDelegateProtocolEngine implements ProtocolEngine
{
+ public void setNetworkDriver(NetworkDriver driver)
+ {
+ _networkDriver = driver;
+ }
+
public SocketAddress getRemoteAddress()
{
- return _network.getRemoteAddress();
+ return _networkDriver.getRemoteAddress();
}
public SocketAddress getLocalAddress()
{
- return _network.getLocalAddress();
+ return _networkDriver.getLocalAddress();
}
public long getWrittenBytes()
@@ -296,16 +305,22 @@ private static final byte[] AMQP_0_9_1_HEADER =
private class SelfDelegateProtocolEngine implements ProtocolEngine
{
+
private final ByteBuffer _header = ByteBuffer.allocate(MINIMUM_REQUIRED_HEADER_BYTES);
+ public void setNetworkDriver(NetworkDriver driver)
+ {
+ _networkDriver = driver;
+ }
+
public SocketAddress getRemoteAddress()
{
- return _network.getRemoteAddress();
+ return _networkDriver.getRemoteAddress();
}
public SocketAddress getLocalAddress()
{
- return _network.getLocalAddress();
+ return _networkDriver.getLocalAddress();
}
public long getWrittenBytes()
@@ -365,12 +380,14 @@ private static final byte[] AMQP_0_9_1_HEADER =
// If no delegate is found then send back the most recent support protocol version id
if(newDelegate == null)
{
- _sender.send(ByteBuffer.wrap(newestSupported));
+ _networkDriver.send(ByteBuffer.wrap(newestSupported));
_delegate = new ClosedDelegateProtocolEngine();
}
else
{
+ newDelegate.setNetworkDriver(_networkDriver);
+
_delegate = newDelegate;
_header.flip();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java
index 96d46353c6..75358c42d9 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java
@@ -20,22 +20,28 @@
*/
package org.apache.qpid.server.protocol;
-import java.util.EnumSet;
-import java.util.Set;
-
-import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.protocol.ProtocolEngineFactory;
+import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.transport.NetworkDriver;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.transport.network.NetworkConnection;
+
+import java.util.Set;
+import java.util.Arrays;
+import java.util.HashSet;
public class MultiVersionProtocolEngineFactory implements ProtocolEngineFactory
{
- private static final Set<AmqpProtocolVersion> ALL_VERSIONS = EnumSet.allOf(AmqpProtocolVersion.class);
+ ;
+
+
+ public enum VERSION { v0_8, v0_9, v0_9_1, v0_10 };
+
+ private static final Set<VERSION> ALL_VERSIONS = new HashSet<VERSION>(Arrays.asList(VERSION.values()));
private final IApplicationRegistry _appRegistry;
private final String _fqdn;
- private final Set<AmqpProtocolVersion> _supported;
+ private final Set<VERSION> _supported;
public MultiVersionProtocolEngineFactory()
@@ -43,7 +49,7 @@ public class MultiVersionProtocolEngineFactory implements ProtocolEngineFactory
this(1, "localhost", ALL_VERSIONS);
}
- public MultiVersionProtocolEngineFactory(String fqdn, Set<AmqpProtocolVersion> versions)
+ public MultiVersionProtocolEngineFactory(String fqdn, Set<VERSION> versions)
{
this(1, fqdn, versions);
}
@@ -54,16 +60,16 @@ public class MultiVersionProtocolEngineFactory implements ProtocolEngineFactory
this(1, fqdn, ALL_VERSIONS);
}
- public MultiVersionProtocolEngineFactory(int instance, String fqdn, Set<AmqpProtocolVersion> supportedVersions)
+ public MultiVersionProtocolEngineFactory(int instance, String fqdn, Set<VERSION> supportedVersions)
{
- _appRegistry = ApplicationRegistry.getInstance();
+ _appRegistry = ApplicationRegistry.getInstance(instance);
_fqdn = fqdn;
_supported = supportedVersions;
}
- public ProtocolEngine newProtocolEngine(NetworkConnection network)
+ public ProtocolEngine newProtocolEngine(NetworkDriver networkDriver)
{
- return new MultiVersionProtocolEngine(_appRegistry, _fqdn, _supported, network);
+ return new MultiVersionProtocolEngine(_appRegistry, _fqdn, _supported, networkDriver);
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java
index 8c62441d59..30d506a89b 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java
@@ -21,12 +21,13 @@
package org.apache.qpid.server.protocol;
import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.transport.NetworkDriver;
import org.apache.qpid.transport.network.InputHandler;
import org.apache.qpid.transport.network.Assembler;
import org.apache.qpid.transport.network.Disassembler;
-import org.apache.qpid.transport.network.NetworkConnection;
import org.apache.qpid.server.configuration.*;
import org.apache.qpid.server.transport.ServerConnection;
+import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.ConnectionMessages;
import org.apache.qpid.server.registry.IApplicationRegistry;
@@ -37,7 +38,7 @@ public class ProtocolEngine_0_10 extends InputHandler implements ProtocolEngine
{
public static final int MAX_FRAME_SIZE = 64 * 1024 - 1;
- private NetworkConnection _network;
+ private NetworkDriver _networkDriver;
private long _readBytes;
private long _writtenBytes;
private ServerConnection _connection;
@@ -46,17 +47,26 @@ public class ProtocolEngine_0_10 extends InputHandler implements ProtocolEngine
private long _createTime = System.currentTimeMillis();
public ProtocolEngine_0_10(ServerConnection conn,
- NetworkConnection network,
+ NetworkDriver networkDriver,
final IApplicationRegistry appRegistry)
{
super(new Assembler(conn));
_connection = conn;
_connection.setConnectionConfig(this);
- _network = network;
+ _networkDriver = networkDriver;
_id = appRegistry.getConfigStore().createId();
_appRegistry = appRegistry;
- _connection.setSender(new Disassembler(_network.getSender(), MAX_FRAME_SIZE));
+ // FIXME Two log messages to maintain compatinbility with earlier protocol versions
+ _connection.getLogActor().message(ConnectionMessages.OPEN(null, null, false, false));
+ _connection.getLogActor().message(ConnectionMessages.OPEN(null, "0-10", false, true));
+ }
+
+ public void setNetworkDriver(NetworkDriver driver)
+ {
+ _networkDriver = driver;
+ Disassembler dis = new Disassembler(driver, MAX_FRAME_SIZE);
+ _connection.setSender(dis);
_connection.onOpen(new Runnable()
{
public void run()
@@ -65,19 +75,16 @@ public class ProtocolEngine_0_10 extends InputHandler implements ProtocolEngine
}
});
- // FIXME Two log messages to maintain compatibility with earlier protocol versions
- _connection.getLogActor().message(ConnectionMessages.OPEN(null, null, false, false));
- _connection.getLogActor().message(ConnectionMessages.OPEN(null, "0-10", false, true));
}
public SocketAddress getRemoteAddress()
{
- return _network.getRemoteAddress();
+ return _networkDriver.getRemoteAddress();
}
public SocketAddress getLocalAddress()
{
- return _network.getLocalAddress();
+ return _networkDriver.getLocalAddress();
}
public long getReadBytes()
@@ -127,7 +134,7 @@ public class ProtocolEngine_0_10 extends InputHandler implements ProtocolEngine
public String getAuthId()
{
- return _connection.getAuthorizedPrincipal() == null ? null : _connection.getAuthorizedPrincipal().getName();
+ return _connection.getAuthorizationID();
}
public String getRemoteProcessName()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java
index 371ae0de50..b6e97e08fb 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java
@@ -60,7 +60,7 @@ public class AMQPriorityQueue extends SimpleAMQQueue
{
// check that all subscriptions are not in advance of the entry
SubscriptionList.SubscriptionNodeIterator subIter = _subscriptionList.iterator();
- while(subIter.advance() && entry.isAvailable())
+ while(subIter.advance() && !entry.isAcquired())
{
final Subscription subscription = subIter.getNode().getSubscription();
if(!subscription.isClosed())
@@ -70,7 +70,7 @@ public class AMQPriorityQueue extends SimpleAMQQueue
{
QueueEntry subnode = context._lastSeenEntry;
QueueEntry released = context._releasedEntry;
- while(subnode != null && entry.compareTo(subnode) < 0 && entry.isAvailable() && (released == null || released.compareTo(entry) < 0))
+ while(subnode != null && entry.compareTo(subnode) < 0 && !entry.isAcquired() && (released == null || released.compareTo(entry) < 0))
{
if(QueueContext._releasedUpdater.compareAndSet(context,released,entry))
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
index 9140a13625..de9dc42de8 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
@@ -21,18 +21,21 @@
package org.apache.qpid.server.queue;
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
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.binding.Binding;
import org.apache.qpid.server.configuration.QueueConfig;
+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.management.Managable;
import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.security.AuthorizationHolder;
+import org.apache.qpid.server.security.PrincipalHolder;
import org.apache.qpid.server.store.TransactionLogResource;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.txn.ServerTransaction;
@@ -69,8 +72,8 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
boolean isAutoDelete();
AMQShortString getOwner();
- AuthorizationHolder getAuthorizationHolder();
- void setAuthorizationHolder(AuthorizationHolder principalHolder);
+ PrincipalHolder getPrincipalHolder();
+ void setPrincipalHolder(PrincipalHolder principalHolder);
void setExclusiveOwningSession(AMQSessionModel owner);
AMQSessionModel getExclusiveOwningSession();
@@ -105,16 +108,23 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
boolean isDeleted();
+
int delete() throws AMQException;
+
void requeue(QueueEntry entry);
+ void requeue(QueueEntryImpl storeContext, Subscription subscription);
+
void dequeue(QueueEntry entry, Subscription sub);
void decrementUnackedMsgCount();
+
boolean resend(final QueueEntry entry, final Subscription subscription) throws AMQException;
+
+
void addQueueDeleteTask(final Task task);
void removeQueueDeleteTask(final Task task);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
index c8eb118b11..b5294b6d2f 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
@@ -43,7 +43,6 @@ import javax.management.JMException;
import javax.management.MBeanException;
import javax.management.MBeanNotificationInfo;
import javax.management.Notification;
-import javax.management.ObjectName;
import javax.management.OperationsException;
import javax.management.monitor.MonitorNotification;
import javax.management.openmbean.ArrayType;
@@ -98,7 +97,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
{
super(ManagedQueue.class, ManagedQueue.TYPE);
_queue = queue;
- _queueName = queue.getName();
+ _queueName = jmxEncode(new StringBuffer(queue.getNameShortString()), 0).toString();
}
public ManagedObject getParentObject()
@@ -148,7 +147,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
public String getObjectInstanceName()
{
- return ObjectName.quote(_queueName);
+ return _queueName;
}
public String getName()
@@ -507,7 +506,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
private String[] getMessageHeaderProperties(ContentHeaderBody headerBody)
{
List<String> list = new ArrayList<String>();
- BasicContentHeaderProperties headerProperties = (BasicContentHeaderProperties) headerBody.getProperties();
+ BasicContentHeaderProperties headerProperties = (BasicContentHeaderProperties) headerBody.properties;
list.add("reply-to = " + headerProperties.getReplyToAsString());
list.add("propertyFlags = " + headerProperties.getPropertyFlags());
list.add("ApplicationID = " + headerProperties.getAppIdAsString());
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java
index 3e3288404f..2d2fb3a214 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java
@@ -96,9 +96,9 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
public void setExpiration()
{
long expiration =
- ((BasicContentHeaderProperties) _contentHeaderBody.getProperties()).getExpiration();
+ ((BasicContentHeaderProperties) _contentHeaderBody.properties).getExpiration();
long timestamp =
- ((BasicContentHeaderProperties) _contentHeaderBody.getProperties()).getTimestamp();
+ ((BasicContentHeaderProperties) _contentHeaderBody.properties).getTimestamp();
if (SYNCHED_CLOCKS)
{
@@ -193,8 +193,8 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
public boolean isPersistent()
{
- return getContentHeader().getProperties() instanceof BasicContentHeaderProperties &&
- ((BasicContentHeaderProperties) getContentHeader().getProperties()).getDeliveryMode() ==
+ return getContentHeader().properties instanceof BasicContentHeaderProperties &&
+ ((BasicContentHeaderProperties) getContentHeader().properties).getDeliveryMode() ==
BasicContentHeaderProperties.PERSISTENT;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
index 88349586c3..edd1e0bdc3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
@@ -52,17 +52,6 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
}
public abstract State getState();
-
- /**
- * Returns true if state is either DEQUEUED or DELETED.
- *
- * @return true if state is either DEQUEUED or DELETED.
- */
- public boolean isDispensed()
- {
- State currentState = getState();
- return currentState == State.DEQUEUED || currentState == State.DELETED;
- }
}
@@ -206,6 +195,8 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
boolean isRejectedBy(Subscription subscription);
+ void requeue(Subscription subscription);
+
void dequeue();
void dispose();
@@ -218,18 +209,4 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
void addStateChangeListener(StateChangeListener listener);
boolean removeStateChangeListener(StateChangeListener listener);
-
- /**
- * Returns true if entry is in DEQUEUED state, otherwise returns false.
- *
- * @return true if entry is in DEQUEUED state, otherwise returns false
- */
- boolean isDequeued();
-
- /**
- * Returns true if entry is either DEQUED or DELETED state.
- *
- * @return true if entry is either DEQUED or DELETED state
- */
- boolean isDispensed();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
index e951b3dfd4..1ba4f4d89b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
@@ -358,6 +358,15 @@ public class QueueEntryImpl implements QueueEntry
}
}
+ public void requeue(Subscription subscription)
+ {
+ getQueue().requeue(this, subscription);
+ if(_stateChangeListeners != null)
+ {
+ notifyStateChange(QueueEntry.State.ACQUIRED, QueueEntry.State.AVAILABLE);
+ }
+ }
+
public void dequeue()
{
EntryState state = _state;
@@ -499,7 +508,7 @@ public class QueueEntryImpl implements QueueEntry
{
QueueEntryImpl next = nextNode();
- while(next != null && next.isDispensed() )
+ while(next != null && next.isDeleted())
{
final QueueEntryImpl newNext = next.nextNode();
@@ -547,14 +556,4 @@ public class QueueEntryImpl implements QueueEntry
return _queueEntryList;
}
- public boolean isDequeued()
- {
- return _state == DEQUEUED_STATE;
- }
-
- public boolean isDispensed()
- {
- return _state.isDispensed();
- }
-
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java
deleted file mode 100644
index 7e1d57e205..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.server.queue;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.pool.ReadWriteRunnable;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.queue.QueueRunner;
-import org.apache.qpid.server.queue.SimpleAMQQueue;
-
-/**
- * QueueRunners are Runnables used to process a queue when requiring
- * asynchronous message delivery to subscriptions, which is necessary
- * when straight-through delivery of a message to a subscription isn't
- * possible during the enqueue operation.
- */
-public class QueueRunner implements ReadWriteRunnable
-{
- private static final Logger _logger = Logger.getLogger(QueueRunner.class);
-
- private final String _name;
- private final SimpleAMQQueue _queue;
-
- public QueueRunner(SimpleAMQQueue queue, long count)
- {
- _queue = queue;
- _name = "QueueRunner-" + count + "-" + queue.getLogActor();
- }
-
- public void run()
- {
- String originalName = Thread.currentThread().getName();
- try
- {
- Thread.currentThread().setName(_name);
- CurrentActor.set(_queue.getLogActor());
-
- _queue.processQueue(this);
- }
- catch (AMQException e)
- {
- _logger.error("Exception during asynchronous delivery by " + _name, e);
- }
- finally
- {
- CurrentActor.remove();
- Thread.currentThread().setName(originalName);
- }
- }
-
- public boolean isRead()
- {
- return false;
- }
-
- public boolean isWrite()
- {
- return true;
- }
-
- public String toString()
- {
- return _name;
- }
-} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
index a095ef47ea..b003152db6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
@@ -44,7 +44,7 @@ import org.apache.qpid.server.logging.subjects.QueueLogSubject;
import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.AuthorizationHolder;
+import org.apache.qpid.server.security.PrincipalHolder;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.subscription.SubscriptionList;
import org.apache.qpid.server.txn.AutoCommitTransaction;
@@ -83,7 +83,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
/** null means shared */
private final AMQShortString _owner;
- private AuthorizationHolder _authorizationHolder;
+ private PrincipalHolder _prinicpalHolder;
private boolean _exclusive = false;
private AMQSessionModel _exclusiveOwner;
@@ -102,7 +102,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
protected final QueueEntryList _entries;
- protected final SubscriptionList _subscriptionList = new SubscriptionList();
+ protected final SubscriptionList _subscriptionList = new SubscriptionList(this);
+
+ private final AtomicReference<SubscriptionList.SubscriptionNode> _lastSubscriptionNode = new AtomicReference<SubscriptionList.SubscriptionNode>(_subscriptionList.getHead());
private volatile Subscription _exclusiveSubscriber;
@@ -371,14 +373,14 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
return _owner;
}
- public AuthorizationHolder getAuthorizationHolder()
+ public PrincipalHolder getPrincipalHolder()
{
- return _authorizationHolder;
+ return _prinicpalHolder;
}
- public void setAuthorizationHolder(final AuthorizationHolder authorizationHolder)
+ public void setPrincipalHolder(PrincipalHolder prinicpalHolder)
{
- _authorizationHolder = authorizationHolder;
+ _prinicpalHolder = prinicpalHolder;
}
@@ -600,25 +602,25 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
iterate over subscriptions and if any is at the end of the queue and can deliver this message, then deliver the message
*/
- SubscriptionList.SubscriptionNode node = _subscriptionList.getMarkedNode();
- SubscriptionList.SubscriptionNode nextNode = node.findNext();
+ SubscriptionList.SubscriptionNode node = _lastSubscriptionNode.get();
+ SubscriptionList.SubscriptionNode nextNode = node.getNext();
if (nextNode == null)
{
- nextNode = _subscriptionList.getHead().findNext();
+ nextNode = _subscriptionList.getHead().getNext();
}
while (nextNode != null)
{
- if (_subscriptionList.updateMarkedNode(node, nextNode))
+ if (_lastSubscriptionNode.compareAndSet(node, nextNode))
{
break;
}
else
{
- node = _subscriptionList.getMarkedNode();
- nextNode = node.findNext();
+ node = _lastSubscriptionNode.get();
+ nextNode = node.getNext();
if (nextNode == null)
{
- nextNode = _subscriptionList.getHead().findNext();
+ nextNode = _subscriptionList.getHead().getNext();
}
}
}
@@ -627,7 +629,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
// this catches the case where we *just* miss an update
int loops = 2;
- while (entry.isAvailable() && loops != 0)
+ while (!(entry.isAcquired() || entry.isDeleted()) && loops != 0)
{
if (nextNode == null)
{
@@ -640,13 +642,13 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
Subscription sub = nextNode.getSubscription();
deliverToSubscription(sub, entry);
}
- nextNode = nextNode.findNext();
+ nextNode = nextNode.getNext();
}
}
- if (entry.isAvailable())
+ if (!(entry.isAcquired() || entry.isDeleted()))
{
checkSubscriptionsNotAheadOfDelivery(entry);
@@ -803,6 +805,24 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
+ public void requeue(QueueEntryImpl entry, Subscription subscription)
+ {
+ SubscriptionList.SubscriptionNodeIterator subscriberIter = _subscriptionList.iterator();
+ // iterate over all the subscribers, and if they are in advance of this queue entry then move them backwards
+ while (subscriberIter.advance())
+ {
+ Subscription sub = subscriberIter.getNode().getSubscription();
+
+ // we don't make browsers send the same stuff twice
+ if (sub.seesRequeues() && (!sub.acquires() && sub == subscription))
+ {
+ updateSubRequeueEntry(sub, entry);
+ }
+ }
+
+ deliverAsync();
+ }
+
public void dequeue(QueueEntry entry, Subscription sub)
{
decrementQueueCount();
@@ -940,7 +960,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (queueListIterator.advance())
{
QueueEntry node = queueListIterator.getNode();
- if (node != null && !node.isDispensed())
+ if (node != null && !node.isDeleted())
{
entryList.add(node);
}
@@ -1044,7 +1064,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (queueListIterator.advance() && !filter.filterComplete())
{
QueueEntry node = queueListIterator.getNode();
- if (!node.isDispensed() && filter.accept(node))
+ if (!node.isDeleted() && filter.accept(node))
{
entryList.add(node);
}
@@ -1238,6 +1258,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
if ((messageId >= fromMessageId)
&& (messageId <= toMessageId)
+ && !node.isDeleted()
&& node.acquire())
{
dequeueEntry(node);
@@ -1267,7 +1288,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (noDeletes && queueListIterator.advance())
{
QueueEntry node = queueListIterator.getNode();
- if (node.acquire())
+ if (!node.isDeleted() && node.acquire())
{
dequeueEntry(node);
noDeletes = false;
@@ -1297,7 +1318,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (queueListIterator.advance())
{
QueueEntry node = queueListIterator.getNode();
- if (node.acquire())
+ if (!node.isDeleted() && node.acquire())
{
dequeueEntry(node, txn);
if(++count == request)
@@ -1564,7 +1585,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
public void deliverAsync()
{
- QueueRunner runner = new QueueRunner(this, _stateChangeCount.incrementAndGet());
+ Runner runner = new Runner(_stateChangeCount.incrementAndGet());
if (_asynchronousRunner.compareAndSet(null, runner))
{
@@ -1583,6 +1604,52 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
_asyncDelivery.execute(flusher);
}
+
+ private class Runner implements ReadWriteRunnable
+ {
+ String _name;
+ public Runner(long count)
+ {
+ _name = "QueueRunner-" + count + "-" + _logActor;
+ }
+
+ public void run()
+ {
+ String originalName = Thread.currentThread().getName();
+ try
+ {
+ Thread.currentThread().setName(_name);
+ CurrentActor.set(_logActor);
+
+ processQueue(this);
+ }
+ catch (AMQException e)
+ {
+ _logger.error(e);
+ }
+ finally
+ {
+ CurrentActor.remove();
+ Thread.currentThread().setName(originalName);
+ }
+ }
+
+ public boolean isRead()
+ {
+ return false;
+ }
+
+ public boolean isWrite()
+ {
+ return true;
+ }
+
+ public String toString()
+ {
+ return _name;
+ }
+ }
+
public void flushSubscription(Subscription sub) throws AMQException
{
// Access control
@@ -1651,7 +1718,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
QueueEntry node = getNextAvailableEntry(sub);
- if (node != null && node.isAvailable())
+ if (node != null && !(node.isAcquired() || node.isDeleted()))
{
if (sub.hasInterest(node))
{
@@ -1712,7 +1779,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
QueueEntry node = (releasedNode != null && lastSeen.compareTo(releasedNode)>=0) ? releasedNode : _entries.next(lastSeen);
boolean expired = false;
- while (node != null && (!node.isAvailable() || (expired = node.expired()) || !sub.hasInterest(node)))
+ while (node != null && (node.isAcquired() || node.isDeleted() || (expired = node.expired()) || !sub.hasInterest(node)))
{
if (expired)
{
@@ -1741,40 +1808,14 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
- /**
- * Used by queue Runners to asynchronously deliver messages to consumers.
- *
- * A queue Runner is started whenever a state change occurs, e.g when a new
- * message arrives on the queue and cannot be immediately delivered to a
- * subscription (i.e. asynchronous delivery is required). Unless there are
- * SubFlushRunners operating (due to subscriptions unsuspending) which are
- * capable of accepting/delivering all messages then these messages would
- * otherwise remain on the queue.
- *
- * processQueue should be running while there are messages on the queue AND
- * there are subscriptions that can deliver them. If there are no
- * subscriptions capable of delivering the remaining messages on the queue
- * then processQueue should stop to prevent spinning.
- *
- * Since processQueue is runs in a fixed size Executor, it should not run
- * indefinitely to prevent starving other tasks of CPU (e.g jobs to process
- * incoming messages may not be able to be scheduled in the thread pool
- * because all threads are working on clearing down large queues). To solve
- * this problem, after an arbitrary number of message deliveries the
- * processQueue job stops iterating, resubmits itself to the executor, and
- * ends the current instance
- *
- * @param runner the Runner to schedule
- * @throws AMQException
- */
- public void processQueue(QueueRunner runner) throws AMQException
+ private void processQueue(Runnable runner) throws AMQException
{
long stateChangeCount;
long previousStateChangeCount = Long.MIN_VALUE;
boolean deliveryIncomplete = true;
- boolean lastLoop = false;
- int iterations = MAX_ASYNC_DELIVERIES;
+ int extraLoops = 1;
+ long iterations = MAX_ASYNC_DELIVERIES;
_asynchronousRunner.compareAndSet(runner, null);
@@ -1791,14 +1832,12 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
if (previousStateChangeCount != stateChangeCount)
{
- //further asynchronous delivery is required since the
- //previous loop. keep going if iteration slicing allows.
- lastLoop = false;
+ extraLoops = 1;
}
previousStateChangeCount = stateChangeCount;
- boolean allSubscriptionsDone = true;
- boolean subscriptionDone;
+ deliveryIncomplete = _subscriptionList.size() != 0;
+ boolean done;
SubscriptionList.SubscriptionNodeIterator subscriptionIter = _subscriptionList.iterator();
//iterate over the subscribers and try to advance their pointer
@@ -1808,25 +1847,30 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
sub.getSendLock();
try
{
- //attempt delivery. returns true if no further delivery currently possible to this sub
- subscriptionDone = attemptDelivery(sub);
- if (subscriptionDone)
+
+ done = attemptDelivery(sub);
+
+ if (done)
{
- //close autoClose subscriptions if we are not currently intent on continuing
- if (lastLoop && sub.isAutoClose())
+ if (extraLoops == 0)
{
- unregisterSubscription(sub);
+ deliveryIncomplete = false;
+ if (sub.isAutoClose())
+ {
+ unregisterSubscription(sub);
- sub.confirmAutoClose();
+ sub.confirmAutoClose();
+ }
+ }
+ else
+ {
+ extraLoops--;
}
}
else
{
- //this subscription can accept additional deliveries, so we must
- //keep going after this (if iteration slicing allows it)
- allSubscriptionsDone = false;
- lastLoop = false;
iterations--;
+ extraLoops = 1;
}
}
finally
@@ -1834,34 +1878,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
sub.releaseSendLock();
}
}
-
- if(allSubscriptionsDone && lastLoop)
- {
- //We have done an extra loop already and there are again
- //again no further delivery attempts possible, only
- //keep going if state change demands it.
- deliveryIncomplete = false;
- }
- else if(allSubscriptionsDone)
- {
- //All subscriptions reported being done, but we have to do
- //an extra loop if the iterations are not exhausted and
- //there is still any work to be done
- deliveryIncomplete = _subscriptionList.size() != 0;
- lastLoop = true;
- }
- else
- {
- //some subscriptions can still accept more messages,
- //keep going if iteration count allows.
- lastLoop = false;
- deliveryIncomplete = true;
- }
-
_asynchronousRunner.set(null);
}
- // If iterations == 0 then the limiting factor was the time-slicing rather than available messages or credit
+ // If deliveries == 0 then the limitting factor was the time-slicing rather than available messages or credit
// therefore we should schedule this runner again (unless someone beats us to it :-) ).
if (iterations == 0 && _asynchronousRunner.compareAndSet(null, runner))
{
@@ -1881,8 +1901,8 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (queueListIterator.advance())
{
QueueEntry node = queueListIterator.getNode();
- // Only process nodes that are not currently deleted and not dequeued
- if (!node.isDispensed())
+ // Only process nodes that are not currently deleted
+ if (!node.isDeleted())
{
// If the node has exired then aquire it
if (node.expired() && node.acquire())
@@ -2222,9 +2242,4 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
}
}
-
- public LogActor getLogActor()
- {
- return _logActor;
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java
index 46baab8c85..b97c2c55c5 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java
@@ -1,5 +1,6 @@
package org.apache.qpid.server.queue;
+import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.message.ServerMessage;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
@@ -155,7 +156,7 @@ public class SimpleQueueEntryList implements QueueEntryList
if(!atTail())
{
QueueEntryImpl nextNode = _lastNode.nextNode();
- while(nextNode.isDispensed() && nextNode.nextNode() != null)
+ while(nextNode.isDeleted() && nextNode.nextNode() != null)
{
nextNode = nextNode.nextNode();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
index 7c804fc1fd..78a642f22f 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
@@ -21,14 +21,9 @@
package org.apache.qpid.server.registry;
import java.net.InetSocketAddress;
-import java.util.Collection;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
import java.util.UUID;
-import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
@@ -46,27 +41,24 @@ import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.logging.CompositeStartupMessageLogger;
import org.apache.qpid.server.logging.Log4jMessageLogger;
import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.AbstractRootMessageLogger;
import org.apache.qpid.server.logging.SystemOutMessageLogger;
-import org.apache.qpid.server.logging.actors.AbstractActor;
import org.apache.qpid.server.logging.actors.BrokerActor;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.BrokerMessages;
-import org.apache.qpid.server.logging.messages.VirtualHostMessages;
import org.apache.qpid.server.management.ManagedObjectRegistry;
import org.apache.qpid.server.management.NoopManagedObjectRegistry;
-import org.apache.qpid.server.plugins.Plugin;
import org.apache.qpid.server.plugins.PluginManager;
import org.apache.qpid.server.security.SecurityManager;
-import org.apache.qpid.server.security.SecurityManager.SecurityConfiguration;
+import org.apache.qpid.server.security.auth.database.ConfigurationFilePrincipalDatabaseManager;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManagerPluginFactory;
-import org.apache.qpid.server.stats.StatisticsCounter;
+import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
import org.apache.qpid.server.transport.QpidAcceptor;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-
/**
* An abstract application registry that provides access to configuration information and handles the
* construction and caching of configurable objects.
@@ -77,10 +69,12 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
protected static final Logger _logger = Logger.getLogger(ApplicationRegistry.class);
- private static AtomicReference<IApplicationRegistry> _instance = new AtomicReference<IApplicationRegistry>(null);
+ private static Map<Integer, IApplicationRegistry> _instanceMap = new HashMap<Integer, IApplicationRegistry>();
protected final ServerConfiguration _configuration;
+ public static final int DEFAULT_INSTANCE = 1;
+
protected final Map<InetSocketAddress, QpidAcceptor> _acceptors = new HashMap<InetSocketAddress, QpidAcceptor>();
protected ManagedObjectRegistry _managedObjectRegistry;
@@ -91,6 +85,8 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
protected SecurityManager _securityManager;
+ protected PrincipalDatabaseManager _databaseManager;
+
protected PluginManager _pluginManager;
protected ConfigurationManager _configurationManager;
@@ -106,10 +102,8 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
private BrokerConfig _broker;
private ConfigStore _configStore;
-
- private Timer _reportingTimer;
- private boolean _statisticsEnabled = false;
- private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
+
+ protected String _registryName;
static
{
@@ -120,54 +114,53 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
public void run()
{
- remove();
+ removeAll();
}
}
public static void initialise(IApplicationRegistry instance) throws Exception
{
- if(instance == null)
- {
- throw new IllegalArgumentException("ApplicationRegistry instance must not be null");
- }
+ initialise(instance, DEFAULT_INSTANCE);
+ }
- if(!_instance.compareAndSet(null, instance))
+ @SuppressWarnings("finally")
+ public static void initialise(IApplicationRegistry instance, int instanceID) throws Exception
+ {
+ if (instance != null)
{
- throw new IllegalStateException("An ApplicationRegistry is already initialised");
- }
-
- _logger.info("Initialising Application Registry(" + instance + ")");
+ _logger.info("Initialising Application Registry(" + instance + "):" + instanceID);
+ _instanceMap.put(instanceID, instance);
+ final ConfigStore store = ConfigStore.newInstance();
+ store.setRoot(new SystemConfigImpl(store));
+ instance.setConfigStore(store);
- final ConfigStore store = ConfigStore.newInstance();
- store.setRoot(new SystemConfigImpl(store));
- instance.setConfigStore(store);
+ BrokerConfig broker = new BrokerConfigAdapter(instance);
- BrokerConfig broker = new BrokerConfigAdapter(instance);
+ SystemConfig system = (SystemConfig) store.getRoot();
+ system.addBroker(broker);
+ instance.setBroker(broker);
- SystemConfig system = (SystemConfig) store.getRoot();
- system.addBroker(broker);
- instance.setBroker(broker);
-
- try
- {
- instance.initialise();
- }
- catch (Exception e)
- {
- _instance.set(null);
-
- //remove the Broker instance, then re-throw
try
{
- system.removeBroker(broker);
+ instance.initialise(instanceID);
}
- catch(Throwable t)
+ catch (Exception e)
{
- //ignore
+ _instanceMap.remove(instanceID);
+ try
+ {
+ system.removeBroker(broker);
+ }
+ finally
+ {
+ throw e;
+ }
}
-
- throw e;
+ }
+ else
+ {
+ remove(instanceID);
}
}
@@ -183,19 +176,35 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
public static boolean isConfigured()
{
- return _instance.get() != null;
+ return isConfigured(DEFAULT_INSTANCE);
+ }
+
+ public static boolean isConfigured(int instanceID)
+ {
+ return _instanceMap.containsKey(instanceID);
}
+ /** Method to cleanly shutdown the default registry running in this JVM */
public static void remove()
{
- IApplicationRegistry instance = _instance.getAndSet(null);
+ remove(DEFAULT_INSTANCE);
+ }
+
+ /**
+ * Method to cleanly shutdown specified registry running in this JVM
+ *
+ * @param instanceID the instance to shutdown
+ */
+ public static void remove(int instanceID)
+ {
try
{
+ IApplicationRegistry instance = _instanceMap.get(instanceID);
if (instance != null)
{
if (_logger.isInfoEnabled())
{
- _logger.info("Shutting down ApplicationRegistry(" + instance + ")");
+ _logger.info("Shutting down ApplicationRegistry(" + instanceID + "):" + instance);
}
instance.close();
instance.getBroker().getSystem().removeBroker(instance.getBroker());
@@ -203,7 +212,21 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
}
catch (Exception e)
{
- _logger.error("Error shutting down Application Registry(" + instance + "): " + e, e);
+ _logger.error("Error shutting down Application Registry(" + instanceID + "): " + e, e);
+ }
+ finally
+ {
+ _instanceMap.remove(instanceID);
+ }
+ }
+
+ /** Method to cleanly shutdown all registries currently running in this JVM */
+ public static void removeAll()
+ {
+ Object[] keys = _instanceMap.keySet().toArray();
+ for (Object k : keys)
+ {
+ remove((Integer) k);
}
}
@@ -228,10 +251,11 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
_configuration.initialise();
}
- public void initialise() throws Exception
+ public void initialise(int instanceID) throws Exception
{
//Create the RootLogger to be used during broker operation
_rootMessageLogger = new Log4jMessageLogger(_configuration);
+ _registryName = String.valueOf(instanceID);
//Create the composite (log4j+SystemOut MessageLogger to be used during startup
RootMessageLogger[] messageLoggers = {new SystemOutMessageLogger(), _rootMessageLogger};
@@ -253,7 +277,11 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
_securityManager = new SecurityManager(_configuration, _pluginManager);
- _authenticationManager = createAuthenticationManager();
+ createDatabaseManager(_configuration);
+
+ _authenticationManager = new PrincipalDatabaseAuthenticationManager(null, null);
+
+ _databaseManager.initialiseManagement(_configuration);
_managedObjectRegistry.start();
}
@@ -266,8 +294,6 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
try
{
initialiseVirtualHosts();
- initialiseStatistics();
- initialiseStatisticsReporting();
}
finally
{
@@ -276,51 +302,9 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
}
}
- /**
- * Iterates across all discovered authentication manager factories, offering the security configuration to each.
- * Expects <b>exactly</b> one authentication manager to configure and initialise itself.
- *
- * It is an error to configure more than one authentication manager, or to configure none.
- *
- * @return authentication manager
- * @throws ConfigurationException
- */
- protected AuthenticationManager createAuthenticationManager() throws ConfigurationException
+ protected void createDatabaseManager(ServerConfiguration configuration) throws Exception
{
- final SecurityConfiguration securityConfiguration = _configuration.getConfiguration(SecurityConfiguration.class.getName());
- final Collection<AuthenticationManagerPluginFactory<? extends Plugin>> factories = _pluginManager.getAuthenticationManagerPlugins().values();
-
- if (factories.size() == 0)
- {
- throw new ConfigurationException("No authentication manager factory plugins found. Check the desired authentication" +
- "manager plugin has been placed in the plugins directory.");
- }
-
- AuthenticationManager authMgr = null;
-
- for (final Iterator<AuthenticationManagerPluginFactory<? extends Plugin>> iterator = factories.iterator(); iterator.hasNext();)
- {
- final AuthenticationManagerPluginFactory<? extends Plugin> factory = (AuthenticationManagerPluginFactory<? extends Plugin>) iterator.next();
- final AuthenticationManager tmp = factory.newInstance(securityConfiguration);
- if (tmp != null)
- {
- if (authMgr != null)
- {
- throw new ConfigurationException("Cannot configure more than one authentication manager."
- + " Both " + tmp.getClass() + " and " + authMgr.getClass() + " are configured."
- + " Remove configuration for one of the authentication manager, or remove the plugin JAR"
- + " from the classpath.");
- }
- authMgr = tmp;
- }
- }
-
- if (authMgr == null)
- {
- throw new ConfigurationException("No authentication managers configured within the configure file.");
- }
-
- return authMgr;
+ _databaseManager = new ConfigurationFilePrincipalDatabaseManager(_configuration);
}
protected void initialiseVirtualHosts() throws Exception
@@ -336,88 +320,26 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
_managedObjectRegistry = new NoopManagedObjectRegistry();
}
-
- public void initialiseStatisticsReporting()
- {
- long report = _configuration.getStatisticsReportingPeriod() * 1000; // convert to ms
- final boolean broker = _configuration.isStatisticsGenerationBrokerEnabled();
- final boolean virtualhost = _configuration.isStatisticsGenerationVirtualhostsEnabled();
- final boolean reset = _configuration.isStatisticsReportResetEnabled();
-
- /* add a timer task to report statistics if generation is enabled for broker or virtualhosts */
- if (report > 0L && (broker || virtualhost))
- {
- _reportingTimer = new Timer("Statistics-Reporting", true);
-
- class StatisticsReportingTask extends TimerTask
- {
- private final int DELIVERED = 0;
- private final int RECEIVED = 1;
-
- public void run()
- {
- CurrentActor.set(new AbstractActor(ApplicationRegistry.getInstance().getRootMessageLogger()) {
- public String getLogMessage()
- {
- return "[" + Thread.currentThread().getName() + "] ";
- }
- });
-
- if (broker)
- {
- 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()));
- }
-
- if (virtualhost)
- {
- for (VirtualHost vhost : getVirtualHostRegistry().getVirtualHosts())
- {
- 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)
- {
- resetStatistics();
- }
-
- CurrentActor.remove();
- }
- }
- _reportingTimer.scheduleAtFixedRate(new StatisticsReportingTask(),
- report / 2,
- report);
- }
+ public static IApplicationRegistry getInstance()
+ {
+ return getInstance(DEFAULT_INSTANCE);
}
- /**
- * Get the ApplicationRegistry
- * @return the IApplicationRegistry instance
- * @throws IllegalStateException if no registry instance has been initialised.
- */
- public static IApplicationRegistry getInstance() throws IllegalStateException
+ public static IApplicationRegistry getInstance(int instanceID)
{
- IApplicationRegistry iApplicationRegistry = _instance.get();
- if (iApplicationRegistry == null)
- {
- throw new IllegalStateException("No ApplicationRegistry has been initialised");
- }
- else
+ synchronized (IApplicationRegistry.class)
{
- return iApplicationRegistry;
+ IApplicationRegistry instance = _instanceMap.get(instanceID);
+
+ if (instance == null)
+ {
+ throw new IllegalStateException("Application Registry (" + instanceID + ") not created");
+ }
+ else
+ {
+ return instance;
+ }
}
}
@@ -447,12 +369,6 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
_logger.info("Shutting down ApplicationRegistry:" + this);
}
-
- //Stop Statistics Reporting
- if (_reportingTimer != null)
- {
- _reportingTimer.cancel();
- }
//Stop incoming connections
unbind();
@@ -460,6 +376,10 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
//Shutdown virtualhosts
close(_virtualHostRegistry);
+// close(_accessManager);
+//
+// close(_databaseManager);
+
close(_authenticationManager);
close(_managedObjectRegistry);
@@ -481,7 +401,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
try
{
- acceptor.getNetworkTransport().close();
+ acceptor.getNetworkDriver().close();
}
catch (Throwable e)
{
@@ -521,6 +441,11 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
return _managedObjectRegistry;
}
+ public PrincipalDatabaseManager getDatabaseManager()
+ {
+ return _databaseManager;
+ }
+
public AuthenticationManager getAuthenticationManager()
{
return _authenticationManager;
@@ -573,76 +498,4 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
getBroker().addVirtualHost(virtualHost);
return virtualHost;
}
-
- public void registerMessageDelivered(long messageSize)
- {
- if (isStatisticsEnabled())
- {
- _messagesDelivered.registerEvent(1L);
- _dataDelivered.registerEvent(messageSize);
- }
- }
-
- public void registerMessageReceived(long messageSize, long timestamp)
- {
- if (isStatisticsEnabled())
- {
- _messagesReceived.registerEvent(1L, timestamp);
- _dataReceived.registerEvent(messageSize, timestamp);
- }
- }
-
- public StatisticsCounter getMessageReceiptStatistics()
- {
- return _messagesReceived;
- }
-
- public StatisticsCounter getDataReceiptStatistics()
- {
- return _dataReceived;
- }
-
- public StatisticsCounter getMessageDeliveryStatistics()
- {
- return _messagesDelivered;
- }
-
- public StatisticsCounter getDataDeliveryStatistics()
- {
- return _dataDelivered;
- }
-
- public void resetStatistics()
- {
- _messagesDelivered.reset();
- _dataDelivered.reset();
- _messagesReceived.reset();
- _dataReceived.reset();
-
- for (VirtualHost vhost : _virtualHostRegistry.getVirtualHosts())
- {
- vhost.resetStatistics();
- }
- }
-
- public void initialiseStatistics()
- {
- setStatisticsEnabled(!StatisticsCounter.DISABLE_STATISTICS &&
- getConfiguration().isStatisticsGenerationBrokerEnabled());
-
- _messagesDelivered = new StatisticsCounter("messages-delivered");
- _dataDelivered = new StatisticsCounter("bytes-delivered");
- _messagesReceived = new StatisticsCounter("messages-received");
- _dataReceived = new StatisticsCounter("bytes-received");
- }
-
- public boolean isStatisticsEnabled()
- {
- return _statisticsEnabled;
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
- _statisticsEnabled = enabled;
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java
index 108533ef96..4a4253153c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java
@@ -71,7 +71,7 @@ public class BrokerConfigAdapter implements BrokerConfig
public Integer getWorkerThreads()
{
- return _instance.getConfiguration().getConnectorProcessors();
+ return _instance.getConfiguration().getProcessors();
}
public Integer getMaxConnections()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
index c27e0d19ec..228c3b9112 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
@@ -33,20 +33,21 @@ import org.apache.qpid.server.logging.RootMessageLogger;
import org.apache.qpid.server.management.ManagedObjectRegistry;
import org.apache.qpid.server.plugins.PluginManager;
import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-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;
-public interface IApplicationRegistry extends StatisticsGatherer
+public interface IApplicationRegistry
{
/**
* Initialise the application registry. All initialisation must be done in this method so that any components
* that need access to the application registry itself for initialisation are able to use it. Attempting to
* initialise in the constructor will lead to failures since the registry reference will not have been set.
+ * @param instanceID the instanceID that we can use to identify this AR.
*/
- void initialise() throws Exception;
+ void initialise(int instanceID) throws Exception;
/**
* Shutdown this Registry
@@ -62,6 +63,8 @@ public interface IApplicationRegistry extends StatisticsGatherer
ManagedObjectRegistry getManagedObjectRegistry();
+ PrincipalDatabaseManager getDatabaseManager();
+
AuthenticationManager getAuthenticationManager();
VirtualHostRegistry getVirtualHostRegistry();
@@ -94,6 +97,4 @@ public interface IApplicationRegistry extends StatisticsGatherer
ConfigStore getConfigStore();
void setConfigStore(ConfigStore store);
-
- void initialiseStatisticsReporting();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java
deleted file mode 100755
index 3d8c77a86f..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java
+++ /dev/null
@@ -1,53 +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 java.security.Principal;
-
-import javax.security.auth.Subject;
-
-import org.apache.qpid.server.security.auth.sasl.GroupPrincipal;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
-
-/**
- * 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 UsernamePrincipal}, representing the the identity
- * used when the user logged on to the application, and zero or more {@link GroupPrincipal}
- * representing the group(s) to which the user belongs.
- *
- * @return the Subject
- */
- 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/qpid/java/broker/src/main/java/org/apache/qpid/server/security/PrincipalHolder.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/PrincipalHolder.java
new file mode 100755
index 0000000000..7e93623cab
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/PrincipalHolder.java
@@ -0,0 +1,29 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.security;
+
+import java.security.Principal;
+
+public interface PrincipalHolder
+{
+ /** @return a Principal that was used to authorized this session */
+ Principal getPrincipal();
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
index f582fed6a0..f18c327692 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
@@ -18,19 +18,8 @@
*/
package org.apache.qpid.server.security;
-import static org.apache.qpid.server.security.access.ObjectType.EXCHANGE;
-import static org.apache.qpid.server.security.access.ObjectType.METHOD;
-import static org.apache.qpid.server.security.access.ObjectType.OBJECT;
-import static org.apache.qpid.server.security.access.ObjectType.QUEUE;
-import static org.apache.qpid.server.security.access.ObjectType.VIRTUALHOST;
-import static org.apache.qpid.server.security.access.Operation.ACCESS;
-import static org.apache.qpid.server.security.access.Operation.BIND;
-import static org.apache.qpid.server.security.access.Operation.CONSUME;
-import static org.apache.qpid.server.security.access.Operation.CREATE;
-import static org.apache.qpid.server.security.access.Operation.DELETE;
-import static org.apache.qpid.server.security.access.Operation.PUBLISH;
-import static org.apache.qpid.server.security.access.Operation.PURGE;
-import static org.apache.qpid.server.security.access.Operation.UNBIND;
+import static org.apache.qpid.server.security.access.ObjectType.*;
+import static org.apache.qpid.server.security.access.Operation.*;
import java.net.SocketAddress;
import java.security.Principal;
@@ -40,8 +29,6 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import javax.security.auth.Subject;
-
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
@@ -50,9 +37,11 @@ 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.protocol.AMQProtocolSession;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.security.access.ObjectProperties;
import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
/**
* The security manager contains references to all loaded {@link SecurityPlugin}s and delegates security decisions to them based
@@ -66,7 +55,7 @@ public class SecurityManager
private static final Logger _logger = Logger.getLogger(SecurityManager.class);
/** Container for the {@link Principal} that is using to this thread. */
- private static final ThreadLocal<Subject> _subject = new ThreadLocal<Subject>();
+ private static final ThreadLocal<Principal> _principal = new ThreadLocal<Principal>();
private PluginManager _pluginManager;
private Map<String, SecurityPluginFactory> _pluginFactories = new HashMap<String, SecurityPluginFactory>();
@@ -137,14 +126,19 @@ public class SecurityManager
configureHostPlugins(configuration);
}
- public static Subject getThreadSubject()
+ public static Principal getThreadPrincipal()
+ {
+ return _principal.get();
+ }
+
+ public static void setThreadPrincipal(Principal principal)
{
- return _subject.get();
+ _principal.set(principal);
}
- public static void setThreadSubject(final Subject subject)
+ public static void setThreadPrincipal(String authId)
{
- _subject.set(subject);
+ setThreadPrincipal(new UsernamePrincipal(authId));
}
public void configureHostPlugins(ConfigurationPlugin hostConfig) throws ConfigurationException
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
index e4bf8df340..70a9ea5356 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
@@ -149,9 +149,9 @@ public class ObjectProperties extends HashMap<ObjectProperties.Property, String>
{
put(Property.OWNER, queue.getOwner());
}
- else if (queue.getAuthorizationHolder() != null)
+ else if (queue.getPrincipalHolder() != null)
{
- put(Property.OWNER, queue.getAuthorizationHolder().getAuthorizedPrincipal().getName());
+ put(Property.OWNER, queue.getPrincipalHolder().getPrincipal().getName());
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
index 8c2d60a660..62967ef7eb 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
@@ -20,93 +20,42 @@
*/
package org.apache.qpid.server.security.auth;
-import javax.security.auth.Subject;
-
-/**
- * Encapsulates the result of an attempt to authenticate.
- * <p>
- * The authentication status describes the overall outcome.
- * <p>
- * <ol>
- * <li>If authentication status is SUCCESS, the subject 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
- * is made available.
- * </li>
- * <li>If authentication status is ERROR , the authentication decision could not be made due
- * to a failure (such as an external system), the {@link AuthenticationResult#getCause()}
- * will provide the underlying exception.
- * </li>
- * </ol>
- *
- */
public class AuthenticationResult
{
public enum AuthenticationStatus
{
- /** Authentication successful */
- SUCCESS,
- /** Authentication not successful due to credentials problem etc */
- CONTINUE,
- /** Problem prevented the authentication from being made e.g. failure of an external system */
- ERROR
+ SUCCESS, CONTINUE, ERROR
}
- public final AuthenticationStatus _status;
- public final byte[] _challenge;
- private final Exception _cause;
- private final Subject _subject;
+ public AuthenticationStatus status;
+ public byte[] challenge;
+
+ private Exception cause;
- public AuthenticationResult(final AuthenticationStatus status)
+ public AuthenticationResult(AuthenticationStatus status)
{
this(null, status, null);
}
- public AuthenticationResult(final byte[] challenge, final AuthenticationStatus status)
+ public AuthenticationResult(byte[] challenge, AuthenticationStatus status)
{
this(challenge, status, null);
}
- public AuthenticationResult(final AuthenticationStatus error, final Exception cause)
+ public AuthenticationResult(AuthenticationStatus error, Exception cause)
{
this(null, error, cause);
}
- public AuthenticationResult(final byte[] challenge, final AuthenticationStatus status, final Exception cause)
- {
- this._status = status;
- this._challenge = challenge;
- this._cause = cause;
- this._subject = null;
- }
-
- public AuthenticationResult(final Subject subject)
+ public AuthenticationResult(byte[] challenge, AuthenticationStatus status, Exception cause)
{
- this._status = AuthenticationStatus.SUCCESS;
- this._challenge = null;
- this._cause = null;
- this._subject = subject;
+ this.status = status;
+ this.challenge = challenge;
+ this.cause = cause;
}
public Exception getCause()
{
- return _cause;
- }
-
- public AuthenticationStatus getStatus()
- {
- return _status;
- }
-
- public byte[] getChallenge()
- {
- return _challenge;
+ return cause;
}
-
- public Subject getSubject()
- {
- return _subject;
- }
-
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
new file mode 100644
index 0000000000..5cebb7d2d8
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
@@ -0,0 +1,221 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * 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.database;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.configuration.PropertyUtils;
+import org.apache.qpid.configuration.PropertyException;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
+import org.apache.qpid.server.security.auth.management.AMQUserManagementMBean;
+import org.apache.qpid.AMQException;
+
+import javax.management.JMException;
+
+public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatabaseManager
+{
+ private static final Logger _logger = Logger.getLogger(ConfigurationFilePrincipalDatabaseManager.class);
+
+ Map<String, PrincipalDatabase> _databases;
+
+ public ConfigurationFilePrincipalDatabaseManager(ServerConfiguration _configuration) throws Exception
+ {
+ _logger.info("Initialising PrincipalDatabase authentication manager");
+ _databases = initialisePrincipalDatabases(_configuration);
+ }
+
+ private Map<String, PrincipalDatabase> initialisePrincipalDatabases(ServerConfiguration _configuration) throws Exception
+ {
+ List<String> databaseNames = _configuration.getPrincipalDatabaseNames();
+ List<String> databaseClasses = _configuration.getPrincipalDatabaseClass();
+ Map<String, PrincipalDatabase> databases = new HashMap<String, PrincipalDatabase>();
+
+ if (databaseNames.size() == 0)
+ {
+ _logger.warn("No Principal databases specified. Broker running with NO AUTHENTICATION");
+ }
+
+ for (int i = 0; i < databaseNames.size(); i++)
+ {
+ Object o;
+ try
+ {
+ o = Class.forName(databaseClasses.get(i)).newInstance();
+ }
+ catch (Exception e)
+ {
+ throw new Exception("Error initialising principal database: " + e, e);
+ }
+
+ if (!(o instanceof PrincipalDatabase))
+ {
+ throw new Exception("Principal databases must implement the PrincipalDatabase interface");
+ }
+
+ initialisePrincipalDatabase((PrincipalDatabase) o, _configuration, i);
+
+ String name = databaseNames.get(i);
+ if ((name == null) || (name.length() == 0))
+ {
+ throw new Exception("Principal database names must have length greater than or equal to one character");
+ }
+
+ PrincipalDatabase pd = databases.get(name);
+ if (pd != null)
+ {
+ throw new Exception("Duplicate principal database name not permitted");
+ }
+
+ _logger.info("Initialised principal database '" + name + "' successfully");
+ databases.put(name, (PrincipalDatabase) o);
+ }
+
+ return databases;
+ }
+
+ private void initialisePrincipalDatabase(PrincipalDatabase principalDatabase, ServerConfiguration _configuration, int index)
+ throws FileNotFoundException, ConfigurationException
+ {
+ List<String> argumentNames = _configuration.getPrincipalDatabaseAttributeNames(index);
+ List<String> argumentValues = _configuration.getPrincipalDatabaseAttributeValues(index);
+ for (int i = 0; i < argumentNames.size(); i++)
+ {
+ String argName = argumentNames.get(i);
+ 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);
+ }
+
+ String methodName = "set" + argName;
+ Method method = null;
+ try
+ {
+ method = principalDatabase.getClass().getMethod(methodName, String.class);
+ }
+ catch (Exception e)
+ {
+ // do nothing.. as on error method will be null
+ }
+
+ if (method == null)
+ {
+ 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");
+ }
+
+ try
+ {
+ method.invoke(principalDatabase, PropertyUtils.replaceProperties(argumentValues.get(i)));
+ }
+ catch (Exception ite)
+ {
+ if (ite instanceof ConfigurationException)
+ {
+ throw(ConfigurationException) ite;
+ }
+ else
+ {
+ throw new ConfigurationException(ite.getMessage(), ite);
+ }
+ }
+ }
+ }
+
+ public Map<String, PrincipalDatabase> getDatabases()
+ {
+ return _databases;
+ }
+
+ public void initialiseManagement(ServerConfiguration config) throws ConfigurationException
+ {
+ try
+ {
+ AMQUserManagementMBean _mbean = new AMQUserManagementMBean();
+
+ List<String> principalDBs = config.getManagementPrincipalDBs();
+ if (principalDBs.isEmpty())
+ {
+ throw new ConfigurationException("No principal-database specified for jmx security");
+ }
+
+ String databaseName = principalDBs.get(0);
+ PrincipalDatabase database = getDatabases().get(databaseName);
+ if (database == null)
+ {
+ throw new ConfigurationException("Principal-database '" + databaseName + "' not found");
+ }
+
+ _mbean.setPrincipalDatabase(database);
+
+ List<String> jmxaccesslist = config.getManagementAccessList();
+ if (jmxaccesslist.isEmpty())
+ {
+ throw new ConfigurationException("No access control files specified for jmx security");
+ }
+
+ String jmxaccesssFile = null;
+
+ try
+ {
+ jmxaccesssFile = PropertyUtils.replaceProperties(jmxaccesslist.get(0));
+ }
+ catch (PropertyException e)
+ {
+ throw new ConfigurationException("Unable to parse access control filename '" + jmxaccesssFile + "'");
+ }
+
+ try
+ {
+ _mbean.setAccessFile(jmxaccesssFile);
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Unable to load access file:" + jmxaccesssFile);
+ }
+
+ _mbean.register();
+ }
+ catch (JMException e)
+ {
+ _logger.warn("User management disabled as unable to create MBean:" + e);
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java
new file mode 100644
index 0000000000..f9882f8810
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * 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.database;
+
+import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+
+import java.util.Map;
+
+public interface PrincipalDatabaseManager
+{
+ public Map<String, PrincipalDatabase> getDatabases();
+
+ public void initialiseManagement(ServerConfiguration _configuration) throws ConfigurationException;
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java
new file mode 100644
index 0000000000..8658101cd8
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.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.security.auth.database;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+
+import java.util.Map;
+import java.util.Properties;
+import java.util.HashMap;
+
+public class PropertiesPrincipalDatabaseManager implements PrincipalDatabaseManager
+{
+
+ Map<String, PrincipalDatabase> _databases = new HashMap<String, PrincipalDatabase>();
+
+ public PropertiesPrincipalDatabaseManager(String name, Properties users)
+ {
+ _databases.put(name, new PropertiesPrincipalDatabase(users));
+ }
+
+ public Map<String, PrincipalDatabase> getDatabases()
+ {
+ return _databases;
+ }
+
+ public void initialiseManagement(ServerConfiguration _configuration) throws ConfigurationException
+ {
+ //todo
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java
index 208130379e..ee4336055b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java
@@ -20,9 +20,19 @@
*/
package org.apache.qpid.server.security.auth.management;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.security.AccessControlContext;
+import java.security.AccessController;
import java.security.Principal;
+import java.util.Enumeration;
import java.util.List;
+import java.util.Properties;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantLock;
import javax.management.JMException;
import javax.management.openmbean.CompositeData;
@@ -34,13 +44,17 @@ import javax.management.openmbean.SimpleType;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
+import javax.management.remote.JMXPrincipal;
+import javax.security.auth.Subject;
import javax.security.auth.login.AccountNotFoundException;
+import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.qpid.management.common.mbeans.UserManagement;
import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation;
import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.server.management.MBeanInvocationHandlerImpl;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
@@ -51,18 +65,22 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
private static final Logger _logger = Logger.getLogger(AMQUserManagementMBean.class);
private PrincipalDatabase _principalDatabase;
+ private Properties _accessRights;
+ private File _accessFile;
+
+ private ReentrantLock _accessRightsUpdate = new ReentrantLock();
// Setup for the TabularType
- private static final TabularType _userlistDataType; // Datatype for representing User Lists
- private static final CompositeType _userDataType; // Composite type for representing User
+ static TabularType _userlistDataType; // Datatype for representing User Lists
+ static CompositeType _userDataType; // Composite type for representing User
static
{
OpenType[] userItemTypes = new OpenType[4]; // User item types.
userItemTypes[0] = SimpleType.STRING; // For Username
- userItemTypes[1] = SimpleType.BOOLEAN; // For Rights - Read - No longer in use
- userItemTypes[2] = SimpleType.BOOLEAN; // For Rights - Write - No longer in use
- userItemTypes[3] = SimpleType.BOOLEAN; // For Rights - Admin - No longer is use
+ userItemTypes[1] = SimpleType.BOOLEAN; // For Rights - Read
+ userItemTypes[2] = SimpleType.BOOLEAN; // For Rights - Write
+ userItemTypes[3] = SimpleType.BOOLEAN; // For Rights - Admin
try
{
@@ -74,11 +92,12 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
}
catch (OpenDataException e)
{
- _logger.error("Tabular data setup for viewing users incorrect.", e);
- throw new ExceptionInInitializerError("Tabular data setup for viewing users incorrect");
+ _logger.error("Tabular data setup for viewing users incorrect.");
+ _userlistDataType = null;
}
}
+
public AMQUserManagementMBean() throws JMException
{
super(UserManagement.class, UserManagement.TYPE);
@@ -91,23 +110,121 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
public boolean setPassword(String username, String password)
{
+ return setPassword(username, password.toCharArray());
+ }
+
+ public boolean setPassword(String username, char[] password)
+ {
try
{
//delegate password changes to the Principal Database
- return _principalDatabase.updatePassword(new UsernamePrincipal(username), password.toCharArray());
+ return _principalDatabase.updatePassword(new UsernamePrincipal(username), password);
}
catch (AccountNotFoundException e)
{
- _logger.warn("Attempt to set password of non-existent user'" + username + "'");
+ _logger.warn("Attempt to set password of non-existant user'" + username + "'");
return false;
}
}
- public boolean createUser(String username, String password)
+ public boolean setRights(String username, boolean read, boolean write, boolean admin)
{
- if (_principalDatabase.createPrincipal(new UsernamePrincipal(username), password.toCharArray()))
+
+ Object oldRights = null;
+ if ((oldRights =_accessRights.get(username)) == null)
{
- return true;
+ // If the user doesn't exist in the access rights file check that they at least have an account.
+ if (_principalDatabase.getUser(username) == null)
+ {
+ return false;
+ }
+ }
+
+ try
+ {
+ _accessRightsUpdate.lock();
+
+ // Update the access rights
+ if (admin)
+ {
+ _accessRights.put(username, MBeanInvocationHandlerImpl.ADMIN);
+ }
+ else
+ {
+ if (read | write)
+ {
+ if (read)
+ {
+ _accessRights.put(username, MBeanInvocationHandlerImpl.READONLY);
+ }
+ if (write)
+ {
+ _accessRights.put(username, MBeanInvocationHandlerImpl.READWRITE);
+ }
+ }
+ else
+ {
+ _accessRights.remove(username);
+ }
+ }
+
+ //save the rights file
+ try
+ {
+ saveAccessFile();
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Problem occured saving '" + _accessFile + "', the access right changes will not be preserved: " + e);
+
+ //the rights file was not successfully saved, restore user rights to previous value
+ _logger.warn("Reverting attempted rights update for user'" + username + "'");
+ if (oldRights != null)
+ {
+ _accessRights.put(username, oldRights);
+ }
+ else
+ {
+ _accessRights.remove(username);
+ }
+
+ return false;
+ }
+ }
+ finally
+ {
+ _accessRightsUpdate.unlock();
+ }
+
+ return true;
+ }
+
+ public boolean createUser(String username, String password, boolean read, boolean write, boolean admin)
+ {
+ return createUser(username, password.toCharArray(), read, write, admin);
+ }
+
+ public boolean createUser(String username, char[] password, boolean read, boolean write, boolean admin)
+ {
+ if (_principalDatabase.createPrincipal(new UsernamePrincipal(username), password))
+ {
+ if (!setRights(username, read, write, admin))
+ {
+ //unable to set rights for user, remove account
+ try
+ {
+ _principalDatabase.deletePrincipal(new UsernamePrincipal(username));
+ }
+ catch (AccountNotFoundException e)
+ {
+ //ignore
+ }
+ return false;
+ }
+ else
+ {
+ return true;
+ }
}
return false;
@@ -117,7 +234,29 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
{
try
{
- _principalDatabase.deletePrincipal(new UsernamePrincipal(username));
+ if (_principalDatabase.deletePrincipal(new UsernamePrincipal(username)))
+ {
+ try
+ {
+ _accessRightsUpdate.lock();
+
+ _accessRights.remove(username);
+
+ try
+ {
+ saveAccessFile();
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Problem occured saving '" + _accessFile + "', the access right changes will not be preserved: " + e);
+ return false;
+ }
+ }
+ finally
+ {
+ _accessRightsUpdate.unlock();
+ }
+ }
}
catch (AccountNotFoundException e)
{
@@ -130,23 +269,38 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
public boolean reloadData()
{
- try
- {
- _principalDatabase.reload();
- }
- catch (IOException e)
- {
- _logger.warn("Reload failed due to:", e);
- return false;
- }
- // Reload successful
- return true;
+ try
+ {
+ loadAccessFile();
+ _principalDatabase.reload();
+ }
+ catch (ConfigurationException e)
+ {
+ _logger.warn("Reload failed due to:" + e);
+ return false;
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Reload failed due to:" + e);
+ return false;
+ }
+ // Reload successful
+ return true;
}
- @MBeanOperation(name = "viewUsers", description = "All users that are currently available to the system.")
+ @MBeanOperation(name = "viewUsers", description = "All users with access rights to the system.")
public TabularData viewUsers()
{
+ // Table of users
+ // Username(string), Access rights Read,Write,Admin(bool,bool,bool)
+
+ if (_userlistDataType == null)
+ {
+ _logger.warn("TabluarData not setup correctly");
+ return null;
+ }
+
List<Principal> users = _principalDatabase.getUsers();
TabularDataSupport userList = new TabularDataSupport(_userlistDataType);
@@ -157,15 +311,29 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
for (Principal user : users)
{
// Create header attributes list
- // Read,Write,Admin items are depcreated and we return always false.
- Object[] itemData = {user.getName(), false, false, false};
+
+ String rights = (String) _accessRights.get(user.getName());
+
+ Boolean read = false;
+ Boolean write = false;
+ Boolean admin = false;
+
+ if (rights != null)
+ {
+ read = rights.equals(MBeanInvocationHandlerImpl.READONLY)
+ || rights.equals(MBeanInvocationHandlerImpl.READWRITE);
+ write = rights.equals(MBeanInvocationHandlerImpl.READWRITE);
+ admin = rights.equals(MBeanInvocationHandlerImpl.ADMIN);
+ }
+
+ Object[] itemData = {user.getName(), read, write, admin};
CompositeData messageData = new CompositeDataSupport(_userDataType, COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]), itemData);
userList.put(messageData);
}
}
catch (OpenDataException e)
{
- _logger.warn("Unable to create user list due to :", e);
+ _logger.warn("Unable to create user list due to :" + e);
return null;
}
@@ -183,4 +351,187 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
{
_principalDatabase = database;
}
+
+ /**
+ * setAccessFile
+ *
+ * @param accessFile the file to use for updating.
+ *
+ * @throws java.io.IOException If the file cannot be accessed
+ * @throws org.apache.commons.configuration.ConfigurationException
+ * if checks on the file fail.
+ */
+ public void setAccessFile(String accessFile) throws IOException, ConfigurationException
+ {
+ if (accessFile != null)
+ {
+ _accessFile = new File(accessFile);
+ if (!_accessFile.exists())
+ {
+ throw new ConfigurationException("'" + _accessFile + "' does not exist");
+ }
+
+ if (!_accessFile.canRead())
+ {
+ throw new ConfigurationException("Cannot read '" + _accessFile + "'.");
+ }
+
+ if (!_accessFile.canWrite())
+ {
+ _logger.warn("Unable to write to access rights file '" + _accessFile + "', changes will not be preserved.");
+ }
+
+ loadAccessFile();
+ }
+ else
+ {
+ _logger.warn("Access rights file specified is null. Access rights not changed.");
+ }
+ }
+
+ private void loadAccessFile() throws IOException, ConfigurationException
+ {
+ if(_accessFile == null)
+ {
+ _logger.error("No jmx access rights file has been specified.");
+ return;
+ }
+
+ if(_accessFile.exists())
+ {
+ try
+ {
+ _accessRightsUpdate.lock();
+
+ Properties accessRights = new Properties();
+ FileInputStream inStream = new FileInputStream(_accessFile);
+ try
+ {
+ accessRights.load(inStream);
+ }
+ finally
+ {
+ inStream.close();
+ }
+
+ checkAccessRights(accessRights);
+ setAccessRights(accessRights);
+ }
+ finally
+ {
+ _accessRightsUpdate.unlock();
+ }
+ }
+ else
+ {
+ _logger.error("Specified jmxaccess rights file '" + _accessFile + "' does not exist.");
+ }
+ }
+
+ private void checkAccessRights(Properties accessRights)
+ {
+ Enumeration values = accessRights.propertyNames();
+
+ while (values.hasMoreElements())
+ {
+ String user = (String) values.nextElement();
+
+ if (_principalDatabase.getUser(user) == null)
+ {
+ _logger.warn("Access rights contains user '" + user + "' but there is no authentication data for that user");
+ }
+ }
+ }
+
+ private void saveAccessFile() throws IOException
+ {
+ try
+ {
+ _accessRightsUpdate.lock();
+
+ // Create temporary file
+ Random r = new Random();
+ File tmp;
+ do
+ {
+ tmp = new File(_accessFile.getPath() + r.nextInt() + ".tmp");
+ }
+ while(tmp.exists());
+
+ tmp.deleteOnExit();
+
+ FileOutputStream output = new FileOutputStream(tmp);
+ _accessRights.store(output, "Generated by AMQUserManagementMBean Console : Last edited by user:" + getCurrentJMXUser());
+ output.close();
+
+ // Swap temp file to main rights file.
+ File old = new File(_accessFile.getAbsoluteFile() + ".old");
+ if (old.exists())
+ {
+ old.delete();
+ }
+
+ if(!_accessFile.renameTo(old))
+ {
+ //unable to rename the existing file to the backup name
+ _logger.error("Could not backup the existing management rights file");
+ throw new IOException("Could not backup the existing management rights file");
+ }
+
+ if(!tmp.renameTo(_accessFile))
+ {
+ //failed to rename the new file to the required filename
+
+ if(!old.renameTo(_accessFile))
+ {
+ //unable to return the backup to required filename
+ _logger.error("Could not rename the new management rights file into place, and unable to restore original file");
+ throw new IOException("Could not rename the new management rights file into place, and unable to restore original file");
+ }
+
+ _logger.error("Could not rename the new management rights file into place");
+ throw new IOException("Could not rename the new management rights file into place");
+ }
+ }
+ finally
+ {
+ _accessRightsUpdate.unlock();
+ }
+
+ }
+
+ private String getCurrentJMXUser()
+ {
+ AccessControlContext acc = AccessController.getContext();
+
+ Subject subject = Subject.getSubject(acc);
+ if (subject == null)
+ {
+ return "Unknown user, authentication Subject was null";
+ }
+
+ // Retrieve JMXPrincipal from Subject
+ Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
+ if (principals == null || principals.isEmpty())
+ {
+ return "Unknown user principals were null";
+ }
+
+ Principal principal = principals.iterator().next();
+ return principal.getName();
+ }
+
+ /**
+ * user=read user=write user=readwrite user=admin
+ *
+ * @param accessRights The properties list of access rights to process
+ */
+ private void setAccessRights(Properties accessRights)
+ {
+ _logger.debug("Setting Access Rights:" + accessRights);
+ _accessRights = accessRights;
+
+ // TODO check where this is used
+ // MBeanInvocationHandlerImpl.setAccessRights(_accessRights);
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
index 4c59c25d84..bc771162fd 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
@@ -20,73 +20,17 @@
*/
package org.apache.qpid.server.security.auth.manager;
-import javax.security.auth.Subject;
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 Subject} containing the user's identity and zero or more principals representing
- * groups to which the user belongs.
- * <p>
- * The {@link #initialise()} method is responsible for registering SASL mechanisms required by
- * the manager. The {@link #close()} method must reverse this registration.
- *
- */
-public interface AuthenticationManager extends Closeable, Plugin
+public interface AuthenticationManager extends Closeable
{
- /** The name for the required SASL Server mechanisms */
- public static final String PROVIDER_NAME= "AMQSASLProvider-Server";
-
- /**
- * Initialise the authentication plugin.
- *
- */
- void initialise();
-
- /**
- * Gets the SASL mechanisms known to this manager.
- *
- * @return SASL mechanism names, space separated.
- */
String getMechanisms();
- /**
- * Creates a SASL server for the specified mechanism name for the given
- * fully qualified domain name.
- *
- * @param mechanism mechanism name
- * @param localFQDN domain name
- *
- * @return SASL server
- * @throws SaslException
- */
SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException;
- /**
- * Authenticates a user using SASL negotiation.
- *
- * @param server SASL server
- * @param response SASL response to process
- *
- * @return authentication result
- */
AuthenticationResult authenticate(SaslServer server, byte[] response);
-
- /**
- * Authenticates a user using their username and password.
- *
- * @param username username
- * @param password password
- *
- * @return authentication result
- */
- AuthenticationResult authenticate(String username, String password);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
index 1945c2e15f..2a967f02af 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
@@ -20,65 +20,27 @@
*/
package org.apache.qpid.server.security.auth.manager;
-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;
-
-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 org.apache.log4j.Logger;
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.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
-import org.apache.qpid.server.security.auth.management.AMQUserManagementMBean;
-import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
import org.apache.qpid.server.security.auth.sasl.JCAProvider;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.SaslServerFactory;
+import javax.security.sasl.SaslServer;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.Sasl;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.TreeMap;
+import java.security.Security;
-/**
- * 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);
@@ -87,109 +49,55 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
private String _mechanisms;
/** Maps from the mechanism to the callback handler to use for handling those requests */
- private final Map<String, CallbackHandler> _callbackHandlerMap = new HashMap<String, CallbackHandler>();
+ private Map<String, CallbackHandler> _callbackHandlerMap = new HashMap<String, CallbackHandler>();
/**
* Maps from the mechanism to the properties used to initialise the server. See the method Sasl.createSaslServer for
* details of the use of these properties. This map is populated during initialisation of each provider.
*/
- private final Map<String, Map<String, ?>> _serverCreationProperties = new HashMap<String, Map<String, ?>>();
-
- protected PrincipalDatabase _principalDatabase = null;
+ private Map<String, Map<String, ?>> _serverCreationProperties = new HashMap<String, Map<String, ?>>();
- protected AMQUserManagementMBean _mbean = null;
+ private AuthenticationManager _default = null;
+ /** The name for the required SASL Server mechanisms */
+ public static final String PROVIDER_NAME= "AMQSASLProvider-Server";
- public static final AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager>()
+ public PrincipalDatabaseAuthenticationManager(String name, VirtualHostConfiguration hostConfig) throws Exception
{
- public PrincipalDatabaseAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException
- {
- final PrincipalDatabaseAuthenticationManagerConfiguration configuration = config.getConfiguration(PrincipalDatabaseAuthenticationManagerConfiguration.class.getName());
+ _logger.info("Initialising " + (name == null ? "Default" : "'" + name + "'")
+ + " PrincipalDatabase authentication manager.");
- // 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;
- }
+ // Fixme This should be done per Vhost but allowing global hack isn't right but ...
+ // required as authentication is done before Vhost selection
- final PrincipalDatabaseAuthenticationManager pdam = new PrincipalDatabaseAuthenticationManager();
- pdam.configure(configuration);
- pdam.initialise();
- return pdam;
- }
+ Map<String, Class<? extends SaslServerFactory>> providerMap = new TreeMap<String, Class<? extends SaslServerFactory>>();
- public Class<PrincipalDatabaseAuthenticationManager> getPluginClass()
- {
- return PrincipalDatabaseAuthenticationManager.class;
- }
- public String getPluginName()
+ if (name == null || hostConfig == null)
{
- return PrincipalDatabaseAuthenticationManager.class.getName();
+ initialiseAuthenticationMechanisms(providerMap, ApplicationRegistry.getInstance().getDatabaseManager().getDatabases());
}
- };
-
- public static class PrincipalDatabaseAuthenticationManagerConfiguration extends ConfigurationPlugin {
-
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
+ else
{
- public List<String> getParentPaths()
- {
- return Arrays.asList("security.pd-auth-manager");
- }
+ String databaseName = hostConfig.getAuthenticationDatabase();
- public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException
+ if (databaseName == null)
{
- 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 _configuration.getString("principal-database.class");
- }
-
- public Map<String,String> getPdClassAttributeMap() throws ConfigurationException
- {
- final List<String> argumentNames = _configuration.getList("principal-database.attributes.attribute.name");
- final List<String> argumentValues = _configuration.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++)
+ _default = ApplicationRegistry.getInstance().getAuthenticationManager();
+ return;
+ }
+ else
{
- final String argName = argumentNames.get(i);
- final String argValue = argumentValues.get(i);
+ PrincipalDatabase database = ApplicationRegistry.getInstance().getDatabaseManager().getDatabases().get(databaseName);
- attributes.put(argName, argValue);
- }
+ if (database == null)
+ {
+ throw new ConfigurationException("Requested database:" + databaseName + " was not found");
+ }
- return Collections.unmodifiableMap(attributes);
+ initialiseAuthenticationMechanisms(providerMap, database);
+ }
}
- }
-
- protected PrincipalDatabaseAuthenticationManager()
- {
- }
-
- public void initialise()
- {
- final Map<String, Class<? extends SaslServerFactory>> providerMap = new TreeMap<String, Class<? extends SaslServerFactory>>();
-
- initialiseAuthenticationMechanisms(providerMap, _principalDatabase);
if (providerMap.size() > 0)
{
@@ -202,16 +110,33 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
{
_logger.info("Additional SASL providers successfully registered.");
}
+
}
else
{
_logger.warn("No additional SASL providers registered.");
}
- registerManagement();
}
- private void initialiseAuthenticationMechanisms(Map<String, Class<? extends SaslServerFactory>> providerMap, PrincipalDatabase database)
+
+ private void initialiseAuthenticationMechanisms(Map<String, Class<? extends SaslServerFactory>> providerMap, Map<String, PrincipalDatabase> databases) throws Exception
+ {
+ if (databases.size() > 1)
+ {
+ _logger.warn("More than one principle database provided currently authentication mechanism will override each other.");
+ }
+
+ for (Map.Entry<String, PrincipalDatabase> entry : databases.entrySet())
+ {
+ // fixme As the database now provide the mechanisms they support, they will ...
+ // overwrite each other in the map. There should only be one database per vhost.
+ // But currently we must have authentication before vhost definition.
+ initialiseAuthenticationMechanisms(providerMap, entry.getValue());
+ }
+ }
+
+ private void initialiseAuthenticationMechanisms(Map<String, Class<? extends SaslServerFactory>> providerMap, PrincipalDatabase database) throws Exception
{
if (database == null || database.getMechanisms().size() == 0)
{
@@ -227,6 +152,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
private void initialiseAuthenticationMechanism(String mechanism, AuthenticationProviderInitialiser initialiser,
Map<String, Class<? extends SaslServerFactory>> providerMap)
+ throws Exception
{
if (_mechanisms == null)
{
@@ -247,217 +173,65 @@ 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;
- }
-
- public SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException
- {
- return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, _serverCreationProperties.get(mechanism),
- _callbackHandlerMap.get(mechanism));
- }
-
- /**
- * @see org.apache.qpid.server.security.auth.manager.AuthenticationManager#authenticate(SaslServer, byte[])
- */
- public AuthenticationResult authenticate(SaslServer server, byte[] response)
- {
- try
+ if (_default != null)
{
- // Process response from the client
- byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
-
- if (server.isComplete())
- {
- final Subject subject = new Subject();
- subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID()));
- return new AuthenticationResult(subject);
- }
- else
- {
- return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.CONTINUE);
- }
+ // Use the default AuthenticationManager if present
+ return _default.getMechanisms();
}
- catch (SaslException e)
+ else
{
- return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
+ return _mechanisms;
}
}
- /**
- * @see org.apache.qpid.server.security.auth.manager.AuthenticationManager#authenticate(String, String)
- */
- public AuthenticationResult authenticate(final String username, final String password)
+ public SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException
{
- try
+ if (_default != null)
{
- if (_principalDatabase.verifyPassword(username, password.toCharArray()))
- {
- final Subject subject = new Subject();
- subject.getPrincipals().add(new UsernamePrincipal(username));
- return new AuthenticationResult(subject);
- }
- else
- {
- return new AuthenticationResult(AuthenticationStatus.CONTINUE);
- }
+ // Use the default AuthenticationManager if present
+ return _default.createSaslServer(mechanism, localFQDN);
}
- catch (AccountNotFoundException e)
+ else
{
- return new AuthenticationResult(AuthenticationStatus.CONTINUE);
+ return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, _serverCreationProperties.get(mechanism),
+ _callbackHandlerMap.get(mechanism));
}
- }
-
- public void close()
- {
- _mechanisms = null;
- Security.removeProvider(PROVIDER_NAME);
- unregisterManagement();
}
- private PrincipalDatabase createPrincipalDatabaseImpl(final String pdClazz) throws ConfigurationException
+ public AuthenticationResult authenticate(SaslServer server, byte[] response)
{
- try
- {
- return (PrincipalDatabase) Class.forName(pdClazz).newInstance();
- }
- catch (InstantiationException ie)
- {
- throw new ConfigurationException("Cannot instantiate " + pdClazz, ie);
- }
- catch (IllegalAccessException iae)
+ // Use the default AuthenticationManager if present
+ if (_default != null)
{
- throw new ConfigurationException("Cannot access " + pdClazz, iae);
+ return _default.authenticate(server, response);
}
- 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();)
+ try
{
- 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)
+ // Process response from the client
+ byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
+
+ if (server.isComplete())
{
- throw new ConfigurationException(e.getMessage(), e);
+ return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.SUCCESS);
}
- catch (InvocationTargetException e)
+ else
{
- // 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());
+ return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.CONTINUE);
}
}
- }
-
- 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;
- }
-
- protected void registerManagement()
- {
- try
- {
- _logger.info("Registering UserManagementMBean");
-
- _mbean = new AMQUserManagementMBean();
- _mbean.setPrincipalDatabase(_principalDatabase);
- _mbean.register();
- }
- catch (Exception e)
+ catch (SaslException e)
{
- _logger.warn("User management disabled as unable to create MBean:", e);
- _mbean = null;
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
}
}
- protected void unregisterManagement()
+ public void close()
{
- try
- {
- if (_mbean != null)
- {
- _logger.info("Unregistering UserManagementMBean");
- _mbean.unregister();
- }
- }
- catch (Exception e)
- {
- _logger.warn("Failed to unregister User management MBean:", e);
- }
- finally
- {
- _mbean = null;
- }
+ Security.removeProvider(PROVIDER_NAME);
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
index b7985ad972..0cbbccb3b8 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
@@ -20,13 +20,14 @@
*/
package org.apache.qpid.server.security.auth.rmi;
+import java.util.Collections;
+
import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
+import javax.security.auth.login.AccountNotFoundException;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
public class RMIPasswordAuthenticator implements JMXAuthenticator
{
@@ -38,15 +39,15 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
static final String CREDENTIALS_REQUIRED = "User details are required. " +
"Please ensure you are using an up to date management console to connect.";
- private AuthenticationManager _authenticationManager = null;
+ private PrincipalDatabase _db = null;
public RMIPasswordAuthenticator()
{
}
-
- public void setAuthenticationManager(final AuthenticationManager authenticationManager)
+
+ public void setPrincipalDatabase(PrincipalDatabase pd)
{
- _authenticationManager = authenticationManager;
+ this._db = pd;
}
public Subject authenticate(Object credentials) throws SecurityException
@@ -64,39 +65,50 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
}
}
- // Verify that required number of credentials.
+ // Verify that required number of credential's.
final String[] userCredentials = (String[]) credentials;
if (userCredentials.length != 2)
{
throw new SecurityException(SHOULD_HAVE_2_ELEMENTS);
}
- final String username = (String) userCredentials[0];
- final String password = (String) userCredentials[1];
+ String username = (String) userCredentials[0];
+ String password = (String) userCredentials[1];
- // Verify that all required credentials are actually present.
+ // Verify that all required credential's 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)
+ // Verify that a PD has been set.
+ if (_db == null)
{
throw new SecurityException(UNABLE_TO_LOOKUP);
}
- final AuthenticationResult result = _authenticationManager.authenticate(username, password);
+
+ boolean authenticated = false;
- if (AuthenticationStatus.ERROR.equals(result.getStatus()))
+ // Perform authentication
+ try
{
- throw new SecurityException("Authentication manager failed", result.getCause());
+ if (_db.verifyPassword(username, password.toCharArray()))
+ {
+ authenticated = true;
+ }
+ }
+ catch (AccountNotFoundException e)
+ {
+ throw new SecurityException(INVALID_CREDENTIALS); // XXX
}
- else if (AuthenticationStatus.SUCCESS.equals(result.getStatus()))
+
+ if (authenticated)
{
- final Subject subject = result.getSubject();
- subject.getPrincipals().add(new JMXPrincipal(username));
- subject.setReadOnly();
- return subject;
+ //credential's check out, return the appropriate JAAS Subject
+ return new Subject(true,
+ Collections.singleton(new JMXPrincipal(username)),
+ Collections.EMPTY_SET,
+ Collections.EMPTY_SET);
}
else
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java
index bc5d8a4f2b..89e545d6f5 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java
@@ -25,6 +25,9 @@ import java.util.Map;
import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.SaslServerFactory;
+import org.apache.commons.configuration.Configuration;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+
public interface AuthenticationProviderInitialiser
{
/**
@@ -34,6 +37,24 @@ public interface AuthenticationProviderInitialiser
String getMechanismName();
/**
+ * Initialise the authentication provider.
+ * @param baseConfigPath the path in the config file that points to any config options for this provider. Each
+ * provider can have its own set of configuration options
+ * @param configuration the Apache Commons Configuration instance used to configure this provider
+ * @param principalDatabases the set of principal databases that are available
+ * @throws Exception needs refined Exception is too broad.
+ */
+ void initialise(String baseConfigPath, Configuration configuration,
+ Map<String, PrincipalDatabase> principalDatabases) throws Exception;
+
+ /**
+ * Initialise the authentication provider.
+ * @param db The principal database to initialise with
+ */
+ void initialise(PrincipalDatabase db);
+
+
+ /**
* @return the callback handler that should be used to process authentication requests for this mechanism. This will
* be called after initialise and will be stored by the authentication manager. The callback handler <b>must</b> be
* fully threadsafe.
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java
deleted file mode 100644
index 30a503c769..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.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.security.auth.sasl;
-
-import java.security.Principal;
-import java.security.acl.Group;
-import java.util.Enumeration;
-
-/**
- * Immutable representation of a user group. In Qpid, groups do <b>not</b> know
- * about their membership, and therefore the {@link #addMember(Principal)}
- * methods etc throw {@link UnsupportedOperationException}.
- *
- */
-public class GroupPrincipal implements Group
-{
- /** Name of the group */
- private final String _groupName;
-
- public GroupPrincipal(final String groupName)
- {
- _groupName = groupName;
- }
-
- public String getName()
- {
- return _groupName;
- }
-
- public boolean addMember(Principal user)
- {
- throw new UnsupportedOperationException("Not supported");
- }
-
- public boolean removeMember(Principal user)
- {
- throw new UnsupportedOperationException("Not supported");
- }
-
- public boolean isMember(Principal member)
- {
- throw new UnsupportedOperationException("Not supported");
- }
-
- public Enumeration<? extends Principal> members()
- {
- throw new UnsupportedOperationException("Not supported");
- }
-
- /**
- * @see java.lang.Object#hashCode()
- */
- public int hashCode()
- {
- final int prime = 37;
- return prime * _groupName.hashCode();
- }
-
- /**
- * @see java.lang.Object#equals(java.lang.Object)
- */
- public boolean equals(Object obj)
- {
- if (this == obj)
- {
- return true;
- }
- else
- {
- if (obj instanceof GroupPrincipal)
- {
- GroupPrincipal other = (GroupPrincipal) obj;
- return _groupName.equals(other._groupName);
- }
- else
- {
- return false;
- }
- }
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
index b4ee13fe6b..d7c8383690 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
@@ -21,21 +21,14 @@
package org.apache.qpid.server.security.auth.sasl;
import java.security.Principal;
-import java.util.Set;
-
-import javax.security.auth.Subject;
/** A principal that is just a wrapper for a simple username. */
public class UsernamePrincipal implements Principal
{
- private final String _name;
+ private String _name;
public UsernamePrincipal(String name)
{
- if (name == null)
- {
- throw new IllegalArgumentException("name cannot be null");
- }
_name = name;
}
@@ -48,53 +41,4 @@ public class UsernamePrincipal implements Principal
{
return _name;
}
-
- /**
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode()
- {
- final int prime = 31;
- return prime * _name.hashCode();
- }
-
- /**
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object obj)
- {
- if (this == obj)
- {
- return true;
- }
- else
- {
- if (obj instanceof UsernamePrincipal)
- {
- UsernamePrincipal other = (UsernamePrincipal) obj;
- return _name.equals(other._name);
- }
- else
- {
- return false;
- }
- }
- }
-
- 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/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java
index 17d123eb0d..67d20136bf 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java
@@ -45,10 +45,9 @@ public class AmqPlainSaslServerFactory implements SaslServerFactory
public String[] getMechanismNames(Map props)
{
- if (props != null &&
- (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
- props.containsKey(Sasl.POLICY_NODICTIONARY) ||
- props.containsKey(Sasl.POLICY_NOACTIVE)))
+ if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
+ props.containsKey(Sasl.POLICY_NODICTIONARY) ||
+ props.containsKey(Sasl.POLICY_NOACTIVE))
{
// returned array must be non null according to interface documentation
return new String[0];
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java
index 8a5ff7df2d..6032255870 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java
@@ -47,11 +47,10 @@ public class AnonymousSaslServerFactory implements SaslServerFactory
public String[] getMechanismNames(Map props)
{
- if (props != null &&
- (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
- props.containsKey(Sasl.POLICY_NODICTIONARY) ||
- props.containsKey(Sasl.POLICY_NOACTIVE) ||
- props.containsKey(Sasl.POLICY_NOANONYMOUS)))
+ if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
+ props.containsKey(Sasl.POLICY_NODICTIONARY) ||
+ props.containsKey(Sasl.POLICY_NOACTIVE) ||
+ props.containsKey(Sasl.POLICY_NOANONYMOUS))
{
// returned array must be non null according to interface documentation
return new String[0];
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
index 139818735f..8020d97364 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
@@ -70,7 +70,7 @@ public class CRAMMD5HexInitialiser extends UsernamePasswordInitialiser
for (char c : password)
{
//toHexString does not prepend 0 so we have to
- if (((byte) c > -1) && (byte) c < 0x10 )
+ if (((byte) c > -1) && (byte) c < 10)
{
sb.append(0);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
index 3144bfbce6..f0dd9eeb6d 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
@@ -45,10 +45,9 @@ public class PlainSaslServerFactory implements SaslServerFactory
public String[] getMechanismNames(Map props)
{
- if (props != null &&
- (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
- props.containsKey(Sasl.POLICY_NODICTIONARY) ||
- props.containsKey(Sasl.POLICY_NOACTIVE)))
+ if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
+ props.containsKey(Sasl.POLICY_NODICTIONARY) ||
+ props.containsKey(Sasl.POLICY_NOACTIVE))
{
// returned array must be non null according to interface documentation
return new String[0];
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java
index 33aebffcfb..6cc5e7b019 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java
@@ -259,7 +259,7 @@ public class AMQStateManager implements AMQMethodListener
public AMQProtocolSession getProtocolSession()
{
- SecurityManager.setThreadSubject(_protocolSession.getAuthorizedSubject());
+ SecurityManager.setThreadPrincipal(_protocolSession.getPrincipal());
return _protocolSession;
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java
deleted file mode 100644
index b732121180..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.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.stats;
-
-import java.util.Date;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class collects statistics and counts the total, rate per second and
- * peak rate per second values for the events that are registered with it.
- */
-public class StatisticsCounter
-{
- private static final Logger _log = LoggerFactory.getLogger(StatisticsCounter.class);
-
- public static final long DEFAULT_SAMPLE_PERIOD = Long.getLong("qpid.statistics.samplePeriod", 2000L); // 2s
- public static final boolean DISABLE_STATISTICS = Boolean.getBoolean("qpid.statistics.disable");
-
- private static final String COUNTER = "counter";
- private static final AtomicLong _counterIds = new AtomicLong(0L);
-
- private long _peak = 0L;
- private long _total = 0L;
- private long _temp = 0L;
- private long _last = 0L;
- private long _rate = 0L;
-
- private long _start;
-
- private final long _period;
- private final String _name;
-
- public StatisticsCounter()
- {
- this(COUNTER);
- }
-
- public StatisticsCounter(String name)
- {
- this(name, DEFAULT_SAMPLE_PERIOD);
- }
-
- public StatisticsCounter(String name, long period)
- {
- _period = period;
- _name = name + "-" + + _counterIds.incrementAndGet();
- reset();
- }
-
- public void registerEvent()
- {
- registerEvent(1L);
- }
-
- public void registerEvent(long value)
- {
- registerEvent(value, System.currentTimeMillis());
- }
-
- public void registerEvent(long value, long timestamp)
- {
- if (DISABLE_STATISTICS)
- {
- return;
- }
-
- long thisSample = (timestamp / _period);
- synchronized (this)
- {
- if (thisSample > _last)
- {
- _last = thisSample;
- _rate = _temp;
- _temp = 0L;
- if (_rate > _peak)
- {
- _peak = _rate;
- }
- }
-
- _total += value;
- _temp += value;
- }
- }
-
- /**
- * Update the current rate and peak - may reset rate to zero if a new
- * sample period has started.
- */
- private void update()
- {
- registerEvent(0L, System.currentTimeMillis());
- }
-
- /**
- * Reset
- */
- public void reset()
- {
- _log.info("Resetting statistics for counter: " + _name);
- _peak = 0L;
- _rate = 0L;
- _total = 0L;
- _start = System.currentTimeMillis();
- _last = _start / _period;
- }
-
- public double getPeak()
- {
- update();
- return (double) _peak / ((double) _period / 1000.0d);
- }
-
- public double getRate()
- {
- update();
- return (double) _rate / ((double) _period / 1000.0d);
- }
-
- public long getTotal()
- {
- return _total;
- }
-
- public long getStart()
- {
- return _start;
- }
-
- public Date getStartTime()
- {
- return new Date(_start);
- }
-
- public String getName()
- {
- return _name;
- }
-
- public long getPeriod()
- {
- return _period;
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java
deleted file mode 100644
index 36fec4025a..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.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.stats;
-
-/**
- * This interface is to be implemented by any broker business object that
- * wishes to gather statistics about messages delivered through it.
- *
- * These statistics are exposed using a separate JMX Mbean interface, which
- * calls these methods to retrieve the underlying {@link StatisticsCounter}s
- * and return their attributes. This interface gives a standard way for
- * parts of the broker to set up and configure statistics generation.
- * <p>
- * When creating these objects, there should be a parent/child relationship
- * between them, such that the lowest level gatherer can record staticics if
- * enabled, and pass on the notification to the parent object to allow higher
- * level aggregation. When resetting statistics, this works in the opposite
- * direction, with higher level gatherers also resetting all of their children.
- */
-public interface StatisticsGatherer
-{
- /**
- * Initialise the statistics gathering for this object.
- *
- * This method is responsible for creating any {@link StatisticsCounter}
- * objects and for determining whether statistics generation should be
- * enabled, by checking broker and system configuration.
- *
- * @see StatisticsCounter#DISABLE_STATISTICS
- */
- void initialiseStatistics();
-
- /**
- * This method is responsible for registering the receipt of a message
- * with the counters, and also for passing this notification to any parent
- * {@link StatisticsGatherer}s. If statistics generation is not enabled,
- * then this method should simple delegate to the parent gatherer.
- *
- * @param messageSize the size in bytes of the delivered message
- * @param timestamp the time the message was delivered
- */
- void registerMessageReceived(long messageSize, long timestamp);
-
- /**
- * This method is responsible for registering the delivery of a message
- * with the counters. Message delivery is recorded by the counter using
- * the current system time, as opposed to the message timestamp.
- *
- * @param messageSize the size in bytes of the delivered message
- * @see #registerMessageReceived(long, long)
- */
- void registerMessageDelivered(long messageSize);
-
- /**
- * Gives access to the {@link StatisticsCounter} that is used to count
- * delivered message statistics.
- *
- * @return the {@link StatisticsCounter} that counts delivered messages
- */
- StatisticsCounter getMessageDeliveryStatistics();
-
- /**
- * Gives access to the {@link StatisticsCounter} that is used to count
- * received message statistics.
- *
- * @return the {@link StatisticsCounter} that counts received messages
- */
- StatisticsCounter getMessageReceiptStatistics();
-
- /**
- * Gives access to the {@link StatisticsCounter} that is used to count
- * delivered message size statistics.
- *
- * @return the {@link StatisticsCounter} that counts delivered bytes
- */
- StatisticsCounter getDataDeliveryStatistics();
-
- /**
- * Gives access to the {@link StatisticsCounter} that is used to count
- * received message size statistics.
- *
- * @return the {@link StatisticsCounter} that counts received bytes
- */
- StatisticsCounter getDataReceiptStatistics();
-
- /**
- * Reset the counters for this, and any child {@link StatisticsGatherer}s.
- */
- void resetStatistics();
-
- /**
- * Check if this object has statistics generation enabled.
- *
- * @return true if statistics generation is enabled
- */
- boolean isStatisticsEnabled();
-
- /**
- * Enable or disable statistics generation for this object.
- */
- void setStatisticsEnabled(boolean enabled);
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionList.java
index 3e6299cb8a..9ea81660c6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionList.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionList.java
@@ -20,108 +20,121 @@
*/
package org.apache.qpid.server.subscription;
+import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.subscription.Subscription;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import java.nio.ByteBuffer;
public class SubscriptionList
{
+
private final SubscriptionNode _head = new SubscriptionNode();
- private final AtomicReference<SubscriptionNode> _tail = new AtomicReference<SubscriptionNode>(_head);
- private final AtomicReference<SubscriptionNode> _subNodeMarker = new AtomicReference<SubscriptionNode>(_head);
- private final AtomicInteger _size = new AtomicInteger();
+ private AtomicReference<SubscriptionNode> _tail = new AtomicReference<SubscriptionNode>(_head);
+ private AtomicInteger _size = new AtomicInteger();
+
- public static final class SubscriptionNode
+ public final class SubscriptionNode
{
private final AtomicBoolean _deleted = new AtomicBoolean();
private final AtomicReference<SubscriptionNode> _next = new AtomicReference<SubscriptionNode>();
private final Subscription _sub;
+
public SubscriptionNode()
{
- //used for sentinel head and dummy node construction
+
_sub = null;
_deleted.set(true);
}
public SubscriptionNode(final Subscription sub)
{
- //used for regular node construction
_sub = sub;
}
- /**
- * Retrieves the first non-deleted node following the current node.
- * Any deleted non-tail nodes encountered during the search are unlinked.
- *
- * @return the next non-deleted node, or null if none was found.
- */
- public SubscriptionNode findNext()
+
+ public SubscriptionNode getNext()
{
+
SubscriptionNode next = nextNode();
while(next != null && next.isDeleted())
{
+
final SubscriptionNode newNext = next.nextNode();
if(newNext != null)
{
- //try to move our _next reference forward to the 'newNext'
- //node to unlink the deleted node
_next.compareAndSet(next, newNext);
next = nextNode();
}
else
{
- //'newNext' is null, meaning 'next' is the current tail. Can't unlink
- //the tail node for thread safety reasons, just use the null.
next = null;
}
- }
+ }
return next;
}
- /**
- * Gets the immediately next referenced node in the structure.
- *
- * @return the immediately next node in the structure, or null if at the tail.
- */
- protected SubscriptionNode nextNode()
+ private SubscriptionNode nextNode()
{
return _next.get();
}
- /**
- * Used to initialise the 'next' reference. Will only succeed if the reference was not previously set.
- *
- * @param node the SubscriptionNode to set as 'next'
- * @return whether the operation succeeded
- */
- private boolean setNext(final SubscriptionNode node)
- {
- return _next.compareAndSet(null, node);
- }
-
public boolean isDeleted()
{
return _deleted.get();
}
+
public boolean delete()
{
- return _deleted.compareAndSet(false,true);
+ if(_deleted.compareAndSet(false,true))
+ {
+ _size.decrementAndGet();
+ advanceHead();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
+
public Subscription getSubscription()
{
return _sub;
}
}
- private void insert(final SubscriptionNode node, final boolean count)
+
+ public SubscriptionList(AMQQueue queue)
+ {
+ }
+
+ private void advanceHead()
+ {
+ SubscriptionNode head = _head.nextNode();
+ while(head._next.get() != null && head.isDeleted())
+ {
+
+ final SubscriptionNode newhead = head.nextNode();
+ if(newhead != null)
+ {
+ _head._next.compareAndSet(head, newhead);
+ }
+ head = _head.nextNode();
+ }
+ }
+
+
+ public SubscriptionNode add(Subscription sub)
{
+ SubscriptionNode node = new SubscriptionNode(sub);
for (;;)
{
SubscriptionNode tail = _tail.get();
@@ -130,14 +143,11 @@ public class SubscriptionList
{
if (next == null)
{
- if (tail.setNext(node))
+ if (tail._next.compareAndSet(null, node))
{
_tail.compareAndSet(tail, node);
- if(count)
- {
- _size.incrementAndGet();
- }
- return;
+ _size.incrementAndGet();
+ return node;
}
}
else
@@ -146,101 +156,27 @@ public class SubscriptionList
}
}
}
- }
- public void add(final Subscription sub)
- {
- SubscriptionNode node = new SubscriptionNode(sub);
- insert(node, true);
}
- public boolean remove(final Subscription sub)
+ public boolean remove(Subscription sub)
{
- SubscriptionNode prevNode = _head;
- SubscriptionNode node = _head.nextNode();
-
+ SubscriptionNode node = _head.getNext();
while(node != null)
{
- if(sub.equals(node.getSubscription()) && node.delete())
+ if(sub.equals(node._sub) && node.delete())
{
- _size.decrementAndGet();
-
- SubscriptionNode tail = _tail.get();
- if(node == tail)
- {
- //we cant remove the last node from the structure for
- //correctness reasons, however we have just 'deleted'
- //the tail. Inserting an empty dummy node after it will
- //let us scavenge the node containing the Subscription.
- insert(new SubscriptionNode(), false);
- }
-
- //advance the next node reference in the 'prevNode' to scavange
- //the newly 'deleted' node for the Subscription.
- prevNode.findNext();
-
- nodeMarkerCleanup(node);
-
return true;
}
-
- prevNode = node;
- node = node.findNext();
+ node = node.getNext();
}
-
return false;
}
- private void nodeMarkerCleanup(final SubscriptionNode node)
- {
- SubscriptionNode markedNode = _subNodeMarker.get();
- if(node == markedNode)
- {
- //if the marked node is the one we are removing, then
- //replace it with a dummy pointing at the next node.
- //this is OK as the marked node is only used to index
- //into the list and find the next node to use.
- //Because we inserted a dummy if node was the
- //tail, markedNode.nextNode() can never be null.
- SubscriptionNode dummy = new SubscriptionNode();
- dummy.setNext(markedNode.nextNode());
-
- //if the CAS fails the marked node has changed, thus
- //we don't care about the dummy and just forget it
- _subNodeMarker.compareAndSet(markedNode, dummy);
- }
- else if(markedNode != null)
- {
- //if the marked node was already deleted then it could
- //hold subsequently removed nodes after it in the list
- //in memory. Scavenge it to ensure their actual removal.
- if(markedNode != _head && markedNode.isDeleted())
- {
- markedNode.findNext();
- }
- }
- }
-
- public boolean updateMarkedNode(final SubscriptionNode expected, final SubscriptionNode nextNode)
- {
- return _subNodeMarker.compareAndSet(expected, nextNode);
- }
-
- /**
- * Get the current marked SubscriptionNode. This should only be used only to index into the list and find the next node
- * after the mark, since if the previously marked node was subsequently deleted the item returned may be a dummy node
- * with reference to the next node.
- *
- * @return the previously marked node (or a dummy if it was subsequently deleted)
- */
- public SubscriptionNode getMarkedNode()
- {
- return _subNodeMarker.get();
- }
-
public static class SubscriptionNodeIterator
{
+
private SubscriptionNode _lastNode;
SubscriptionNodeIterator(SubscriptionNode startNode)
@@ -248,25 +184,49 @@ public class SubscriptionList
_lastNode = startNode;
}
+
+ public boolean atTail()
+ {
+ return _lastNode.nextNode() == null;
+ }
+
public SubscriptionNode getNode()
{
+
return _lastNode;
+
}
public boolean advance()
{
- SubscriptionNode nextNode = _lastNode.findNext();
- _lastNode = nextNode;
- return _lastNode != null;
+ if(!atTail())
+ {
+ SubscriptionNode nextNode = _lastNode.nextNode();
+ while(nextNode.isDeleted() && nextNode.nextNode() != null)
+ {
+ nextNode = nextNode.nextNode();
+ }
+ _lastNode = nextNode;
+ return true;
+
+ }
+ else
+ {
+ return false;
+ }
+
}
+
}
+
public SubscriptionNodeIterator iterator()
{
return new SubscriptionNodeIterator(_head);
}
+
public SubscriptionNode getHead()
{
return _head;
@@ -276,6 +236,9 @@ public class SubscriptionList
{
return _size.get();
}
+
+
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
index 68e47fd86a..b36ac84cdd 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
@@ -97,6 +97,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
private FlowCreditManager_0_10 _creditManager;
+
private StateListener _stateListener = new StateListener()
{
@@ -441,7 +442,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
Struct[] headers = new Struct[] { deliveryProps, messageProps };
BasicContentHeaderProperties properties =
- (BasicContentHeaderProperties) message_0_8.getContentHeaderBody().getProperties();
+ (BasicContentHeaderProperties) message_0_8.getContentHeaderBody().properties;
final AMQShortString exchange = message_0_8.getMessagePublishInfo().getExchange();
if(exchange != null)
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java
index abbc5a3805..3ca22b60c8 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java
@@ -20,21 +20,21 @@
*/
package org.apache.qpid.server.transport;
-import org.apache.qpid.transport.network.NetworkTransport;
+import org.apache.qpid.transport.NetworkDriver;
public class QpidAcceptor
{
- NetworkTransport _transport;
+ NetworkDriver _driver;
String _protocol;
- public QpidAcceptor(NetworkTransport transport, String protocol)
+ public QpidAcceptor(NetworkDriver driver, String protocol)
{
- _transport = transport;
+ _driver = driver;
_protocol = protocol;
}
- public NetworkTransport getNetworkTransport()
+ public NetworkDriver getNetworkDriver()
{
- return _transport;
+ return _driver;
}
public String toString()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
index 9b3673e8b7..d2addfde0c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
@@ -22,14 +22,8 @@ package org.apache.qpid.server.transport;
import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.*;
-import java.security.Principal;
import java.text.MessageFormat;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-import javax.security.auth.Subject;
import org.apache.qpid.AMQException;
import org.apache.qpid.protocol.AMQConstant;
@@ -41,40 +35,25 @@ import org.apache.qpid.server.logging.actors.GenericActor;
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.sasl.UsernamePrincipal;
-import org.apache.qpid.server.stats.StatisticsCounter;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.transport.Connection;
-import org.apache.qpid.transport.ConnectionCloseCode;
import org.apache.qpid.transport.ExecutionErrorCode;
import org.apache.qpid.transport.ExecutionException;
import org.apache.qpid.transport.Method;
import org.apache.qpid.transport.ProtocolEvent;
-import org.apache.qpid.transport.Session;
-public class ServerConnection extends Connection implements AMQConnectionModel, LogSubject, AuthorizationHolder
+public class ServerConnection extends Connection implements AMQConnectionModel, LogSubject
{
private ConnectionConfig _config;
private Runnable _onOpenTask;
private AtomicBoolean _logClosed = new AtomicBoolean(false);
private LogActor _actor = GenericActor.getInstance(this);
- private Subject _authorizedSubject = null;
- private Principal _authorizedPrincipal = null;
- private boolean _statisticsEnabled = false;
- private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
-
public ServerConnection()
{
}
- public UUID getId()
- {
- return _config.getId();
- }
-
@Override
protected void invoke(Method method)
{
@@ -93,18 +72,8 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
_onOpenTask.run();
}
_actor.message(ConnectionMessages.OPEN(getClientId(), "0-10", true, true));
-
- getVirtualHost().getConnectionRegistry().registerConnection(this);
- }
-
- if (state == State.CLOSE_RCVD || state == State.CLOSED || state == State.CLOSING)
- {
- if(_virtualHost != null)
- {
- _virtualHost.getConnectionRegistry().deregisterConnection(this);
- }
}
-
+
if (state == State.CLOSED)
{
logClosed();
@@ -141,8 +110,6 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
public void setVirtualHost(VirtualHost virtualHost)
{
_virtualHost = virtualHost;
-
- initialiseStatistics();
}
public void setConnectionConfig(final ConnectionConfig config)
@@ -178,11 +145,6 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
((ServerSession)session).close();
}
-
- public LogSubject getLogSubject()
- {
- return (LogSubject) this;
- }
@Override
public void received(ProtocolEvent event)
@@ -217,9 +179,9 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
public String toLogString()
{
boolean hasVirtualHost = (null != this.getVirtualHost());
- boolean hasClientId = (null != getClientId());
+ boolean hasPrincipal = (null != getAuthorizationID());
- if (hasClientId && hasVirtualHost)
+ if (hasPrincipal && hasVirtualHost)
{
return "[" +
MessageFormat.format(CONNECTION_FORMAT,
@@ -229,7 +191,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
getVirtualHost().getName())
+ "] ";
}
- else if (hasClientId)
+ else if (hasPrincipal)
{
return "[" +
MessageFormat.format(USER_FORMAT,
@@ -253,130 +215,4 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
{
return _actor;
}
-
- public void close(AMQConstant cause, String message) throws AMQException
- {
- ConnectionCloseCode replyCode = ConnectionCloseCode.NORMAL;
- try
- {
- replyCode = ConnectionCloseCode.get(cause.getCode());
- }
- catch (IllegalArgumentException iae)
- {
- // Ignore
- }
- close(replyCode, message);
- }
-
- public List<AMQSessionModel> getSessionModels()
- {
- List<AMQSessionModel> sessions = new ArrayList<AMQSessionModel>();
- for (Session ssn : getChannels())
- {
- sessions.add((AMQSessionModel) ssn);
- }
- return sessions;
- }
-
- public void registerMessageDelivered(long messageSize)
- {
- if (isStatisticsEnabled())
- {
- _messagesDelivered.registerEvent(1L);
- _dataDelivered.registerEvent(messageSize);
- }
- _virtualHost.registerMessageDelivered(messageSize);
- }
-
- public void registerMessageReceived(long messageSize, long timestamp)
- {
- if (isStatisticsEnabled())
- {
- _messagesReceived.registerEvent(1L, timestamp);
- _dataReceived.registerEvent(messageSize, timestamp);
- }
- _virtualHost.registerMessageReceived(messageSize, timestamp);
- }
-
- public StatisticsCounter getMessageReceiptStatistics()
- {
- return _messagesReceived;
- }
-
- public StatisticsCounter getDataReceiptStatistics()
- {
- return _dataReceived;
- }
-
- public StatisticsCounter getMessageDeliveryStatistics()
- {
- return _messagesDelivered;
- }
-
- public StatisticsCounter getDataDeliveryStatistics()
- {
- return _dataDelivered;
- }
-
- public void resetStatistics()
- {
- _messagesDelivered.reset();
- _dataDelivered.reset();
- _messagesReceived.reset();
- _dataReceived.reset();
- }
-
- public void initialiseStatistics()
- {
- setStatisticsEnabled(!StatisticsCounter.DISABLE_STATISTICS &&
- _virtualHost.getApplicationRegistry().getConfiguration().isStatisticsGenerationConnectionsEnabled());
-
- _messagesDelivered = new StatisticsCounter("messages-delivered-" + getConnectionId());
- _dataDelivered = new StatisticsCounter("data-delivered-" + getConnectionId());
- _messagesReceived = new StatisticsCounter("messages-received-" + getConnectionId());
- _dataReceived = new StatisticsCounter("data-received-" + getConnectionId());
- }
-
- public boolean isStatisticsEnabled()
- {
- return _statisticsEnabled;
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
- _statisticsEnabled = enabled;
- }
-
- /**
- * @return authorizedSubject
- */
- public Subject getAuthorizedSubject()
- {
- return _authorizedSubject;
- }
-
- /**
- * Sets the authorized subject. It also extracts the UsernamePrincipal from the subject
- * and caches it for optimisation purposes.
- *
- * @param authorizedSubject
- */
- public void setAuthorizedSubject(final Subject authorizedSubject)
- {
- if (authorizedSubject == null)
- {
- _authorizedSubject = null;
- _authorizedPrincipal = null;
- }
- else
- {
- _authorizedSubject = authorizedSubject;
- _authorizedPrincipal = UsernamePrincipal.getUsernamePrincipalFromSubject(_authorizedSubject);
- }
- }
-
- public Principal getAuthorizedPrincipal()
- {
- return _authorizedPrincipal;
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
index 27e199291d..2b9e92f685 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
@@ -20,30 +20,26 @@
*/
package org.apache.qpid.server.transport;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
+import org.apache.qpid.transport.*;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.GenericActor;
+import org.apache.qpid.common.ClientProperties;
import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.security.SecurityManager;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.*;
+
+import javax.security.sasl.SaslServer;
+import javax.security.sasl.SaslException;
+import java.util.*;
public class ServerConnectionDelegate extends ServerDelegate
{
private String _localFQDN;
private final IApplicationRegistry _appRegistry;
+
public ServerConnectionDelegate(IApplicationRegistry appRegistry, String localFQDN)
{
this(new HashMap<String,Object>(Collections.singletonMap("qpid.federation_tag",appRegistry.getBroker().getFederationTag())), Collections.singletonList((Object)"en_US"), appRegistry, localFQDN);
@@ -72,6 +68,7 @@ public class ServerConnectionDelegate extends ServerDelegate
return list;
}
+ @Override
public ServerSession getSession(Connection conn, SessionAttach atc)
{
SessionDelegate serverSessionDelegate = new ServerSessionDelegate(_appRegistry);
@@ -81,33 +78,14 @@ public class ServerConnectionDelegate extends ServerDelegate
return ssn;
}
+ @Override
protected SaslServer createSaslServer(String mechanism) throws SaslException
{
return _appRegistry.getAuthenticationManager().createSaslServer(mechanism, _localFQDN);
}
- protected void secure(final SaslServer ss, final Connection conn, final byte[] response)
- {
- final AuthenticationResult authResult = _appRegistry.getAuthenticationManager().authenticate(ss, response);
- final ServerConnection sconn = (ServerConnection) conn;
-
-
- if (AuthenticationStatus.SUCCESS.equals(authResult.getStatus()))
- {
- tuneAuthorizedConnection(sconn);
- sconn.setAuthorizedSubject(authResult.getSubject());
- }
- else if (AuthenticationStatus.CONTINUE.equals(authResult.getStatus()))
- {
- connectionAuthContinue(sconn, authResult.getChallenge());
- }
- else
- {
- connectionAuthFailed(sconn, authResult.getCause());
- }
- }
-
+ @Override
public void connectionClose(Connection conn, ConnectionClose close)
{
try
@@ -121,9 +99,10 @@ public class ServerConnectionDelegate extends ServerDelegate
}
+ @Override
public void connectionOpen(Connection conn, ConnectionOpen open)
{
- final ServerConnection sconn = (ServerConnection) conn;
+ ServerConnection sconn = (ServerConnection) conn;
VirtualHost vhost;
String vhostName;
@@ -137,7 +116,7 @@ public class ServerConnectionDelegate extends ServerDelegate
}
vhost = _appRegistry.getVirtualHostRegistry().getVirtualHost(vhostName);
- SecurityManager.setThreadSubject(sconn.getAuthorizedSubject());
+ SecurityManager.setThreadPrincipal(conn.getAuthorizationID());
if(vhost != null)
{
@@ -159,7 +138,6 @@ public class ServerConnectionDelegate extends ServerDelegate
sconn.invoke(new ConnectionClose(ConnectionCloseCode.INVALID_PATH, "Unknown virtualhost '"+vhostName+"'"));
sconn.setState(Connection.State.CLOSING);
}
-
}
@Override
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
index e9168f71fb..540ad3fffd 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
@@ -23,25 +23,9 @@ package org.apache.qpid.server.transport;
import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_FORMAT;
import static org.apache.qpid.util.Serial.gt;
-import java.lang.ref.WeakReference;
-import java.security.Principal;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentSkipListMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.security.auth.Subject;
+import com.sun.security.auth.UserPrincipal;
import org.apache.qpid.AMQException;
-import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.server.configuration.ConfigStore;
import org.apache.qpid.server.configuration.ConfiguredObject;
@@ -54,18 +38,18 @@ import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.GenericActor;
import org.apache.qpid.server.logging.messages.ChannelMessages;
import org.apache.qpid.server.message.ServerMessage;
-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.BaseQueue;
import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.security.AuthorizationHolder;
+import org.apache.qpid.server.security.PrincipalHolder;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.subscription.Subscription_0_10;
import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.server.txn.LocalTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.protocol.AMQSessionModel;
+import org.apache.qpid.server.protocol.AMQConnectionModel;
import org.apache.qpid.transport.Binary;
import org.apache.qpid.transport.Connection;
import org.apache.qpid.transport.MessageTransfer;
@@ -74,13 +58,24 @@ import org.apache.qpid.transport.Range;
import org.apache.qpid.transport.RangeSet;
import org.apache.qpid.transport.Session;
import org.apache.qpid.transport.SessionDelegate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-public class ServerSession extends Session implements AuthorizationHolder, SessionConfig, AMQSessionModel, LogSubject
+import java.lang.ref.WeakReference;
+import java.security.Principal;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class ServerSession extends Session implements PrincipalHolder, SessionConfig, AMQSessionModel, LogSubject
{
- private static final Logger _logger = LoggerFactory.getLogger(ServerSession.class);
-
private static final String NULL_DESTINTATION = UUID.randomUUID().toString();
private final UUID _id;
@@ -116,7 +111,8 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
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 Principal _principal;
private Map<String, Subscription_0_10> _subscriptions = new ConcurrentHashMap<String, Subscription_0_10>();
@@ -144,8 +140,8 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
super(connection, delegate, name, expiry);
_connectionConfig = connConfig;
_transaction = new AutoCommitTransaction(this.getMessageStore());
-
- _reference = new WeakReference<Session>(this);
+ _principal = new UserPrincipal(connection.getAuthorizationID());
+ _reference = new WeakReference(this);
_id = getConfigStore().createId();
getConfigStore().addConfiguredObject(this);
}
@@ -164,8 +160,8 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
public void enqueue(final ServerMessage message, final ArrayList<? extends BaseQueue> queues)
{
- getConnectionModel().registerMessageReceived(message.getSize(), message.getArrivalTime());
- _transaction.enqueue(queues,message, new ServerTransaction.Action()
+
+ _transaction.enqueue(queues,message, new ServerTransaction.Action()
{
BaseQueue[] _queues = queues.toArray(new BaseQueue[queues.size()]);
@@ -193,7 +189,6 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
});
incrementOutstandingTxnsIfNecessary();
- updateTransactionalActivity();
}
@@ -201,7 +196,6 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
Runnable postIdSettingAction)
{
invoke(xfr, postIdSettingAction);
- getConnectionModel().registerMessageDelivered(xfr.getBodySize());
}
public void onMessageDispositionChange(MessageTransfer xfr, MessageDispositionChangeListener acceptListener)
@@ -383,7 +377,6 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
entry.release();
}
});
- updateTransactionalActivity();
}
public Collection<Subscription_0_10> getSubscriptions()
@@ -417,7 +410,7 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
catch (AMQException e)
{
// TODO
- _logger.error("Failed to unregister subscription", e);
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
finally
{
@@ -432,11 +425,6 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
// theory
return !(_transaction instanceof AutoCommitTransaction);
}
-
- public boolean inTransaction()
- {
- return isTransactional() && _txnUpdateTime.get() > 0 && _transaction.getTransactionStartTime() > 0;
- }
public void selectTx()
{
@@ -483,17 +471,6 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
}
}
- /**
- * Update last transaction activity timestamp
- */
- public void updateTransactionalActivity()
- {
- if (isTransactional())
- {
- _txnUpdateTime.set(System.currentTimeMillis());
- }
- }
-
public Long getTxnStarts()
{
return _txnStarts.get();
@@ -514,14 +491,9 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
return _txnCount.get();
}
- public Principal getAuthorizedPrincipal()
- {
- return ((ServerConnection) getConnection()).getAuthorizedPrincipal();
- }
-
- public Subject getAuthorizedSubject()
+ public Principal getPrincipal()
{
- return ((ServerConnection) getConnection()).getAuthorizedSubject();
+ return _principal;
}
public void addSessionCloseTask(Task task)
@@ -634,38 +606,7 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
return (LogSubject) this;
}
- 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();
-
- // Log a warning on idle or open transactions
- if (idleWarn > 0L && idleTime > idleWarn)
- {
- CurrentActor.get().message(getLogSubject(), ChannelMessages.IDLE_TXN(openTime));
- _logger.warn("IDLE TRANSACTION ALERT " + getLogSubject().toString() + " " + idleTime + " ms");
- }
- else if (openWarn > 0L && openTime > openWarn)
- {
- CurrentActor.get().message(getLogSubject(), ChannelMessages.OPEN_TXN(openTime));
- _logger.warn("OPEN TRANSACTION ALERT " + getLogSubject().toString() + " " + openTime + " ms");
- }
-
- // Close connection for idle or open transactions that have timed out
- if (idleClose > 0L && idleTime > idleClose)
- {
- getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Idle transaction timed out");
- }
- else if (openClose > 0L && openTime > openClose)
- {
- getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Open transaction timed out");
- }
- }
- }
-
+ @Override
public String toLogString()
{
return "[" +
@@ -676,5 +617,7 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
getVirtualHost().getName(),
getChannel())
+ "] ";
+
}
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
index f316d60c6a..42a3975e24 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
@@ -25,23 +25,21 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
-import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQUnknownExchangeType;
+import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
-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.exchange.*;
import org.apache.qpid.server.filter.FilterManager;
import org.apache.qpid.server.filter.FilterManagerFactory;
import org.apache.qpid.server.flow.FlowCreditManager_0_10;
import org.apache.qpid.server.flow.WindowCreditManager;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.GenericActor;
import org.apache.qpid.server.message.MessageMetaData_0_10;
import org.apache.qpid.server.message.MessageTransferMessage;
+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.BaseQueue;
@@ -97,7 +95,6 @@ import org.apache.qpid.transport.TxSelect;
public class ServerSessionDelegate extends SessionDelegate
{
- private static final Logger LOGGER = Logger.getLogger(ServerSessionDelegate.class);
private final IApplicationRegistry _appRegistry;
public ServerSessionDelegate(IApplicationRegistry appRegistry)
@@ -108,24 +105,16 @@ public class ServerSessionDelegate extends SessionDelegate
@Override
public void command(Session session, Method method)
{
- try
- {
- setThreadSubject(session);
+ SecurityManager.setThreadPrincipal(session.getConnection().getAuthorizationID());
- if(!session.isClosing())
+ if(!session.isClosing())
+ {
+ super.command(session, method);
+ if (method.isSync())
{
- super.command(session, method);
- if (method.isSync())
- {
- session.flushProcessed();
- }
+ session.flushProcessed();
}
}
- catch(RuntimeException e)
- {
- LOGGER.error("Exception processing command", e);
- exception(session, method, ExecutionErrorCode.INTERNAL_ERROR, "Exception processing command: " + e);
- }
}
@Override
@@ -134,6 +123,8 @@ public class ServerSessionDelegate extends SessionDelegate
((ServerSession)session).accept(method.getTransfers());
}
+
+
@Override
public void messageReject(Session session, MessageReject method)
{
@@ -212,33 +203,32 @@ public class ServerSessionDelegate extends SessionDelegate
{
exception(session,method,ExecutionErrorCode.NOT_FOUND, "Queue: " + queueName + " not found");
}
- else if(queue.getAuthorizationHolder() != null && queue.getAuthorizationHolder() != session)
+ else if(queue.getPrincipalHolder() != null && queue.getPrincipalHolder() != session)
{
exception(session,method,ExecutionErrorCode.RESOURCE_LOCKED, "Exclusive Queue: " + queueName + " owned exclusively by another session");
}
else
{
+
if(queue.isExclusive())
{
- ServerSession s = (ServerSession) session;
- queue.setExclusiveOwningSession(s);
- if(queue.getAuthorizationHolder() == null)
+ if(queue.getPrincipalHolder() == null)
{
- queue.setAuthorizationHolder(s);
- queue.setExclusiveOwningSession(s);
+ queue.setPrincipalHolder((ServerSession)session);
((ServerSession) session).addSessionCloseTask(new ServerSession.Task()
{
+
public void doTask(ServerSession session)
{
- if(queue.getAuthorizationHolder() == session)
+ if(queue.getPrincipalHolder() == session)
{
- queue.setAuthorizationHolder(null);
- queue.setExclusiveOwningSession(null);
+ queue.setPrincipalHolder(null);
}
}
});
}
+
}
FlowCreditManager_0_10 creditManager = new WindowCreditManager(0L,0L);
@@ -379,6 +369,7 @@ public class ServerSessionDelegate extends SessionDelegate
}
ssn.processed(xfr);
+
}
@Override
@@ -398,7 +389,7 @@ public class ServerSessionDelegate extends SessionDelegate
((ServerSession)session).unregister(sub);
if(!queue.isDeleted() && queue.isExclusive() && queue.getConsumerCount() == 0)
{
- queue.setAuthorizationHolder(null);
+ queue.setPrincipalHolder(null);
}
}
}
@@ -457,19 +448,6 @@ public class ServerSessionDelegate extends SessionDelegate
VirtualHost virtualHost = getVirtualHost(session);
Exchange exchange = getExchange(session, exchangeName);
- //we must check for any unsupported arguments present and throw not-implemented
- if(method.hasArguments())
- {
- Map<String,Object> args = method.getArguments();
-
- //QPID-3392: currently we don't support any!
- if(!args.isEmpty())
- {
- exception(session, method, ExecutionErrorCode.NOT_IMPLEMENTED, "Unsupported exchange argument(s) found " + args.keySet().toString());
- return;
- }
- }
-
if(method.getPassive())
{
if(exchange == null)
@@ -479,6 +457,7 @@ public class ServerSessionDelegate extends SessionDelegate
}
else
{
+ // TODO - check exchange has same properties
if(!exchange.getTypeShortString().toString().equals(method.getType()))
{
exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Cannot redeclare with a different exchange type");
@@ -990,10 +969,10 @@ public class ServerSessionDelegate extends SessionDelegate
}
- if (method.hasAutoDelete()
- && method.getAutoDelete()
- && method.hasExclusive()
- && method.getExclusive())
+ if(method.hasAutoDelete()
+ && method.getAutoDelete()
+ && method.hasExclusive()
+ && method.getExclusive())
{
final AMQQueue q = queue;
final ServerSession.Task deleteQueueTask = new ServerSession.Task()
@@ -1020,23 +999,23 @@ public class ServerSessionDelegate extends SessionDelegate
}
});
}
- if (method.hasExclusive()
- && method.getExclusive())
+ else if(method.getExclusive())
{
final AMQQueue q = queue;
final ServerSession.Task removeExclusive = new ServerSession.Task()
{
+
public void doTask(ServerSession session)
{
- q.setAuthorizationHolder(null);
+ q.setPrincipalHolder(null);
q.setExclusiveOwningSession(null);
}
};
final ServerSession s = (ServerSession) session;
- q.setExclusiveOwningSession(s);
s.addSessionCloseTask(removeExclusive);
queue.addQueueDeleteTask(new AMQQueue.Task()
{
+
public void doTask(AMQQueue queue) throws AMQException
{
s.removeSessionCloseTask(removeExclusive);
@@ -1050,7 +1029,7 @@ public class ServerSessionDelegate extends SessionDelegate
}
}
}
- else if (method.getExclusive() && (queue.getExclusiveOwningSession() != null && !queue.getExclusiveOwningSession().equals(session)))
+ else if (method.getExclusive() && (queue.getPrincipalHolder() != null && !queue.getPrincipalHolder().equals(session)))
{
String description = "Cannot declare queue('" + queueName + "'),"
+ " as exclusive queue with same name "
@@ -1098,7 +1077,7 @@ public class ServerSessionDelegate extends SessionDelegate
}
else
{
- if(queue.getAuthorizationHolder() != null && queue.getAuthorizationHolder() != session)
+ if(queue.getPrincipalHolder() != null && queue.getPrincipalHolder() != session)
{
exception(session,method,ExecutionErrorCode.RESOURCE_LOCKED, "Exclusive Queue: " + queueName + " owned exclusively by another session");
}
@@ -1244,8 +1223,6 @@ public class ServerSessionDelegate extends SessionDelegate
@Override
public void closed(Session session)
{
- setThreadSubject(session);
-
for(Subscription_0_10 sub : getSubscriptions(session))
{
((ServerSession)session).unregister(sub);
@@ -1264,9 +1241,4 @@ public class ServerSessionDelegate extends SessionDelegate
return ((ServerSession)session).getSubscriptions();
}
- private void setThreadSubject(Session session)
- {
- final ServerConnection scon = (ServerConnection) session.getConnection();
- SecurityManager.setThreadSubject(scon.getAuthorizedSubject());
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
index 36e9d78440..db781ead96 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
@@ -50,11 +50,6 @@ public class AutoCommitTransaction implements ServerTransaction
_transactionLog = transactionLog;
}
- public long getTransactionStartTime()
- {
- return 0L;
- }
-
/**
* Since AutoCommitTransaction have no concept of a long lived transaction, any Actions registered
* by the caller are executed immediately.
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
index 946dbd7c28..a04c743be1 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
@@ -20,23 +20,18 @@ package org.apache.qpid.server.txn;
*
*/
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.QueueEntry;
import org.apache.qpid.server.store.TransactionLog;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.store.TransactionLog;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* A concrete implementation of ServerTransaction where enqueue/dequeue
@@ -46,28 +41,17 @@ import org.slf4j.LoggerFactory;
*/
public class LocalTransaction implements ServerTransaction
{
- protected static final Logger _logger = LoggerFactory.getLogger(LocalTransaction.class);
+ protected static final Logger _logger = Logger.getLogger(LocalTransaction.class);
private final List<Action> _postTransactionActions = new ArrayList<Action>();
private volatile TransactionLog.Transaction _transaction;
private TransactionLog _transactionLog;
- private long _txnStartTime = 0L;
public LocalTransaction(TransactionLog transactionLog)
{
_transactionLog = transactionLog;
}
-
- public boolean inTransaction()
- {
- return _transaction != null;
- }
-
- public long getTransactionStartTime()
- {
- return _txnStartTime;
- }
public void addPostTransactionAction(Action postTransactionAction)
{
@@ -105,6 +89,7 @@ public class LocalTransaction implements ServerTransaction
try
{
+
for(QueueEntry entry : queueEntries)
{
ServerMessage message = entry.getMessage();
@@ -128,6 +113,7 @@ public class LocalTransaction implements ServerTransaction
_logger.error("Error during message dequeues", e);
tidyUpOnError(e);
}
+
}
private void tidyUpOnError(Exception e)
@@ -154,7 +140,8 @@ public class LocalTransaction implements ServerTransaction
}
finally
{
- resetDetails();
+ _transaction = null;
+ _postTransactionActions.clear();
}
}
@@ -206,11 +193,6 @@ public class LocalTransaction implements ServerTransaction
{
_postTransactionActions.add(postTransactionAction);
- if (_txnStartTime == 0L)
- {
- _txnStartTime = System.currentTimeMillis();
- }
-
if(message.isPersistent())
{
try
@@ -266,14 +248,17 @@ public class LocalTransaction implements ServerTransaction
}
finally
{
- resetDetails();
+ _transaction = null;
+ _postTransactionActions.clear();
}
+
}
public void rollback()
{
try
{
+
if(_transaction != null)
{
_transaction.abortTran();
@@ -295,15 +280,9 @@ public class LocalTransaction implements ServerTransaction
}
finally
{
- resetDetails();
+ _transaction = null;
+ _postTransactionActions.clear();
}
}
}
-
- private void resetDetails()
- {
- _transaction = null;
- _postTransactionActions.clear();
- _txnStartTime = 0L;
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
index b3c6e1ac3a..b61b8a5c64 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
@@ -52,13 +52,6 @@ public interface ServerTransaction
public void onRollback();
}
- /**
- * Return the time the current transaction started.
- *
- * @return the time this transaction started or 0 if not in a transaction
- */
- long getTransactionStartTime();
-
/**
* Register an Action for execution after transaction commit or rollback. Actions
* will be executed in the order in which they are registered.
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java
index ebace95f65..2db1944cd1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java
@@ -63,10 +63,6 @@ public abstract class HouseKeepingTask implements Runnable
{
_logger.warn(this.getClass().getSimpleName() + " throw exception: " + e, e);
}
- finally
- {
- CurrentActor.remove();
- }
}
public VirtualHost getVirtualHost()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
index 04f19b79bb..4ed0507228 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
@@ -20,28 +20,30 @@
*/
package org.apache.qpid.server.virtualhost;
-import java.util.UUID;
-
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.management.ManagedObject;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.configuration.VirtualHostConfig;
+import org.apache.qpid.server.configuration.ConfigStore;
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.StatisticsGatherer;
-import org.apache.qpid.server.store.DurableConfigurationStore;
+import org.apache.qpid.server.exchange.ExchangeRegistry;
+import org.apache.qpid.server.exchange.ExchangeFactory;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.TransactionLog;
+import org.apache.qpid.server.store.DurableConfigurationStore;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.management.ManagedObject;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.server.binding.BindingFactory;
+
+import java.util.List;
+import java.util.UUID;
+import java.util.TimerTask;
+import java.util.concurrent.FutureTask;
-public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHostConfig, Closeable, StatisticsGatherer
+public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHostConfig, Closeable
{
IConnectionRegistry getConnectionRegistry();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
index 52acd9085b..6ec1c512e5 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
@@ -24,18 +24,19 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.management.NotCompliantMBeanException;
-import javax.management.ObjectName;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQInternalException;
import org.apache.qpid.AMQStoreException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
@@ -62,8 +63,6 @@ import org.apache.qpid.server.logging.messages.VirtualHostMessages;
import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject;
import org.apache.qpid.server.management.AMQManagedObject;
import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.protocol.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.queue.DefaultQueueRegistry;
@@ -72,7 +71,7 @@ import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.stats.StatisticsCounter;
+import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
import org.apache.qpid.server.store.ConfigurationRecoveryHandler;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.store.MessageStore;
@@ -100,7 +99,7 @@ public class VirtualHostImpl implements VirtualHost
private AMQBrokerManagerMBean _brokerMBean;
- private final AuthenticationManager _authenticationManager;
+ private AuthenticationManager _authenticationManager;
private SecurityManager _securityManager;
@@ -112,8 +111,6 @@ public class VirtualHostImpl implements VirtualHost
private BrokerConfig _broker;
private UUID _id;
- private boolean _statisticsEnabled = false;
- private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
private final long _createTime = System.currentTimeMillis();
private final ConcurrentHashMap<BrokerLink,BrokerLink> _links = new ConcurrentHashMap<BrokerLink, BrokerLink>();
@@ -164,12 +161,12 @@ public class VirtualHostImpl implements VirtualHost
public String getObjectInstanceName()
{
- return ObjectName.quote(_name);
+ return _name.toString();
}
public String getName()
{
- return _name;
+ return _name.toString();
}
public VirtualHostImpl getVirtualHost()
@@ -247,13 +244,11 @@ public class VirtualHostImpl implements VirtualHost
initialiseMessageStore(hostConfig);
}
- _authenticationManager = ApplicationRegistry.getInstance().getAuthenticationManager();
+ _authenticationManager = new PrincipalDatabaseAuthenticationManager(_name, _configuration);
_brokerMBean = new AMQBrokerManagerMBean(_virtualHostMBean);
_brokerMBean.register();
initialiseHouseKeeping(hostConfig.getHousekeepingExpiredMessageCheckPeriod());
-
- initialiseStatistics();
}
private void initialiseHouseKeeping(long period)
@@ -286,30 +281,19 @@ public class VirtualHostImpl implements VirtualHost
// house keeping task from running.
}
}
- for (AMQConnectionModel connection : getConnectionRegistry().getConnections())
- {
- _logger.debug("Checking for long running open transactions on connection " + connection);
- for (AMQSessionModel session : connection.getSessionModels())
- {
- _logger.debug("Checking for long running open transactions on session " + session);
- try
- {
- session.checkTransactionStatus(_configuration.getTransactionTimeoutOpenWarn(),
- _configuration.getTransactionTimeoutOpenClose(),
- _configuration.getTransactionTimeoutIdleWarn(),
- _configuration.getTransactionTimeoutIdleClose());
- }
- catch (Exception e)
- {
- _logger.error("Exception in housekeeping for connection: " + connection.toString(), e);
- }
- }
- }
}
}
scheduleHouseKeepingTask(period, new ExpiredMessagesTask(this));
+ class ForceChannelClosuresTask extends TimerTask
+ {
+ public void run()
+ {
+ _connectionRegistry.expireClosedChannels();
+ }
+ }
+
Map<String, VirtualHostPluginFactory> plugins =
ApplicationRegistry.getInstance().getPluginManager().getVirtualHostPlugins();
@@ -643,80 +627,6 @@ public class VirtualHostImpl implements VirtualHost
{
return _bindingFactory;
}
-
- public void registerMessageDelivered(long messageSize)
- {
- if (isStatisticsEnabled())
- {
- _messagesDelivered.registerEvent(1L);
- _dataDelivered.registerEvent(messageSize);
- }
- _appRegistry.registerMessageDelivered(messageSize);
- }
-
- public void registerMessageReceived(long messageSize, long timestamp)
- {
- if (isStatisticsEnabled())
- {
- _messagesReceived.registerEvent(1L, timestamp);
- _dataReceived.registerEvent(messageSize, timestamp);
- }
- _appRegistry.registerMessageReceived(messageSize, timestamp);
- }
-
- public StatisticsCounter getMessageReceiptStatistics()
- {
- return _messagesReceived;
- }
-
- public StatisticsCounter getDataReceiptStatistics()
- {
- return _dataReceived;
- }
-
- public StatisticsCounter getMessageDeliveryStatistics()
- {
- return _messagesDelivered;
- }
-
- public StatisticsCounter getDataDeliveryStatistics()
- {
- return _dataDelivered;
- }
-
- public void resetStatistics()
- {
- _messagesDelivered.reset();
- _dataDelivered.reset();
- _messagesReceived.reset();
- _dataReceived.reset();
-
- for (AMQConnectionModel connection : _connectionRegistry.getConnections())
- {
- connection.resetStatistics();
- }
- }
-
- public void initialiseStatistics()
- {
- setStatisticsEnabled(!StatisticsCounter.DISABLE_STATISTICS &&
- _appRegistry.getConfiguration().isStatisticsGenerationVirtualhostsEnabled());
-
- _messagesDelivered = new StatisticsCounter("messages-delivered-" + getName());
- _dataDelivered = new StatisticsCounter("bytes-delivered-" + getName());
- _messagesReceived = new StatisticsCounter("messages-received-" + getName());
- _dataReceived = new StatisticsCounter("bytes-received-" + getName());
- }
-
- public boolean isStatisticsEnabled()
- {
- return _statisticsEnabled;
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
- _statisticsEnabled = enabled;
- }
public void createBrokerConnection(final String transport,
final String host,
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java b/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java
index 2c0ceed80b..dca165fa7e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java
@@ -192,7 +192,7 @@ public class MessageStoreTool
if (_initialised)
{
- ApplicationRegistry.remove();
+ ApplicationRegistry.remove(1);
}
_console.println("...exiting");
@@ -274,7 +274,7 @@ public class MessageStoreTool
{
ConfigurationFileApplicationRegistry registry = new ConfigurationFileApplicationRegistry(configFile);
- ApplicationRegistry.remove();
+ ApplicationRegistry.remove(1);
ApplicationRegistry.initialise(registry);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java b/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java
index 806e161bbc..4fd4999b19 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java
@@ -364,7 +364,7 @@ public class Show extends AbstractCommand
{
if(msg instanceof AMQMessage)
{
- headers = ((BasicContentHeaderProperties) ((AMQMessage)msg).getContentHeaderBody().getProperties());
+ headers = ((BasicContentHeaderProperties) ((AMQMessage)msg).getContentHeaderBody().properties);
}
}
catch (AMQException e)
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java
deleted file mode 100644
index 63423cbaa7..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java
+++ /dev/null
@@ -1,196 +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 static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-import static org.apache.qpid.server.configuration.ServerConfiguration.DEFAULT_PORT;
-import static org.apache.qpid.server.configuration.ServerConfiguration.DEFAULT_JMXPORT;
-
-import java.util.Collections;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-
-import org.apache.qpid.test.utils.QpidTestCase;
-
-
-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()
- {
- _options.addPort(TEST_PORT1);
- assertEquals(Collections.singleton(TEST_PORT1), _options.getPorts());
- }
-
- public void testManyOverriddenPorts()
- {
- _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());
- }
-
- public void testDuplicateOverriddenPortsAreSilentlyIgnored()
- {
- _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());
- }
-
- 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()
- {
- final String testConfigFile = "etc/mytestconfig.xml";
- _options.setConfigFile(testConfigFile);
- assertEquals(testConfigFile, _options.getConfigFile());
- }
-
- public void testDefaultLogConfigFile()
- {
- assertNull(_options.getLogConfigFile());
- }
-
- public void testOverriddenLogConfigFile()
- {
- final String testLogConfigFile = "etc/mytestlog4j.xml";
- _options.setLogConfigFile(testLogConfigFile);
- assertEquals(testLogConfigFile, _options.getLogConfigFile());
- }
-
- public void testDefaultJmxPort()
- {
- assertNull(_options.getJmxPort());
- }
-
- public void testJmxPort()
- {
- _options.setJmxPort(TEST_PORT1);
- assertEquals(Integer.valueOf(TEST_PORT1), _options.getJmxPort());
- }
-
- public void testQpidHomeExposesSysProperty()
- {
- 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));
- }
-
- public void testManyOverriddenExcludedPortFor0_10()
- {
- _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));
- }
-
- public void testDuplicatedOverriddenExcludedPortFor0_10AreSilentlyIgnored()
- {
- _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));
- }
-
- public void testDefaultBind()
- {
- assertNull(_options.getBind());
- }
-
- public void testOverriddenBind()
- {
- final String bind = "192.168.0.1";
- _options.setBind(bind);
- assertEquals(bind, _options.getBind());
- }
-
- public void testDefaultLogWatchFrequency()
- {
- assertEquals(0L, _options.getLogWatchFrequency());
- }
-
- public void testOverridenLogWatchFrequency()
- {
- final int myFreq = 10 * 1000;
-
- _options.setLogWatchFrequency(myFreq);
- assertEquals(myFreq, _options.getLogWatchFrequency());
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java
deleted file mode 100644
index 3bb8d33190..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package org.apache.qpid.server;
-
-import java.util.EnumSet;
-
-import org.apache.qpid.test.utils.QpidTestCase;
-
-/**
- * Test to verify the command line parsing within the Main class, by
- * providing it a series of command line arguments and verifying the
- * BrokerOptions emerging for use in starting the Broker instance.
- */
-public class MainTest extends QpidTestCase
-{
- public void testNoOptionsSpecified()
- {
- BrokerOptions options = startDummyMain("");
-
- assertTrue(options.getPorts().isEmpty());
- assertTrue(options.getSSLPorts().isEmpty());
- assertEquals(null, options.getJmxPort());
- assertEquals(null, options.getConfigFile());
- assertEquals(null, options.getLogConfigFile());
- assertEquals(null, options.getBind());
-
- for(ProtocolExclusion pe : EnumSet.allOf(ProtocolExclusion.class))
- {
- assertEquals(0, options.getExcludedPorts(pe).size());
- }
- }
-
- public void testPortOverriddenSingle()
- {
- BrokerOptions options = startDummyMain("-p 1234");
-
- assertTrue(options.getPorts().contains(1234));
- assertEquals(1, options.getPorts().size());
- assertTrue(options.getSSLPorts().isEmpty());
- }
-
- public void testPortOverriddenMultiple()
- {
- BrokerOptions options = startDummyMain("-p 1234 -p 4321");
-
- assertTrue(options.getPorts().contains(1234));
- assertTrue(options.getPorts().contains(4321));
- assertEquals(2, options.getPorts().size());
- assertTrue(options.getSSLPorts().isEmpty());
- }
-
- public void testSSLPortOverriddenSingle()
- {
- BrokerOptions options = startDummyMain("-s 5678");
-
- assertTrue(options.getSSLPorts().contains(5678));
- assertEquals(1, options.getSSLPorts().size());
- assertTrue(options.getPorts().isEmpty());
- }
-
- public void testSSLPortOverriddenMultiple()
- {
- BrokerOptions options = startDummyMain("-s 5678 -s 8765");
-
- assertTrue(options.getSSLPorts().contains(5678));
- assertTrue(options.getSSLPorts().contains(8765));
- assertEquals(2, options.getSSLPorts().size());
- assertTrue(options.getPorts().isEmpty());
- }
-
- public void testNonSSLandSSLPortsOverridden()
- {
- BrokerOptions options = startDummyMain("-p 5678 -s 8765");
-
- assertTrue(options.getPorts().contains(5678));
- assertTrue(options.getSSLPorts().contains(8765));
- assertEquals(1, options.getPorts().size());
- assertEquals(1, options.getSSLPorts().size());
- }
-
- public void testJMXportOverridden()
- {
- BrokerOptions options = startDummyMain("-m 3456");
-
- assertEquals(Integer.valueOf(3456), options.getJmxPort());
- }
-
- public void testExclude0_10()
- {
- BrokerOptions options = startDummyMain("-p 3456 --exclude-0-10 3456");
-
- 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");
-
- assertEquals("abcd/config.xml", options.getConfigFile());
- }
-
- public void testLogConfig()
- {
- BrokerOptions options = startDummyMain("-l wxyz/log4j.xml");
-
- assertEquals("wxyz/log4j.xml", options.getLogConfigFile());
- }
-
- public void testLogWatch()
- {
- BrokerOptions options = startDummyMain("-w 9");
-
- assertEquals(9, options.getLogWatchFrequency());
- }
-
- private BrokerOptions startDummyMain(String commandLine)
- {
- return (new TestMain(commandLine.split("\\s"))).getOptions();
- }
-
- private class TestMain extends Main
- {
- private BrokerOptions _options;
-
- public TestMain(String[] args)
- {
- super(args);
- }
-
- @Override
- protected void startBroker(BrokerOptions options)
- {
- _options = options;
- }
-
- public BrokerOptions getOptions()
- {
- return _options;
- }
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/RunBrokerWithCommand.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/RunBrokerWithCommand.java
new file mode 100644
index 0000000000..59543874b4
--- /dev/null
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/RunBrokerWithCommand.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.server;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.Level;
+
+import java.io.InputStream;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+
+public class RunBrokerWithCommand
+{
+ public static void main(String[] args)
+ {
+ //Start the broker
+ try
+ {
+ String[] fudge = args.clone();
+
+ // Override the first value which is the command we are going to run later.
+ fudge[0] = "-v";
+ new Main(fudge).startup();
+ }
+ catch (Exception e)
+ {
+ System.err.println("Unable to start broker due to: " + e.getMessage());
+
+ e.printStackTrace();
+ exit(1);
+ }
+
+ Logger.getRootLogger().setLevel(Level.ERROR);
+
+ //run command
+ try
+ {
+ Process task = Runtime.getRuntime().exec(args[0]);
+ System.err.println("Started Proccess: " + args[0]);
+
+ InputStream inputStream = task.getInputStream();
+
+ InputStream errorStream = task.getErrorStream();
+
+ Thread out = new Thread(new Outputter("[OUT]", new BufferedReader(new InputStreamReader(inputStream))));
+ Thread err = new Thread(new Outputter("[ERR]", new BufferedReader(new InputStreamReader(errorStream))));
+
+ out.start();
+ err.start();
+
+ out.join();
+ err.join();
+
+ System.err.println("Waiting for process to exit: " + args[0]);
+ task.waitFor();
+ System.err.println("Done Proccess: " + args[0]);
+
+ }
+ catch (IOException e)
+ {
+ System.err.println("Proccess had problems: " + e.getMessage());
+ e.printStackTrace(System.err);
+ exit(1);
+ }
+ catch (InterruptedException e)
+ {
+ System.err.println("Proccess had problems: " + e.getMessage());
+ e.printStackTrace(System.err);
+
+ exit(1);
+ }
+
+
+ exit(0);
+ }
+
+ private static void exit(int i)
+ {
+ Logger.getRootLogger().setLevel(Level.INFO);
+ System.exit(i);
+ }
+
+ static class Outputter implements Runnable
+ {
+
+ BufferedReader reader;
+ String prefix;
+
+ Outputter(String s, BufferedReader r)
+ {
+ prefix = s;
+ reader = r;
+ }
+
+ public void run()
+ {
+ String line;
+ try
+ {
+ while ((line = reader.readLine()) != null)
+ {
+ System.out.println(prefix + line);
+ }
+ }
+ catch (IOException e)
+ {
+ System.out.println("Error occured reading; " + e.getMessage());
+ }
+ }
+
+ }
+
+}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
index b0893eb53f..718874cf69 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
@@ -20,558 +20,742 @@
*/
package org.apache.qpid.server.configuration;
-import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.List;
import java.util.Locale;
+import junit.framework.TestCase;
+
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.AMQProtocolEngine;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
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.util.InternalBrokerBaseCase;
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.TestNetworkDriver;
-public class ServerConfigurationTest extends QpidTestCase
+public class ServerConfigurationTest extends InternalBrokerBaseCase
{
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 testSetJMXManagementPort() throws ConfigurationException
{
- _serverConfig.initialise();
- _serverConfig.setJMXManagementPort(23);
- assertEquals(23, _serverConfig.getJMXManagementPort());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ serverConfig.setJMXManagementPort(23);
+ assertEquals(23, serverConfig.getJMXManagementPort());
}
public void testGetJMXManagementPort() throws ConfigurationException
{
_config.setProperty("management.jmxport", 42);
- _serverConfig.initialise();
- assertEquals(42, _serverConfig.getJMXManagementPort());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(42, serverConfig.getJMXManagementPort());
}
public void testGetPlatformMbeanserver() throws ConfigurationException
{
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getPlatformMbeanserver());
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getPlatformMbeanserver());
}
public void testGetPluginDirectory() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(null, _serverConfig.getPluginDirectory());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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());
+ 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());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("/path/to/cache", serverConfig.getCacheDirectory());
+ }
+
+ public void testGetPrincipalDatabaseNames() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getPrincipalDatabaseNames().size());
+
+ // Check value we set
+ _config.setProperty("security.principal-databases.principal-database(0).name", "a");
+ _config.setProperty("security.principal-databases.principal-database(1).name", "b");
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ List<String> dbs = serverConfig.getPrincipalDatabaseNames();
+ assertEquals(2, dbs.size());
+ assertEquals("a", dbs.get(0));
+ assertEquals("b", dbs.get(1));
+ }
+
+ public void testGetPrincipalDatabaseClass() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getPrincipalDatabaseClass().size());
+
+ // Check value we set
+ _config.setProperty("security.principal-databases.principal-database(0).class", "a");
+ _config.setProperty("security.principal-databases.principal-database(1).class", "b");
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ List<String> dbs = serverConfig.getPrincipalDatabaseClass();
+ assertEquals(2, dbs.size());
+ assertEquals("a", dbs.get(0));
+ assertEquals("b", dbs.get(1));
+ }
+
+ public void testGetPrincipalDatabaseAttributeNames() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getPrincipalDatabaseAttributeNames(1).size());
+
+ // Check value we set
+ _config.setProperty("security.principal-databases.principal-database(0).attributes(0).attribute.name", "a");
+ _config.setProperty("security.principal-databases.principal-database(0).attributes(1).attribute.name", "b");
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ List<String> dbs = serverConfig.getPrincipalDatabaseAttributeNames(0);
+ assertEquals(2, dbs.size());
+ assertEquals("a", dbs.get(0));
+ assertEquals("b", dbs.get(1));
+ }
+
+ public void testGetPrincipalDatabaseAttributeValues() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getPrincipalDatabaseAttributeValues(1).size());
+
+ // Check value we set
+ _config.setProperty("security.principal-databases.principal-database(0).attributes(0).attribute.value", "a");
+ _config.setProperty("security.principal-databases.principal-database(0).attributes(1).attribute.value", "b");
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ List<String> dbs = serverConfig.getPrincipalDatabaseAttributeValues(0);
+ assertEquals(2, dbs.size());
+ assertEquals("a", dbs.get(0));
+ assertEquals("b", dbs.get(1));
+ }
+
+ public void testGetManagementAccessList() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getManagementAccessList().size());
+
+ // Check value we set
+ _config.setProperty("security.jmx.access(0)", "a");
+ _config.setProperty("security.jmx.access(1)", "b");
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ List<String> dbs = serverConfig.getManagementAccessList();
+ assertEquals(2, dbs.size());
+ assertEquals("a", dbs.get(0));
+ assertEquals("b", dbs.get(1));
}
public void testGetFrameSize() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(65536, _serverConfig.getFrameSize());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getFrameSize());
+ }
+
+ public void testGetProtectIOEnabled() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getProtectIOEnabled());
+
+ // Check value we set
+ _config.setProperty(ServerConfiguration.CONNECTOR_PROTECTIO_ENABLED, true);
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getProtectIOEnabled());
+ }
+
+ public void testGetBufferReadLimit() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(262144, serverConfig.getBufferReadLimit());
+
+ // Check value we set
+ _config.setProperty(ServerConfiguration.CONNECTOR_PROTECTIO_READ_BUFFER_LIMIT_SIZE, 23);
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getBufferReadLimit());
}
+ public void testGetBufferWriteLimit() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(262144, serverConfig.getBufferWriteLimit());
+
+ // Check value we set
+ _config.setProperty(ServerConfiguration.CONNECTOR_PROTECTIO_WRITE_BUFFER_LIMIT_SIZE, 23);
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getBufferWriteLimit());
+ }
+
+
public void testGetStatusEnabled() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
assertEquals(ServerConfiguration.DEFAULT_STATUS_UPDATES.equalsIgnoreCase("on"),
- _serverConfig.getStatusUpdatesEnabled());
+ serverConfig.getStatusUpdatesEnabled());
// Check disabling we set
_config.setProperty(ServerConfiguration.STATUS_UPDATES, "off");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getStatusUpdatesEnabled());
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getStatusUpdatesEnabled());
}
public void testGetSynchedClocks() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getSynchedClocks());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getSynchedClocks());
}
public void testGetLocale() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
// The Default is what ever the VMs default is
Locale defaultLocale = Locale.getDefault();
- assertEquals(defaultLocale, _serverConfig.getLocale());
+ 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());
+ 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());
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(update, serverConfig.getLocale());
}
public void testGetMsgAuth() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getMsgAuth());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getMsgAuth());
+ }
+
+ public void testGetJMXPrincipalDatabase() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(null, serverConfig.getJMXPrincipalDatabase());
+
+ // Check value we set
+ _config.setProperty("security.jmx.principal-database", "a");
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("a", serverConfig.getJMXPrincipalDatabase());
}
public void testGetManagementKeyStorePath() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(null, _serverConfig.getManagementKeyStorePath());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("a", serverConfig.getManagementKeyStorePath());
}
public void testGetManagementSSLEnabled() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getManagementSSLEnabled());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getManagementSSLEnabled());
// Check value we set
_config.setProperty("management.ssl.enabled", false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getManagementSSLEnabled());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getManagementSSLEnabled());
}
public void testGetManagementKeyStorePassword() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(null, _serverConfig.getManagementKeyStorePassword());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("a", serverConfig.getManagementKeyStorePassword());
}
public void testGetQueueAutoRegister() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getQueueAutoRegister());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getQueueAutoRegister());
}
public void testGetManagementEnabled() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getManagementEnabled());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getManagementEnabled());
// Check value we set
_config.setProperty("management.enabled", false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getManagementEnabled());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getManagementEnabled());
}
public void testSetManagementEnabled() throws ConfigurationException
{
// Check value we set
- _serverConfig.initialise();
- _serverConfig.setManagementEnabled(false);
- assertEquals(false, _serverConfig.getManagementEnabled());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ serverConfig.setManagementEnabled(false);
+ assertEquals(false, serverConfig.getManagementEnabled());
}
public void testGetHeartBeatDelay() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(5, _serverConfig.getHeartBeatDelay());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getHeartBeatDelay());
}
public void testGetHeartBeatTimeout() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(2.0, _serverConfig.getHeartBeatTimeout());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(2.3, serverConfig.getHeartBeatTimeout());
}
public void testGetMaximumMessageAge() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(0, _serverConfig.getMaximumMessageAge());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getMaximumMessageAge());
// Check value we set
_config.setProperty("maximumMessageAge", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMaximumMessageAge());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(10, serverConfig.getMaximumMessageAge());
}
public void testGetMaximumMessageCount() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(0, _serverConfig.getMaximumMessageCount());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getMaximumMessageCount());
// Check value we set
_config.setProperty("maximumMessageCount", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMaximumMessageCount());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(10, serverConfig.getMaximumMessageCount());
}
public void testGetMaximumQueueDepth() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(0, _serverConfig.getMaximumQueueDepth());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getMaximumQueueDepth());
// Check value we set
_config.setProperty("maximumQueueDepth", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMaximumQueueDepth());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(10, serverConfig.getMaximumQueueDepth());
}
public void testGetMaximumMessageSize() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(0, _serverConfig.getMaximumMessageSize());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getMaximumMessageSize());
// Check value we set
_config.setProperty("maximumMessageSize", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMaximumMessageSize());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(10, serverConfig.getMaximumMessageSize());
}
public void testGetMinimumAlertRepeatGap() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(0, _serverConfig.getMinimumAlertRepeatGap());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getMinimumAlertRepeatGap());
// Check value we set
_config.setProperty("minimumAlertRepeatGap", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMinimumAlertRepeatGap());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(10, serverConfig.getMinimumAlertRepeatGap());
}
public void testGetProcessors() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(4, _serverConfig.getConnectorProcessors());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(4, serverConfig.getProcessors());
// Check value we set
_config.setProperty("connector.processors", 10);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getConnectorProcessors());
- }
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(10, serverConfig.getProcessors());
+ }
- public void testGetPorts() throws ConfigurationException
+ public void testGetPort() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertNotNull(_serverConfig.getPorts());
- assertEquals(1, _serverConfig.getPorts().size());
- assertEquals(5672, _serverConfig.getPorts().get(0));
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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));
+ 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());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("wildcard", serverConfig.getBind());
// Check value we set
_config.setProperty("connector.bind", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getBind());
+ 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());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(32767, serverConfig.getReceiveBufferSize());
// Check value we set
_config.setProperty("connector.socketReceiveBuffer", "23");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(23, _serverConfig.getReceiveBufferSize());
+ 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());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(32767, serverConfig.getWriteBufferSize());
// Check value we set
_config.setProperty("connector.socketWriteBuffer", "23");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(23, _serverConfig.getWriteBufferSize());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getWriteBufferSize());
}
public void testGetTcpNoDelay() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getTcpNoDelay());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getTcpNoDelay());
}
public void testGetEnableExecutorPool() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getEnableExecutorPool());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getEnableExecutorPool());
// Check value we set
_config.setProperty("advanced.filterchain[@enableExecutorPool]", true);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getEnableExecutorPool());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getEnableExecutorPool());
}
public void testGetEnableSSL() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getEnableSSL());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getEnableSSL());
}
public void testGetSSLOnly() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getSSLOnly());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ 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());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getSSLOnly());
}
- public void testGetSSLPorts() throws ConfigurationException
+ public void testGetSSLPort() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertNotNull(_serverConfig.getSSLPorts());
- assertEquals(1, _serverConfig.getSSLPorts().size());
- assertEquals(ServerConfiguration.DEFAULT_SSL_PORT, _serverConfig.getSSLPorts().get(0));
-
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(8672, serverConfig.getSSLPort());
// 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));
+ _config.setProperty("connector.ssl.port", 23);
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getSSLPort());
}
public void testGetKeystorePath() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals("none", _serverConfig.getKeystorePath());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("none", serverConfig.getKeystorePath());
// Check value we set
_config.setProperty("connector.ssl.keystorePath", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getKeystorePath());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("a", serverConfig.getKeystorePath());
}
public void testGetKeystorePassword() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals("none", _serverConfig.getKeystorePassword());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("none", serverConfig.getKeystorePassword());
// Check value we set
_config.setProperty("connector.ssl.keystorePassword", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getKeystorePassword());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("a", serverConfig.getKeystorePassword());
}
public void testGetCertType() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals("SunX509", _serverConfig.getCertType());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("SunX509", serverConfig.getCertType());
// Check value we set
_config.setProperty("connector.ssl.certType", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getCertType());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("a", serverConfig.getCertType());
+ }
+
+ public void testGetQpidNIO() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getQpidNIO());
+
+ // Check value we set
+ _config.setProperty("connector.qpidnio", true);
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getQpidNIO());
}
public void testGetUseBiasedWrites() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getUseBiasedWrites());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getUseBiasedWrites());
// Check value we set
_config.setProperty("advanced.useWriteBiasedPool", true);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getUseBiasedWrites());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getUseBiasedWrites());
}
public void testGetHousekeepingExpiredMessageCheckPeriod() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(30000, _serverConfig.getHousekeepingCheckPeriod());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(30000, serverConfig.getHousekeepingCheckPeriod());
// Check value we set
_config.setProperty("housekeeping.expiredMessageCheckPeriod", 23L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(23, _serverConfig.getHousekeepingCheckPeriod());
- _serverConfig.setHousekeepingExpiredMessageCheckPeriod(42L);
- assertEquals(42, _serverConfig.getHousekeepingCheckPeriod());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getHousekeepingCheckPeriod());
+ serverConfig.setHousekeepingExpiredMessageCheckPeriod(42L);
+ assertEquals(42, serverConfig.getHousekeepingCheckPeriod());
}
public void testSingleConfiguration() throws IOException, ConfigurationException
@@ -583,7 +767,7 @@ public class ServerConfigurationTest extends QpidTestCase
out.close();
ServerConfiguration conf = new ServerConfiguration(fileA);
conf.initialise();
- assertEquals("4235", conf.getSSLPorts().get(0));
+ assertEquals(4235, conf.getSSLPort());
}
public void testCombinedConfiguration() throws IOException, ConfigurationException
@@ -608,17 +792,19 @@ public class ServerConfigurationTest extends QpidTestCase
out.close();
out = new FileWriter(fileB);
- out.write("<broker><connector><ssl><port>2345</port></ssl></connector></broker>");
+ out.write("<broker><connector><ssl><port>2345</port></ssl><qpidnio>true</qpidnio></connector></broker>");
out.close();
ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile());
config.initialise();
- assertEquals("4235", config.getSSLPorts().get(0)); // From first file, not
+ assertEquals(4235, config.getSSLPort()); // 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
+ assertEquals(true, config.getQpidNIO()); // From the second file, not
+ // present in the first
}
public void testVariableInterpolation() throws Exception
@@ -649,8 +835,9 @@ public class ServerConfigurationTest extends QpidTestCase
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<principal-databases>\n");
out.write("\t\t\t<principal-database>\n");
+ out.write("\t\t\t\t<name>passwordfile</name>\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");
@@ -659,7 +846,11 @@ public class ServerConfigurationTest extends QpidTestCase
out.write("\t\t\t\t\t</attribute>\n");
out.write("\t\t\t\t</attributes>\n");
out.write("\t\t\t</principal-database>\n");
- out.write("\t\t</pd-auth-manager>\n");
+ out.write("\t\t</principal-databases>\n");
+ out.write("\t\t<jmx>\n");
+ out.write("\t\t\t<access>/dev/null</access>\n");
+ out.write("\t\t\t<principal-database>passwordfile</principal-database>\n");
+ out.write("\t\t</jmx>\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");
@@ -695,8 +886,9 @@ public class ServerConfigurationTest extends QpidTestCase
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<principal-databases>\n");
out.write("\t\t\t<principal-database>\n");
+ out.write("\t\t\t\t<name>passwordfile</name>\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");
@@ -705,7 +897,11 @@ public class ServerConfigurationTest extends QpidTestCase
out.write("\t\t\t\t\t</attribute>\n");
out.write("\t\t\t\t</attributes>\n");
out.write("\t\t\t</principal-database>\n");
- out.write("\t\t</pd-auth-manager>\n");
+ out.write("\t\t</principal-databases>\n");
+ out.write("\t\t<jmx>\n");
+ out.write("\t\t\t<access>/dev/null</access>\n");
+ out.write("\t\t\t<principal-database>passwordfile</principal-database>\n");
+ out.write("\t\t</jmx>\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");
@@ -796,8 +992,9 @@ public class ServerConfigurationTest extends QpidTestCase
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<principal-databases>\n");
out.write("\t\t\t<principal-database>\n");
+ out.write("\t\t\t\t<name>passwordfile</name>\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");
@@ -806,7 +1003,11 @@ public class ServerConfigurationTest extends QpidTestCase
out.write("\t\t\t\t\t</attribute>\n");
out.write("\t\t\t\t</attributes>\n");
out.write("\t\t\t</principal-database>\n");
- out.write("\t\t</pd-auth-manager>\n");
+ out.write("\t\t</principal-databases>\n");
+ out.write("\t\t<jmx>\n");
+ out.write("\t\t\t<access>/dev/null</access>\n");
+ out.write("\t\t\t<principal-database>passwordfile</principal-database>\n");
+ out.write("\t\t</jmx>\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");
@@ -843,9 +1044,8 @@ public class ServerConfigurationTest extends QpidTestCase
writeConfigFile(mainFile, false, true, null, "test");
// Load config
- ApplicationRegistry.remove();
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ ApplicationRegistry.initialise(reg, 1);
// Test config
VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
@@ -876,9 +1076,8 @@ public class ServerConfigurationTest extends QpidTestCase
writeVirtualHostsFile(vhostsFile, "test");
// Load config
- ApplicationRegistry.remove();
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ ApplicationRegistry.initialise(reg, 1);
// Test config
VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
@@ -911,9 +1110,8 @@ public class ServerConfigurationTest extends QpidTestCase
writeConfigFile(mainFile, false, false, vhostsFile, null);
// Load config
- ApplicationRegistry.remove();
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ ApplicationRegistry.initialise(reg, 1);
// Test config
VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
@@ -955,10 +1153,9 @@ public class ServerConfigurationTest extends QpidTestCase
// Load config
try
- {
- ApplicationRegistry.remove();
+ {
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ ApplicationRegistry.initialise(reg, 1);
fail("Different virtualhost XML configurations not allowed");
}
catch (ConfigurationException ce)
@@ -991,9 +1188,8 @@ public class ServerConfigurationTest extends QpidTestCase
// Load config
try
{
- ApplicationRegistry.remove();
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ ApplicationRegistry.initialise(reg, 1);
fail("Multiple virtualhost XML configurations not allowed");
}
catch (ConfigurationException ce)
@@ -1285,81 +1481,4 @@ public class ServerConfigurationTest extends QpidTestCase
fail("Should throw a ConfigurationException");
}
}
-
- /*
- * 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());
- }
- }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
index 593119041d..917755e8a5 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
@@ -20,8 +20,6 @@
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.queue.AMQPriorityQueue;
import org.apache.qpid.server.queue.AMQQueue;
@@ -205,29 +203,5 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase
}
- /**
- * Tests that the old element security.authentication.name is rejected. This element
- * was never supported properly as authentication is performed before the virtual host
- * is considered.
- */
- public void testSecurityAuthenticationNameRejected() throws Exception
- {
- getConfigXml().addProperty("virtualhosts.virtualhost.testSecurityAuthenticationNameRejected.security.authentication.name",
- "testdb");
-
- try
- {
- super.createBroker();
- fail("Exception not thrown");
- }
- catch(ConfigurationException ce)
- {
- assertEquals("Incorrect error message",
- "Validation error : security/authentication/name is no longer a supported element within the configuration xml." +
- " It appears in virtual host definition : " + getName(),
- ce.getMessage());
- }
- }
-
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
index 44da761353..7b58966a4c 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
@@ -276,7 +276,7 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
static ContentHeaderBody getContentHeader(FieldTable headers)
{
ContentHeaderBody header = new ContentHeaderBody();
- header.setProperties(getProperties(headers));
+ header.properties = getProperties(headers);
return header;
}
@@ -482,16 +482,6 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
{
return 0; //To change body of implemented methods use File | Settings | File Templates.
}
-
- public boolean isDequeued()
- {
- return false;
- }
-
- public boolean isDispensed()
- {
- return false;
- }
};
if(action != null)
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
index 403a290a0f..f72961c03c 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
@@ -396,7 +396,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
IncomingMessage message = new IncomingMessage(info);
final ContentHeaderBody chb = new ContentHeaderBody();
BasicContentHeaderProperties props = new BasicContentHeaderProperties();
- chb.setProperties(props);
+ chb.properties = props;
message.setContentHeaderBody(chb);
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java
index e8defd0e58..3752dcb37e 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java
@@ -28,7 +28,11 @@ import org.apache.qpid.server.logging.AbstractRootMessageLogger;
public class UnitTestMessageLogger extends AbstractRootMessageLogger
{
- private final List<Object> _log = new LinkedList<Object>();
+ List<Object> _log;
+
+ {
+ _log = new LinkedList<Object>();
+ }
public UnitTestMessageLogger()
{
@@ -65,14 +69,4 @@ public class UnitTestMessageLogger extends AbstractRootMessageLogger
{
_log.clear();
}
-
- public boolean messageContains(final int index, final String contains)
- {
- if (index + 1 > _log.size())
- {
- throw new IllegalArgumentException("Message with index " + index + " has not been logged");
- }
- final String message = _log.get(index).toString();
- return message.contains(contains);
- }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java
index f3ee2707b0..a6c17e042e 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java
@@ -21,26 +21,22 @@
package org.apache.qpid.server.management;
+import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
+import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularData;
-
-
-import org.apache.commons.lang.NotImplementedException;
-import org.apache.qpid.management.common.mbeans.UserManagement;
+import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
import org.apache.qpid.server.security.auth.management.AMQUserManagementMBean;
import org.apache.qpid.server.util.InternalBrokerBaseCase;
-/**
- *
- * Tests the AMQUserManagementMBean and its interaction with the PrincipalDatabase.
- *
+/* Note: The main purpose is to test the jmx access rights file manipulation
+ * within AMQUserManagementMBean. The Principal Databases are tested by their own tests,
+ * this test just exercises their usage in AMQUserManagementMBean.
*/
public class AMQUserManagementMBeanTest extends InternalBrokerBaseCase
{
@@ -48,6 +44,7 @@ public class AMQUserManagementMBeanTest extends InternalBrokerBaseCase
private AMQUserManagementMBean _amqumMBean;
private File _passwordFile;
+ private File _accessFile;
private static final String TEST_USERNAME = "testuser";
private static final String TEST_PASSWORD = "password";
@@ -60,6 +57,7 @@ public class AMQUserManagementMBeanTest extends InternalBrokerBaseCase
_database = new PlainPasswordFilePrincipalDatabase();
_amqumMBean = new AMQUserManagementMBean();
loadFreshTestPasswordFile();
+ loadFreshTestAccessFile();
}
@Override
@@ -67,67 +65,142 @@ public class AMQUserManagementMBeanTest extends InternalBrokerBaseCase
{
//clean up test password/access files
File _oldPasswordFile = new File(_passwordFile.getAbsolutePath() + ".old");
+ File _oldAccessFile = new File(_accessFile.getAbsolutePath() + ".old");
_oldPasswordFile.delete();
+ _oldAccessFile.delete();
_passwordFile.delete();
+ _accessFile.delete();
super.tearDown();
}
public void testDeleteUser()
{
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
- assertTrue("Delete should return true to flag successful delete", _amqumMBean.deleteUser(TEST_USERNAME));
- assertEquals("Unexpected number of users after test", 0,_amqumMBean.viewUsers().size());
- }
-
- public void testDeleteUserWhereUserDoesNotExist()
- {
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
- assertFalse("Delete should return false to flag unsuccessful delete", _amqumMBean.deleteUser("made.up.username"));
- assertEquals("Unexpected number of users after test", 1,_amqumMBean.viewUsers().size());
+ loadFreshTestPasswordFile();
+ loadFreshTestAccessFile();
+ //try deleting a non existant user
+ assertFalse(_amqumMBean.deleteUser("made.up.username"));
+
+ assertTrue(_amqumMBean.deleteUser(TEST_USERNAME));
}
- public void testCreateUser()
+ public void testDeleteUserIsSavedToAccessFile()
{
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
- assertTrue("Create should return true to flag successful create", _amqumMBean.createUser("newuser", "mypass"));
- assertEquals("Unexpected number of users before test", 2,_amqumMBean.viewUsers().size());
- }
+ loadFreshTestPasswordFile();
+ loadFreshTestAccessFile();
- public void testCreateUserWhereUserAlreadyExists()
- {
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
- assertFalse("Create should return false to flag unsuccessful create", _amqumMBean.createUser(TEST_USERNAME, "mypass"));
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
+ assertTrue(_amqumMBean.deleteUser(TEST_USERNAME));
+
+ //check the access rights were actually deleted from the file
+ try{
+ BufferedReader reader = new BufferedReader(new FileReader(_accessFile));
+
+ //check the 'generated by' comment line is present
+ assertTrue("File has no content", reader.ready());
+ assertTrue("'Generated by' comment line was missing",reader.readLine().contains("Generated by " +
+ "AMQUserManagementMBean Console : Last edited by user:"));
+
+ //there should also be a modified date/time comment line
+ assertTrue("File has no modified date/time comment line", reader.ready());
+ assertTrue("Modification date/time comment line was missing",reader.readLine().startsWith("#"));
+
+ //the access file should not contain any further data now as we just deleted the only user
+ assertFalse("User access data was present when it should have been deleted", reader.ready());
+ }
+ catch (IOException e)
+ {
+ fail("Unable to valdate file contents due to:" + e.getMessage());
+ }
+
}
- public void testSetPassword()
+ public void testSetRights()
{
- assertTrue("Set password should return true to flag successful change", _amqumMBean.setPassword(TEST_USERNAME, "newpassword"));
+ loadFreshTestPasswordFile();
+ loadFreshTestAccessFile();
+
+ assertFalse(_amqumMBean.setRights("made.up.username", true, false, false));
+
+ assertTrue(_amqumMBean.setRights(TEST_USERNAME, true, false, false));
+ assertTrue(_amqumMBean.setRights(TEST_USERNAME, false, true, false));
+ assertTrue(_amqumMBean.setRights(TEST_USERNAME, false, false, true));
}
- public void testSetPasswordWhereUserDoesNotExist()
+ public void testSetRightsIsSavedToAccessFile()
{
- assertFalse("Set password should return false to flag successful change", _amqumMBean.setPassword("made.up.username", "newpassword"));
+ loadFreshTestPasswordFile();
+ loadFreshTestAccessFile();
+
+ assertTrue(_amqumMBean.setRights(TEST_USERNAME, false, false, true));
+
+ //check the access rights were actually updated in the file
+ try{
+ BufferedReader reader = new BufferedReader(new FileReader(_accessFile));
+
+ //check the 'generated by' comment line is present
+ assertTrue("File has no content", reader.ready());
+ assertTrue("'Generated by' comment line was missing",reader.readLine().contains("Generated by " +
+ "AMQUserManagementMBean Console : Last edited by user:"));
+
+ //there should also be a modified date/time comment line
+ assertTrue("File has no modified date/time comment line", reader.ready());
+ assertTrue("Modification date/time comment line was missing",reader.readLine().startsWith("#"));
+
+ //the access file should not contain any further data now as we just deleted the only user
+ assertTrue("User access data was not updated in the access file",
+ reader.readLine().equals(TEST_USERNAME + "=" + MBeanInvocationHandlerImpl.ADMIN));
+
+ //the access file should not contain any further data now as we just deleted the only user
+ assertFalse("Additional user access data was present when there should be no more", reader.ready());
+ }
+ catch (IOException e)
+ {
+ fail("Unable to valdate file contents due to:" + e.getMessage());
+ }
}
- public void testViewUsers()
+ public void testSetAccessFileWithMissingFile()
{
- TabularData userList = _amqumMBean.viewUsers();
+ try
+ {
+ _amqumMBean.setAccessFile("made.up.filename");
+ }
+ catch (IOException e)
+ {
+ fail("Should not have been an IOE." + e.getMessage());
+ }
+ catch (ConfigurationException e)
+ {
+ assertTrue(e.getMessage(), e.getMessage().endsWith("does not exist"));
+ }
+ }
- assertNotNull(userList);
- assertEquals("Unexpected number of users in user list", 1, userList.size());
- assertTrue(userList.containsKey(new Object[]{TEST_USERNAME}));
-
- // Check the deprecated read, write and admin items continue to exist but return false.
- CompositeData userRec = userList.get(new Object[]{TEST_USERNAME});
- assertTrue(userRec.containsKey(UserManagement.RIGHTS_READ_ONLY));
- assertEquals(false, userRec.get(UserManagement.RIGHTS_READ_ONLY));
- assertEquals(false, userRec.get(UserManagement.RIGHTS_READ_WRITE));
- assertTrue(userRec.containsKey(UserManagement.RIGHTS_READ_WRITE));
- assertTrue(userRec.containsKey(UserManagement.RIGHTS_ADMIN));
- assertEquals(false, userRec.get(UserManagement.RIGHTS_ADMIN));
+ public void testSetAccessFileWithReadOnlyFile()
+ {
+ File testFile = null;
+ try
+ {
+ testFile = File.createTempFile(this.getClass().getName(),".access.readonly");
+ BufferedWriter passwordWriter = new BufferedWriter(new FileWriter(testFile, false));
+ passwordWriter.write(TEST_USERNAME + ":" + TEST_PASSWORD);
+ passwordWriter.newLine();
+ passwordWriter.flush();
+ passwordWriter.close();
+
+ testFile.setReadOnly();
+ _amqumMBean.setAccessFile(testFile.getPath());
+ }
+ catch (IOException e)
+ {
+ fail("Access file was not created." + e.getMessage());
+ }
+ catch (ConfigurationException e)
+ {
+ fail("There should not have been a configuration exception." + e.getMessage());
+ }
+
+ testFile.delete();
}
// ============================ Utility methods =========================
@@ -154,4 +227,37 @@ public class AMQUserManagementMBeanTest extends InternalBrokerBaseCase
fail("Unable to create test password file: " + e.getMessage());
}
}
+
+ private void loadFreshTestAccessFile()
+ {
+ try
+ {
+ if(_accessFile == null)
+ {
+ _accessFile = File.createTempFile(this.getClass().getName(),".access");
+ }
+
+ BufferedWriter accessWriter = new BufferedWriter(new FileWriter(_accessFile,false));
+ accessWriter.write("#Last Updated By comment");
+ accessWriter.newLine();
+ accessWriter.write("#Date/time comment");
+ accessWriter.newLine();
+ accessWriter.write(TEST_USERNAME + "=" + MBeanInvocationHandlerImpl.READONLY);
+ accessWriter.newLine();
+ accessWriter.flush();
+ accessWriter.close();
+ }
+ catch (IOException e)
+ {
+ fail("Unable to create test access file: " + e.getMessage());
+ }
+
+ try{
+ _amqumMBean.setAccessFile(_accessFile.toString());
+ }
+ catch (Exception e)
+ {
+ fail("Unable to set access file: " + e.getMessage());
+ }
+ }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java
index 3af665141c..3b6cd37ea9 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java
@@ -21,31 +21,23 @@
package org.apache.qpid.server.protocol;
import java.security.Principal;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
-import javax.security.auth.Subject;
-
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
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.output.ProtocolOutputConverter;
+import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.queue.QueueEntry;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.TestNetworkConnection;
+import org.apache.qpid.server.message.MessageContentSource;
+import org.apache.qpid.transport.TestNetworkDriver;
public class InternalTestProtocolSession extends AMQProtocolEngine implements ProtocolOutputConverter
{
@@ -55,13 +47,18 @@ public class InternalTestProtocolSession extends AMQProtocolEngine implements Pr
public InternalTestProtocolSession(VirtualHost virtualHost) throws AMQException
{
- super(ApplicationRegistry.getInstance().getVirtualHostRegistry(), new TestNetworkConnection());
+ super(ApplicationRegistry.getInstance().getVirtualHostRegistry(), new TestNetworkDriver());
_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));
+ setAuthorizedID(new Principal()
+ {
+ public String getName()
+ {
+ return "InternalTestProtocolSession";
+ }
+ });
setVirtualHost(virtualHost);
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java
index 3961b3b355..d52f4c03f3 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java
@@ -96,7 +96,7 @@ public class AMQPriorityQueueTest extends SimpleAMQQueueTest
AMQMessage msg = super.createMessage(id);
BasicContentHeaderProperties props = new BasicContentHeaderProperties();
props.setPriority(i);
- msg.getContentHeaderBody().setProperties(props);
+ msg.getContentHeaderBody().properties = props;
return msg;
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
index a8bddcf6bf..0707cab3d5 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
@@ -277,7 +277,7 @@ public class AMQQueueAlertTest extends InternalBrokerBaseCase
ContentHeaderBody contentHeaderBody = new ContentHeaderBody();
BasicContentHeaderProperties props = new BasicContentHeaderProperties();
- contentHeaderBody.setProperties(props);
+ contentHeaderBody.properties = props;
contentHeaderBody.bodySize = size; // in bytes
IncomingMessage message = new IncomingMessage(publish);
message.setContentHeaderBody(contentHeaderBody);
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
index 365353e734..5b72cfac40 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
@@ -402,8 +402,8 @@ public class AMQQueueMBeanTest extends InternalBrokerBaseCase
ContentHeaderBody contentHeaderBody = new ContentHeaderBody();
contentHeaderBody.bodySize = MESSAGE_SIZE; // in bytes
- contentHeaderBody.setProperties(new BasicContentHeaderProperties());
- ((BasicContentHeaderProperties) contentHeaderBody.getProperties()).setDeliveryMode((byte) (persistent ? 2 : 1));
+ contentHeaderBody.properties = new BasicContentHeaderProperties();
+ ((BasicContentHeaderProperties) contentHeaderBody.properties).setDeliveryMode((byte) (persistent ? 2 : 1));
IncomingMessage msg = new IncomingMessage(publish);
msg.setContentHeaderBody(contentHeaderBody);
return msg;
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java
index 0f5374b3e5..04608275a3 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java
@@ -126,7 +126,7 @@ public class AckTest extends InternalBrokerBaseCase
//IncomingMessage msg2 = null;
BasicContentHeaderProperties b = new BasicContentHeaderProperties();
ContentHeaderBody cb = new ContentHeaderBody();
- cb.setProperties(b);
+ cb.properties = b;
if (persistent)
{
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java
index 4c31092983..888a16053c 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java
@@ -29,7 +29,7 @@ import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.security.AuthorizationHolder;
+import org.apache.qpid.server.security.PrincipalHolder;
import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.binding.Binding;
@@ -48,7 +48,7 @@ public class MockAMQQueue implements AMQQueue
private AMQShortString _name;
private VirtualHost _virtualhost;
- private AuthorizationHolder _authorizationHolder;
+ private PrincipalHolder _principalHolder;
private AMQSessionModel _exclusiveOwner;
private AMQShortString _owner;
@@ -536,14 +536,14 @@ public class MockAMQQueue implements AMQQueue
return null; //To change body of implemented methods use File | Settings | File Templates.
}
- public AuthorizationHolder getAuthorizationHolder()
+ public PrincipalHolder getPrincipalHolder()
{
- return _authorizationHolder;
+ return _principalHolder;
}
- public void setAuthorizationHolder(final AuthorizationHolder authorizationHolder)
+ public void setPrincipalHolder(PrincipalHolder principalHolder)
{
- _authorizationHolder = authorizationHolder;
+ _principalHolder = principalHolder;
}
public AMQSessionModel getExclusiveOwningSession()
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java
index a3f8f4c0d3..5bdbe2c68e 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java
@@ -231,14 +231,4 @@ public class MockQueueEntry implements QueueEntry
_message = msg;
}
- public boolean isDequeued()
- {
- return false;
- }
-
- public boolean isDispensed()
- {
- return false;
- }
-
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java
deleted file mode 100644
index 0899f25cc5..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.server.queue;
-
-import java.lang.reflect.Field;
-
-import junit.framework.TestCase;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.message.AMQMessage;
-import org.apache.qpid.server.queue.QueueEntry.EntryState;
-import org.apache.qpid.server.subscription.MockSubscription;
-
-/**
- * Tests for {@link QueueEntryImpl}
- *
- */
-public class QueueEntryImplTest extends TestCase
-{
- // tested entry
- private QueueEntryImpl _queueEntry;
-
- public void setUp() throws Exception
- {
- AMQMessage message = new MockAMQMessage(1);
- SimpleQueueEntryList queueEntryList = new SimpleQueueEntryList(new MockAMQQueue("test"));
- _queueEntry = new QueueEntryImpl(queueEntryList, message, 1);
- }
-
- public void testAquire()
- {
- assertTrue("Queue entry should be in AVAILABLE state before invoking of acquire method",
- _queueEntry.isAvailable());
- acquire();
- }
-
- public void testDequeue()
- {
- dequeue();
- }
-
- public void testDelete()
- {
- delete();
- }
-
- /**
- * Tests release method for entry in acquired state.
- * <p>
- * Entry in state ACQUIRED should be released and its status should be
- * changed to AVAILABLE.
- */
- public void testReleaseAquired()
- {
- acquire();
- _queueEntry.release();
- assertTrue("Queue entry should be in AVAILABLE state after invoking of release method",
- _queueEntry.isAvailable());
- }
-
- /**
- * Tests release method for entry in dequeued state.
- * <p>
- * Invoking release on dequeued entry should not have any effect on its
- * state.
- */
- public void testReleaseDequeued()
- {
- dequeue();
- _queueEntry.release();
- EntryState state = getState();
- assertEquals("Invoking of release on entry in DEQUEUED state should not have any effect",
- QueueEntry.DEQUEUED_STATE, state);
- }
-
- /**
- * Tests release method for entry in deleted state.
- * <p>
- * Invoking release on deleted entry should not have any effect on its
- * state.
- */
- public void testReleaseDeleted()
- {
- delete();
- _queueEntry.release();
- assertTrue("Invoking of release on entry in DELETED state should not have any effect",
- _queueEntry.isDeleted());
- }
-
- /**
- * Tests if entries in DEQUQUED or DELETED state are not returned by getNext method.
- */
- public void testGetNext()
- {
- int numberOfEntries = 5;
- QueueEntryImpl[] entries = new QueueEntryImpl[numberOfEntries];
- SimpleQueueEntryList queueEntryList = new SimpleQueueEntryList(new MockAMQQueue("test"));
-
- // create test entries
- for(int i = 0; i < numberOfEntries ; i++)
- {
- AMQMessage message = null;;
- try
- {
- message = new MockAMQMessage(i);
- }
- catch (AMQException e)
- {
- fail("Failure to create a mock message:" + e.getMessage());
- }
- QueueEntryImpl entry = (QueueEntryImpl)queueEntryList.add(message);
- entries[i] = entry;
- }
-
- // test getNext for not acquired entries
- for(int i = 0; i < numberOfEntries ; i++)
- {
- QueueEntryImpl queueEntry = entries[i];
- QueueEntryImpl next = queueEntry.getNext();
- if (i < numberOfEntries - 1)
- {
- assertEquals("Unexpected entry from QueueEntryImpl#getNext()", entries[i + 1], next);
- }
- else
- {
- assertNull("The next entry after the last should be null", next);
- }
- }
-
- // delete second
- entries[1].acquire();
- entries[1].delete();
-
- // dequeue third
- entries[2].acquire();
- entries[2].dequeue();
-
- QueueEntryImpl next = entries[0].getNext();
- assertEquals("expected forth entry",entries[3], next);
- next = next.getNext();
- assertEquals("expected fifth entry", entries[4], next);
- next = next.getNext();
- assertNull("The next entry after the last should be null", next);
- }
- /**
- * A helper method to put tested object into deleted state and assert the state
- */
- private void delete()
- {
- _queueEntry.delete();
- assertTrue("Queue entry should be in DELETED state after invoking of delete method",
- _queueEntry.isDeleted());
- }
-
- /**
- * A helper method to put tested entry into dequeue state and assert the sate
- */
- private void dequeue()
- {
- acquire();
- _queueEntry.dequeue();
- EntryState state = getState();
- assertEquals("Queue entry should be in DEQUEUED state after invoking of dequeue method",
- QueueEntry.DEQUEUED_STATE, state);
- }
-
- /**
- * A helper method to put tested entry into acquired state and assert the sate
- */
- private void acquire()
- {
- _queueEntry.acquire(new MockSubscription());
- assertTrue("Queue entry should be in ACQUIRED state after invoking of acquire method",
- _queueEntry.isAcquired());
- }
-
- /**
- * A helper method to get entry state
- *
- * @return entry state
- */
- private EntryState getState()
- {
- EntryState state = null;
- try
- {
- Field f = QueueEntryImpl.class.getDeclaredField("_state");
- f.setAccessible(true);
- state = (EntryState) f.get(_queueEntry);
- }
- catch (Exception e)
- {
- fail("Failure to get a state field: " + e.getMessage());
- }
- return state;
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
index 0e136c523f..67d093d00a 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
@@ -36,16 +36,13 @@ 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;
-import org.apache.qpid.server.message.ServerMessage;
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.LocalTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.util.InternalBrokerBaseCase;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -54,8 +51,6 @@ import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
public class SimpleAMQQueueTest extends InternalBrokerBaseCase
{
@@ -232,10 +227,10 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
}
/**
- * Tests that a released queue entry is resent to the subscriber. Verifies also that the
+ * Tests that a re-queued message is resent to the subscriber. Verifies also that the
* QueueContext._releasedEntry is reset to null after the entry has been reset.
*/
- public void testReleasedMessageIsResentToSubscriber() throws Exception
+ public void testRequeuedMessageIsResentToSubscriber() throws Exception
{
_queue.registerSubscription(_subscription, false);
@@ -258,18 +253,19 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
_queue.enqueue(messageB, postEnqueueAction);
_queue.enqueue(messageC, postEnqueueAction);
- Thread.sleep(150); // Work done by SubFlushRunner/QueueRunner Threads
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
assertEquals("Unexpected total number of messages sent to subscription", 3, _subscription.getMessages().size());
assertFalse("Redelivery flag should not be set", queueEntries.get(0).isRedelivered());
assertFalse("Redelivery flag should not be set", queueEntries.get(1).isRedelivered());
assertFalse("Redelivery flag should not be set", queueEntries.get(2).isRedelivered());
- /* Now release the first message only, causing it to be requeued */
+ /* Now requeue the first message only */
queueEntries.get(0).release();
+ _queue.requeue(queueEntries.get(0));
- Thread.sleep(150); // Work done by SubFlushRunner/QueueRunner Threads
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
assertEquals("Unexpected total number of messages sent to subscription", 4, _subscription.getMessages().size());
assertTrue("Redelivery flag should now be set", queueEntries.get(0).isRedelivered());
@@ -279,11 +275,11 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
}
/**
- * Tests that a released message that becomes expired is not resent to the subscriber.
+ * Tests that a re-queued message that becomes expired is not resent to the subscriber.
* This tests ensures that SimpleAMQQueueEntry.getNextAvailableEntry avoids expired entries.
* Verifies also that the QueueContext._releasedEntry is reset to null after the entry has been reset.
*/
- public void testReleaseMessageThatBecomesExpiredIsNotRedelivered() throws Exception
+ public void testRequeuedMessageThatBecomesExpiredIsNotRedelivered() throws Exception
{
_queue.registerSubscription(_subscription, false);
@@ -305,16 +301,17 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
_queue.enqueue(messageA, postEnqueueAction);
int subFlushWaitTime = 150;
- Thread.sleep(subFlushWaitTime); // Work done by SubFlushRunner/QueueRunner Threads
+ Thread.sleep(subFlushWaitTime); // Work done by SubFlushRunner Thread
assertEquals("Unexpected total number of messages sent to subscription", 1, _subscription.getMessages().size());
assertFalse("Redelivery flag should not be set", queueEntries.get(0).isRedelivered());
- /* Wait a little more to be sure that message will have expired, then release the first message only, causing it to be requeued */
+ /* Wait a little more to be sure that message will have expired, then requeue it */
Thread.sleep(messageExpirationOffset - subFlushWaitTime + 10);
queueEntries.get(0).release();
+ _queue.requeue(queueEntries.get(0));
- Thread.sleep(subFlushWaitTime); // Work done by SubFlushRunner/QueueRunner Threads
+ Thread.sleep(subFlushWaitTime); // Work done by SubFlushRunner Thread
assertTrue("Expecting the queue entry to be now expired", queueEntries.get(0).expired());
assertEquals("Total number of messages sent should not have changed", 1, _subscription.getMessages().size());
@@ -324,12 +321,12 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
}
/**
- * Tests that if a client releases entries 'out of order' (the order
+ * Tests that if a client requeues messages 'out of order' (the order
* used by QueueEntryImpl.compareTo) that messages are still resent
* successfully. Specifically this test ensures the {@see SimpleAMQQueue#requeue()}
* can correctly move the _releasedEntry to an earlier position in the QueueEntry list.
*/
- public void testReleasedOutOfComparableOrderAreRedelivered() throws Exception
+ public void testMessagesRequeuedOutOfComparableOrderAreDelivered() throws Exception
{
_queue.registerSubscription(_subscription, false);
@@ -352,19 +349,21 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
_queue.enqueue(messageB, postEnqueueAction);
_queue.enqueue(messageC, postEnqueueAction);
- Thread.sleep(150); // Work done by SubFlushRunner/QueueRunner Threads
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
assertEquals("Unexpected total number of messages sent to subscription", 3, _subscription.getMessages().size());
assertFalse("Redelivery flag should not be set", queueEntries.get(0).isRedelivered());
assertFalse("Redelivery flag should not be set", queueEntries.get(1).isRedelivered());
assertFalse("Redelivery flag should not be set", queueEntries.get(2).isRedelivered());
- /* Now release the third and first message only, causing it to be requeued */
+ /* Now requeue the third and first message only */
queueEntries.get(2).release();
queueEntries.get(0).release();
+ _queue.requeue(queueEntries.get(2));
+ _queue.requeue(queueEntries.get(0));
- Thread.sleep(150); // Work done by SubFlushRunner/QueueRunner Threads
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
assertEquals("Unexpected total number of messages sent to subscription", 5, _subscription.getMessages().size());
assertTrue("Redelivery flag should now be set", queueEntries.get(0).isRedelivered());
@@ -375,10 +374,10 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
/**
- * Tests that a release requeues an entry for a queue with multiple subscriptions. Verifies that a
+ * Tests a requeue for a queue with multiple subscriptions. Verifies that a
* requeue resends a message to a <i>single</i> subscriber.
*/
- public void testReleaseForQueueWithMultipleSubscriptions() throws Exception
+ public void testRequeueForQueueWithMultipleSubscriptions() throws Exception
{
MockSubscription subscription1 = new MockSubscription();
MockSubscription subscription2 = new MockSubscription();
@@ -403,16 +402,66 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
_queue.enqueue(messageA, postEnqueueAction);
_queue.enqueue(messageB, postEnqueueAction);
- Thread.sleep(150); // Work done by SubFlushRunner/QueueRunner Threads
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
- assertEquals("Unexpected total number of messages sent to both after enqueue", 2, subscription1.getMessages().size() + subscription2.getMessages().size());
+ assertEquals("Unexpected total number of messages sent to subscription1 after enqueue", 1, subscription1.getMessages().size());
+ assertEquals("Unexpected total number of messages sent to subscription2 after enqueue", 1, subscription2.getMessages().size());
- /* Now release the first message only, causing it to be requeued */
- queueEntries.get(0).release();
+ /* Now requeue a message (for any subscription) */
- Thread.sleep(150); // Work done by SubFlushRunner/QueueRunner Threads
+ queueEntries.get(0).release();
+ _queue.requeue((QueueEntryImpl)queueEntries.get(0));
+
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
- assertEquals("Unexpected total number of messages sent to both subscriptions after release", 3, subscription1.getMessages().size() + subscription2.getMessages().size());
+ assertEquals("Unexpected total number of messages sent to all subscriptions after requeue", 3, subscription1.getMessages().size() + subscription2.getMessages().size());
+ assertNull("releasedEntry should be cleared after requeue processed", ((QueueContext)subscription1.getQueueContext())._releasedEntry);
+ assertNull("releasedEntry should be cleared after requeue processed", ((QueueContext)subscription2.getQueueContext())._releasedEntry);
+ }
+
+ /**
+ * Tests a requeue for a queue with multiple subscriptions. Verifies that a
+ * subscriber specific requeue resends the message to <i>that</i> subscriber.
+ */
+ public void testSubscriptionSpecificRequeueForQueueWithMultipleSubscriptions() throws Exception
+ {
+ MockSubscription subscription1 = new MockSubscription();
+ MockSubscription subscription2 = new MockSubscription();
+
+ _queue.registerSubscription(subscription1, false);
+ _queue.registerSubscription(subscription2, false);
+
+ final ArrayList<QueueEntry> queueEntries = new ArrayList<QueueEntry>();
+ PostEnqueueAction postEnqueueAction = new PostEnqueueAction()
+ {
+ public void onEnqueue(QueueEntry entry)
+ {
+ queueEntries.add(entry);
+ }
+ };
+
+ AMQMessage messageA = createMessage(new Long(24));
+ AMQMessage messageB = createMessage(new Long(25));
+
+ /* Enqueue two messages */
+
+ _queue.enqueue(messageA, postEnqueueAction);
+ _queue.enqueue(messageB, postEnqueueAction);
+
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
+
+ assertEquals("Unexpected total number of messages sent to subscription1 after enqueue", 1, subscription1.getMessages().size());
+ assertEquals("Unexpected total number of messages sent to subscription2 after enqueue", 1, subscription2.getMessages().size());
+
+ /* Now requeue a message (for first subscription) */
+
+ queueEntries.get(0).release();
+ _queue.requeue((QueueEntryImpl)queueEntries.get(0), subscription1);
+
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
+
+ assertEquals("Unexpected total number of messages sent to subscription1 after requeue", 2, subscription1.getMessages().size());
+ assertEquals("Unexpected total number of messages sent to subscription2 after requeue", 1, subscription2.getMessages().size());
assertNull("releasedEntry should be cleared after requeue processed", ((QueueContext)subscription1.getQueueContext())._releasedEntry);
assertNull("releasedEntry should be cleared after requeue processed", ((QueueContext)subscription2.getQueueContext())._releasedEntry);
}
@@ -611,8 +660,8 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
// Create IncomingMessage and nondurable queue
final IncomingMessage msg = new IncomingMessage(info);
ContentHeaderBody contentHeaderBody = new ContentHeaderBody();
- contentHeaderBody.setProperties(new BasicContentHeaderProperties());
- ((BasicContentHeaderProperties) contentHeaderBody.getProperties()).setDeliveryMode((byte) 2);
+ contentHeaderBody.properties = new BasicContentHeaderProperties();
+ ((BasicContentHeaderProperties) contentHeaderBody.properties).setDeliveryMode((byte) 2);
msg.setContentHeaderBody(contentHeaderBody);
final ArrayList<BaseQueue> qs = new ArrayList<BaseQueue>();
@@ -658,635 +707,6 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
}
- /**
- * processQueue() is used when asynchronously delivering messages to
- * subscriptions which could not be delivered immediately during the
- * enqueue() operation.
- *
- * A defect within the method would mean that delivery of these messages may
- * not occur should the Runner stop before all messages have been processed.
- * Such a defect was discovered when Selectors were used such that one and
- * only one subscription can/will accept any given messages, but multiple
- * subscriptions are present, and one of the earlier subscriptions receives
- * more messages than the others.
- *
- * This test is to validate that the processQueue() method is able to
- * correctly deliver all of the messages present for asynchronous delivery
- * to subscriptions in such a scenario.
- */
- public void testProcessQueueWithUniqueSelectors() throws Exception
- {
- TestSimpleQueueEntryListFactory factory = new TestSimpleQueueEntryListFactory();
- SimpleAMQQueue testQueue = new SimpleAMQQueue("testQueue", false, "testOwner",false,
- false, _virtualHost, factory, null)
- {
- @Override
- public void deliverAsync(Subscription sub)
- {
- // do nothing, i.e prevent deliveries by the SubFlushRunner
- // when registering the new subscriptions
- }
- };
-
- // retrieve the QueueEntryList the queue creates and insert the test
- // messages, thus avoiding straight-through delivery attempts during
- //enqueue() process.
- QueueEntryList list = factory.getQueueEntryList();
- assertNotNull("QueueEntryList should have been created", list);
-
- QueueEntry msg1 = list.add(createMessage(1L));
- QueueEntry msg2 = list.add(createMessage(2L));
- QueueEntry msg3 = list.add(createMessage(3L));
- QueueEntry msg4 = list.add(createMessage(4L));
- QueueEntry msg5 = list.add(createMessage(5L));
-
- // Create lists of the entries each subscription should be interested
- // in.Bias over 50% of the messages to the first subscription so that
- // the later subscriptions reject them and report being done before
- // the first subscription as the processQueue method proceeds.
- List<QueueEntry> msgListSub1 = createEntriesList(msg1, msg2, msg3);
- List<QueueEntry> msgListSub2 = createEntriesList(msg4);
- List<QueueEntry> msgListSub3 = createEntriesList(msg5);
-
- MockSubscription sub1 = new MockSubscription(msgListSub1);
- MockSubscription sub2 = new MockSubscription(msgListSub2);
- MockSubscription sub3 = new MockSubscription(msgListSub3);
-
- // register the subscriptions
- testQueue.registerSubscription(sub1, false);
- testQueue.registerSubscription(sub2, false);
- testQueue.registerSubscription(sub3, false);
-
- //check that no messages have been delivered to the
- //subscriptions during registration
- assertEquals("No messages should have been delivered yet", 0, sub1.getMessages().size());
- assertEquals("No messages should have been delivered yet", 0, sub2.getMessages().size());
- assertEquals("No messages should have been delivered yet", 0, sub3.getMessages().size());
-
- // call processQueue to deliver the messages
- testQueue.processQueue(new QueueRunner(testQueue, 1)
- {
- @Override
- public void run()
- {
- // we dont actually want/need this runner to do any work
- // because we we are already doing it!
- }
- });
-
- // check expected messages delivered to correct consumers
- verifyRecievedMessages(msgListSub1, sub1.getMessages());
- verifyRecievedMessages(msgListSub2, sub2.getMessages());
- verifyRecievedMessages(msgListSub3, sub3.getMessages());
- }
-
- /**
- * Tests that dequeued message is not present in the list returned form
- * {@link SimpleAMQQueue#getMessagesOnTheQueue()}
- */
- public void testGetMessagesOnTheQueueWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
-
- // send test messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // get messages on the queue
- List<QueueEntry> entries = _queue.getMessagesOnTheQueue();
-
- // assert queue entries
- assertEquals(messageNumber - 1, entries.size());
- int expectedId = 0;
- for (int i = 0; i < messageNumber - 1; i++)
- {
- Long id = ((AMQMessage) entries.get(i).getMessage()).getMessageId();
- if (i == dequeueMessageIndex)
- {
- assertFalse("Message with id " + dequeueMessageIndex
- + " was dequeued and should not be returned by method getMessagesOnTheQueue!",
- new Long(expectedId).equals(id));
- expectedId++;
- }
- assertEquals("Expected message with id " + expectedId + " but got message with id " + id,
- new Long(expectedId), id);
- expectedId++;
- }
- }
-
- /**
- * Tests that dequeued message is not present in the list returned form
- * {@link SimpleAMQQueue#getMessagesOnTheQueue(QueueEntryFilter)}
- */
- public void testGetMessagesOnTheQueueByQueueEntryFilterWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
-
- // send test messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // get messages on the queue with filter accepting all available messages
- List<QueueEntry> entries = _queue.getMessagesOnTheQueue(new QueueEntryFilter()
- {
- public boolean accept(QueueEntry entry)
- {
- return true;
- }
-
- public boolean filterComplete()
- {
- return false;
- }
- });
-
- // assert entries on the queue
- assertEquals(messageNumber - 1, entries.size());
- int expectedId = 0;
- for (int i = 0; i < messageNumber - 1; i++)
- {
- Long id = ((AMQMessage) entries.get(i).getMessage()).getMessageId();
- if (i == dequeueMessageIndex)
- {
- assertFalse("Message with id " + dequeueMessageIndex
- + " was dequeued and should not be returned by method getMessagesOnTheQueue!",
- new Long(expectedId).equals(id));
- expectedId++;
- }
- assertEquals("Expected message with id " + expectedId + " but got message with id " + id,
- new Long(expectedId), id);
- expectedId++;
- }
- }
-
- /**
- * Tests that dequeued message is not copied as part of invocation of
- * {@link SimpleAMQQueue#copyMessagesToAnotherQueue(long, long, String, StoreContext)}
- */
- public void testCopyMessagesWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
- String anotherQueueName = "testQueue2";
-
- // put test messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // create another queue
- SimpleAMQQueue queue = createQueue(anotherQueueName);
-
- // create transaction
- ServerTransaction txn = new LocalTransaction(_queue.getVirtualHost().getTransactionLog());
-
- // copy messages into another queue
- _queue.copyMessagesToAnotherQueue(0, messageNumber, anotherQueueName, txn);
-
- // commit transaction
- txn.commit();
-
- // get messages on another queue
- List<QueueEntry> entries = queue.getMessagesOnTheQueue();
-
- // assert another queue entries
- assertEquals(messageNumber - 1, entries.size());
- int expectedId = 0;
- for (int i = 0; i < messageNumber - 1; i++)
- {
- Long id = ((AMQMessage)entries.get(i).getMessage()).getMessageId();
- if (i == dequeueMessageIndex)
- {
- assertFalse("Message with id " + dequeueMessageIndex
- + " was dequeued and should not been copied into another queue!",
- new Long(expectedId).equals(id));
- expectedId++;
- }
- assertEquals("Expected message with id " + expectedId + " but got message with id " + id,
- new Long(expectedId), id);
- expectedId++;
- }
- }
-
- /**
- * Tests that dequeued message is not moved as part of invocation of
- * {@link SimpleAMQQueue#moveMessagesToAnotherQueue(long, long, String, StoreContext)}
- */
- public void testMovedMessagesWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
- String anotherQueueName = "testQueue2";
-
- // put messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // create another queue
- SimpleAMQQueue queue = createQueue(anotherQueueName);
-
- // create transaction
- ServerTransaction txn = new LocalTransaction(_queue.getVirtualHost().getTransactionLog());
-
- // move messages into another queue
- _queue.moveMessagesToAnotherQueue(0, messageNumber, anotherQueueName, txn);
-
- // commit transaction
- txn.commit();
-
- // get messages on another queue
- List<QueueEntry> entries = queue.getMessagesOnTheQueue();
-
- // assert another queue entries
- assertEquals(messageNumber - 1, entries.size());
- int expectedId = 0;
- for (int i = 0; i < messageNumber - 1; i++)
- {
- Long id = ((AMQMessage)entries.get(i).getMessage()).getMessageId();
- if (i == dequeueMessageIndex)
- {
- assertFalse("Message with id " + dequeueMessageIndex
- + " was dequeued and should not been copied into another queue!",
- new Long(expectedId).equals(id));
- expectedId++;
- }
- assertEquals("Expected message with id " + expectedId + " but got message with id " + id,
- new Long(expectedId), id);
- expectedId++;
- }
- }
-
- /**
- * Tests that messages in given range including dequeued one are deleted
- * from the queue on invocation of
- * {@link SimpleAMQQueue#removeMessagesFromQueue(long, long, StoreContext)}
- */
- public void testRemoveMessagesFromQueueWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
-
- // put messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // remove messages
- _queue.removeMessagesFromQueue(0, messageNumber);
-
- // get queue entries
- List<QueueEntry> entries = _queue.getMessagesOnTheQueue();
-
- // assert queue entries
- assertNotNull("Null is returned from getMessagesOnTheQueue", entries);
- assertEquals("Queue should be empty", 0, entries.size());
- }
-
- /**
- * Tests that dequeued message on the top is not accounted and next message
- * is deleted from the queue on invocation of
- * {@link SimpleAMQQueue#deleteMessageFromTop(StoreContext)}
- */
- public void testDeleteMessageFromTopWithDequeuedEntryOnTop()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 0;
-
- // put messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message on top
- dequeueMessage(_queue, dequeueMessageIndex);
-
- //delete message from top
- _queue.deleteMessageFromTop();
-
- //get queue netries
- List<QueueEntry> entries = _queue.getMessagesOnTheQueue();
-
- // assert queue entries
- assertNotNull("Null is returned from getMessagesOnTheQueue", entries);
- assertEquals("Expected " + (messageNumber - 2) + " number of messages but recieved " + entries.size(),
- messageNumber - 2, entries.size());
- assertEquals("Expected first entry with id 2", new Long(2),
- ((AMQMessage) entries.get(0).getMessage()).getMessageId());
- }
-
- /**
- * Tests that all messages including dequeued one are deleted from the queue
- * on invocation of {@link SimpleAMQQueue#clearQueue(StoreContext)}
- */
- public void testClearQueueWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
-
- // put messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message on a test queue
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // clean queue
- try
- {
- _queue.clearQueue();
- }
- catch (AMQException e)
- {
- fail("Failure to clear queue:" + e.getMessage());
- }
-
- // get queue entries
- List<QueueEntry> entries = _queue.getMessagesOnTheQueue();
-
- // assert queue entries
- assertNotNull(entries);
- assertEquals(0, entries.size());
- }
-
- /**
- * Tests whether dequeued entry is sent to subscriber in result of
- * invocation of {@link SimpleAMQQueue#processQueue(QueueRunner)}
- */
- public void testProcessQueueWithDequeuedEntry()
- {
- // total number of messages to send
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
-
- // create queue with overridden method deliverAsync
- SimpleAMQQueue testQueue = new SimpleAMQQueue(new AMQShortString("test"), false,
- new AMQShortString("testOwner"), false, false, _virtualHost, null)
- {
- @Override
- public void deliverAsync(Subscription sub)
- {
- // do nothing
- }
- };
-
- // put messages
- List<QueueEntry> entries = enqueueGivenNumberOfMessages(testQueue, messageNumber);
-
- // dequeue message
- dequeueMessage(testQueue, dequeueMessageIndex);
-
- // latch to wait for message receipt
- final CountDownLatch latch = new CountDownLatch(messageNumber -1);
-
- // create a subscription
- MockSubscription subscription = new MockSubscription()
- {
- /**
- * Send a message and decrement latch
- */
- public void send(QueueEntry msg) throws AMQException
- {
- super.send(msg);
- latch.countDown();
- }
- };
-
- try
- {
- // subscribe
- testQueue.registerSubscription(subscription, false);
-
- // process queue
- testQueue.processQueue(new QueueRunner(testQueue, 1)
- {
- public void run()
- {
- // do nothing
- }
- });
- }
- catch (AMQException e)
- {
- fail("Failure to process queue:" + e.getMessage());
- }
- // wait up to 1 minute for message receipt
- try
- {
- latch.await(1, TimeUnit.MINUTES);
- }
- catch (InterruptedException e1)
- {
- Thread.currentThread().interrupt();
- }
- List<QueueEntry> expected = createEntriesList(entries.get(0), entries.get(2), entries.get(3));
- verifyRecievedMessages(expected, subscription.getMessages());
- }
-
- /**
- * Tests that entry in dequeued state are not enqueued and not delivered to subscription
- */
- public void testEqueueDequeuedEntry()
- {
- // create a queue where each even entry is considered a dequeued
- SimpleAMQQueue queue = new SimpleAMQQueue(new AMQShortString("test"), false, new AMQShortString("testOwner"),
- false, false, _virtualHost, new QueueEntryListFactory()
- {
- public QueueEntryList createQueueEntryList(AMQQueue queue)
- {
- /**
- * Override SimpleQueueEntryList to create a dequeued
- * entries for messages with even id
- */
- return new SimpleQueueEntryList(queue)
- {
- /**
- * Entries with even message id are considered
- * dequeued!
- */
- protected QueueEntryImpl createQueueEntry(final ServerMessage message)
- {
- return new QueueEntryImpl(this, message)
- {
- public boolean isDequeued()
- {
- return (((AMQMessage) message).getMessageId().longValue() % 2 == 0);
- }
-
- public boolean isDispensed()
- {
- return (((AMQMessage) message).getMessageId().longValue() % 2 == 0);
- }
-
- public boolean isAvailable()
- {
- return !(((AMQMessage) message).getMessageId().longValue() % 2 == 0);
- }
- };
- }
- };
- }
- }, null);
- // create a subscription
- MockSubscription subscription = new MockSubscription();
-
- // register subscription
- try
- {
- queue.registerSubscription(subscription, false);
- }
- catch (AMQException e)
- {
- fail("Failure to register subscription:" + e.getMessage());
- }
-
- // put test messages into a queue
- putGivenNumberOfMessages(queue, 4);
-
- // assert received messages
- List<QueueEntry> messages = subscription.getMessages();
- assertEquals("Only 2 messages should be returned", 2, messages.size());
- assertEquals("ID of first message should be 1", new Long(1),
- ((AMQMessage) messages.get(0).getMessage()).getMessageId());
- assertEquals("ID of second message should be 3", new Long(3),
- ((AMQMessage) messages.get(1).getMessage()).getMessageId());
- }
-
- /**
- * A helper method to create a queue with given name
- *
- * @param name
- * queue name
- * @return queue
- */
- private SimpleAMQQueue createQueue(String name)
- {
- SimpleAMQQueue queue = null;
- try
- {
- AMQShortString queueName = new AMQShortString(name);
- AMQShortString ownerName = new AMQShortString(name + "Owner");
- queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(queueName, false, ownerName, false, false,
- _virtualHost, _arguments);
- }
- catch (AMQException e)
- {
- fail("Failure to create a queue:" + e.getMessage());
- }
- assertNotNull("Queue was not created", queue);
- return queue;
- }
-
- /**
- * A helper method to put given number of messages into queue
- * <p>
- * All messages are asserted that they are present on queue
- *
- * @param queue
- * queue to put messages into
- * @param messageNumber
- * number of messages to put into queue
- */
- private List<QueueEntry> enqueueGivenNumberOfMessages(AMQQueue queue, int messageNumber)
- {
- putGivenNumberOfMessages(queue, messageNumber);
-
- // make sure that all enqueued messages are on the queue
- List<QueueEntry> entries = queue.getMessagesOnTheQueue();
- assertEquals(messageNumber, entries.size());
- for (int i = 0; i < messageNumber; i++)
- {
- assertEquals(new Long(i), ((AMQMessage)entries.get(i).getMessage()).getMessageId());
- }
- return entries;
- }
-
- /**
- * A helper method to put given number of messages into queue
- * <p>
- * Queue is not checked if messages are added into queue
- *
- * @param queue
- * queue to put messages into
- * @param messageNumber
- * number of messages to put into queue
- * @param queue
- * @param messageNumber
- */
- private void putGivenNumberOfMessages(AMQQueue queue, int messageNumber)
- {
- for (int i = 0; i < messageNumber; i++)
- {
- // Create message
- Long messageId = new Long(i);
- AMQMessage message = null;
- try
- {
- message = createMessage(messageId);
- }
- catch (AMQException e)
- {
- fail("Failure to create a test message:" + e.getMessage());
- }
- // Put message on queue
- try
- {
- queue.enqueue(message);
- }
- catch (AMQException e)
- {
- fail("Failure to put message on queue:" + e.getMessage());
- }
- }
- }
-
- /**
- * A helper method to dequeue an entry on queue with given index
- *
- * @param queue
- * queue to dequeue message on
- * @param dequeueMessageIndex
- * entry index to dequeue.
- */
- private QueueEntry dequeueMessage(AMQQueue queue, int dequeueMessageIndex)
- {
- List<QueueEntry> entries = queue.getMessagesOnTheQueue();
- QueueEntry entry = entries.get(dequeueMessageIndex);
- entry.acquire();
- entry.dequeue();
- assertTrue(entry.isDequeued());
- return entry;
- }
-
- private List<QueueEntry> createEntriesList(QueueEntry... entries)
- {
- ArrayList<QueueEntry> entriesList = new ArrayList<QueueEntry>();
- for (QueueEntry entry : entries)
- {
- entriesList.add(entry);
- }
- return entriesList;
- }
-
- private void verifyRecievedMessages(List<QueueEntry> expected,
- List<QueueEntry> delivered)
- {
- assertEquals("Consumer did not receive the expected number of messages",
- expected.size(), delivered.size());
-
- for (QueueEntry msg : expected)
- {
- assertTrue("Consumer did not recieve msg: "
- + msg.getMessage().getMessageNumber(), delivered.contains(msg));
- }
- }
-
public class TestMessage extends AMQMessage
{
private final long _tag;
@@ -1327,20 +747,4 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
AMQMessage messageA = new TestMessage(id, id, info);
return messageA;
}
-
- class TestSimpleQueueEntryListFactory implements QueueEntryListFactory
- {
- QueueEntryList _list;
-
- public QueueEntryList createQueueEntryList(AMQQueue queue)
- {
- _list = new SimpleQueueEntryList(queue);
- return _list;
- }
-
- public QueueEntryList getQueueEntryList()
- {
- return _list;
- }
- }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java
index 7136f07ca5..320a75045a 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java
@@ -23,7 +23,6 @@ package org.apache.qpid.server.queue;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import org.apache.qpid.AMQException;
import org.apache.qpid.server.message.AMQMessage;
import junit.framework.TestCase;
@@ -156,55 +155,5 @@ public class SimpleQueueEntryListTest extends TestCase
assertEquals("Count should have been equal",count,remainingMessages.size());
}
-
- public void testDequedMessagedNotPresentInIterator()
- {
- int numberOfMessages = 10;
- SimpleQueueEntryList entryList = new SimpleQueueEntryList(new MockAMQQueue("test"));
- QueueEntry[] entries = new QueueEntry[numberOfMessages];
-
- for(int i = 0; i < numberOfMessages ; i++)
- {
- AMQMessage message = null;;
- try
- {
- message = new MockAMQMessage(i);
- }
- catch (AMQException e)
- {
- fail("Failure to create a mock message:" + e.getMessage());
- }
- QueueEntry entry = entryList.add(message);
- assertNotNull("QE should not be null", entry);
- entries[i]= entry;
- }
-
- // dequeue all even messages
- for (QueueEntry queueEntry : entries)
- {
- long i = ((AMQMessage)queueEntry.getMessage()).getMessageId().longValue();
- if (i%2 == 0)
- {
- queueEntry.acquire();
- queueEntry.dequeue();
- }
- }
-
- // iterate and check that dequeued messages are not returned by iterator
- QueueEntryIterator it = entryList.iterator();
- int counter = 0;
- int i = 1;
- while (it.advance())
- {
- QueueEntry entry = it.getNode();
- Long id = ((AMQMessage)entry.getMessage()).getMessageId();
- assertEquals("Expected message with id " + i + " but got message with id "
- + id, new Long(i), id);
- counter++;
- i += 2;
- }
- int expectedNumber = numberOfMessages / 2;
- assertEquals("Expected " + expectedNumber + " number of entries in iterator but got " + counter,
- expectedNumber, counter);
- }
+
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java
deleted file mode 100644
index b10442d7db..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java
+++ /dev/null
@@ -1,358 +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.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.auth.Subject;
-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.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;
-
-/**
- *
- * Tests the public methods of PrincipalDatabaseAuthenticationManager.
- *
- */
-public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBaseCase
-{
- private AuthenticationManager _manager = null; // Class under test
- private String TEST_USERNAME = "guest";
- private String TEST_PASSWORD = "guest";
-
- /**
- * @see org.apache.qpid.server.util.InternalBrokerBaseCase#tearDown()
- */
- @Override
- public void tearDown() throws Exception
- {
- super.tearDown();
- if (_manager != null)
- {
- _manager.close();
- }
- }
-
- /**
- * @see org.apache.qpid.server.util.InternalBrokerBaseCase#setUp()
- */
- @Override
- public void setUp() throws Exception
- {
- super.setUp();
-
- final String passwdFilename = createPasswordFile().getCanonicalPath();
- final ConfigurationPlugin config = getConfig(PlainPasswordFilePrincipalDatabase.class.getName(),
- "passwordFile", passwdFilename);
-
- _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(config);
- }
-
- /**
- * 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
- }
- }
-
- /**
- * 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
- }
- }
-
- /**
- * Tests the case where a setter with the desired name cannot be found.
- */
- public void testPrincipalDatabaseSetterNotFound() throws Exception
- {
- try
- {
- _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(getConfig(PlainPasswordFilePrincipalDatabase.class.getName(), "noMethod", "test"));
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- // PASS
- }
- }
-
- /**
- * 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)
- {
- // PASS
- assertNotNull("Expected an underlying cause", ce.getCause());
- assertEquals(FileNotFoundException.class, ce.getCause().getClass());
- }
- }
-
- /**
- * Tests that the PDAM registers SASL mechanisms correctly with the runtime.
- */
- public void testRegisteredMechanisms() throws Exception
- {
- assertNotNull(_manager.getMechanisms());
- // relies on those mechanisms attached to PropertiesPrincipalDatabaseManager
- assertEquals("AMQPLAIN PLAIN CRAM-MD5", _manager.getMechanisms());
-
- Provider qpidProvider = Security.getProvider(PrincipalDatabaseAuthenticationManager.PROVIDER_NAME);
- assertNotNull(qpidProvider);
- }
-
- /**
- * Tests that the SASL factory method createSaslServer correctly
- * returns a non-null implementation.
- */
- public void testSaslMechanismCreation() throws Exception
- {
- SaslServer server = _manager.createSaslServer("CRAM-MD5", "localhost");
- 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
- {
- SaslServer testServer = createTestSaslServer(true, false);
-
- AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes());
- final Subject subject = result.getSubject();
- assertTrue(subject.getPrincipals().contains(new UsernamePrincipal("guest")));
- assertEquals(AuthenticationStatus.SUCCESS, result.getStatus());
- }
-
- /**
- *
- * Tests that the authenticate method correctly interprets an
- * authentication not complete.
- *
- */
- public void testSaslAuthenticationNotCompleted() throws Exception
- {
- SaslServer testServer = createTestSaslServer(false, false);
-
- AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes());
- assertNull(result.getSubject());
- assertEquals(AuthenticationStatus.CONTINUE, result.getStatus());
- }
-
- /**
- *
- * Tests that the authenticate method correctly interprets an
- * authentication error.
- *
- */
- public void testSaslAuthenticationError() throws Exception
- {
- SaslServer testServer = createTestSaslServer(false, true);
-
- AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes());
- assertNull(result.getSubject());
- assertEquals(AuthenticationStatus.ERROR, result.getStatus());
- }
-
- /**
- * Tests that the authenticate method correctly interprets an
- * authentication success.
- *
- */
- public void testNonSaslAuthenticationSuccess() throws Exception
- {
- 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")));
- assertEquals(AuthenticationStatus.SUCCESS, result.getStatus());
- }
-
- /**
- * Tests that the authenticate method correctly interprets an
- * authentication success.
- *
- */
- public void testNonSaslAuthenticationNotCompleted() throws Exception
- {
- AuthenticationResult result = _manager.authenticate("guest", "wrongpassword");
- assertNull(result.getSubject());
- 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));
-
- _manager.close();
-
- // Check provider has been removed.
- assertNull(_manager.getMechanisms());
- assertNull(Security.getProvider(PrincipalDatabaseAuthenticationManager.PROVIDER_NAME));
- _manager = null;
- }
-
- /**
- * Test SASL implementation used to test the authenticate() method.
- */
- private SaslServer createTestSaslServer(final boolean complete, final boolean throwSaslException)
- {
- return new SaslServer()
- {
- public String getMechanismName()
- {
- return null;
- }
-
- public byte[] evaluateResponse(byte[] response) throws SaslException
- {
- if (throwSaslException)
- {
- throw new SaslException("Mocked exception");
- }
- return null;
- }
-
- public boolean isComplete()
- {
- return complete;
- }
-
- public String getAuthorizationID()
- {
- return complete ? "guest" : null;
- }
-
- public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
- {
- return null;
- }
-
- public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
- {
- return null;
- }
-
- public Object getNegotiatedProperty(String propName)
- {
- return null;
- }
-
- public void dispose() throws SaslException
- {
- }
- };
- }
-
- private ConfigurationPlugin getConfig(final String clazz, final String argName, final String argValue) throws Exception
- {
- final ConfigurationPlugin config = new PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
- xmlconfig.addProperty("pd-auth-manager.principal-database.class", clazz);
-
- if (argName != null)
- {
- xmlconfig.addProperty("pd-auth-manager.principal-database.attributes.attribute.name", argName);
- xmlconfig.addProperty("pd-auth-manager.principal-database.attributes.attribute.value", argValue);
- }
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
- config.setConfiguration("security", xmlconfig);
- return config;
- }
-
- private File createPasswordFile() throws Exception
- {
- 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
- {
- if (writer != null)
- {
- writer.close();
- }
- }
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
index 6dc7b19d3d..e8c24da68d 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
@@ -20,125 +20,188 @@
*/
package org.apache.qpid.server.security.auth.rmi;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
import java.util.Collections;
import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-import junit.framework.TestCase;
+import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
+import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
-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.manager.AuthenticationManager;
+import junit.framework.TestCase;
-/**
- * Tests the RMIPasswordAuthenticator and its collaboration with the AuthenticationManager.
- *
- */
public class RMIPasswordAuthenticatorTest extends TestCase
{
private final String USERNAME = "guest";
private final String PASSWORD = "guest";
+ private final String B64_MD5HASHED_PASSWORD = "CE4DQ6BIb/BVMN9scFyLtA==";
private RMIPasswordAuthenticator _rmipa;
- private String[] _credentials;
+
+ private Base64MD5PasswordFilePrincipalDatabase _md5Pd;
+ private File _md5PwdFile;
+
+ private PlainPasswordFilePrincipalDatabase _plainPd;
+ private File _plainPwdFile;
+
+ private Subject testSubject;
protected void setUp() throws Exception
{
_rmipa = new RMIPasswordAuthenticator();
- _credentials = new String[] {USERNAME, PASSWORD};
- }
-
- /**
- * Tests a successful authentication. Ensures that a populated read-only subject it returned.
- */
- public void testAuthenticationSuccess()
- {
- final Subject expectedSubject = new Subject(true,
+ _md5Pd = new Base64MD5PasswordFilePrincipalDatabase();
+ _md5PwdFile = createTempPasswordFile(this.getClass().getName()+"md5pwd", USERNAME, B64_MD5HASHED_PASSWORD);
+ _md5Pd.setPasswordFile(_md5PwdFile.getAbsolutePath());
+
+ _plainPd = new PlainPasswordFilePrincipalDatabase();
+ _plainPwdFile = createTempPasswordFile(this.getClass().getName()+"plainpwd", USERNAME, PASSWORD);
+ _plainPd.setPasswordFile(_plainPwdFile.getAbsolutePath());
+
+ testSubject = new Subject(true,
Collections.singleton(new JMXPrincipal(USERNAME)),
Collections.EMPTY_SET,
Collections.EMPTY_SET);
+ }
+
+ private File createTempPasswordFile(String filenamePrefix, String user, String password)
+ {
+ try
+ {
+ File testFile = File.createTempFile(filenamePrefix,"tmp");
+ testFile.deleteOnExit();
+
+ BufferedWriter writer = new BufferedWriter(new FileWriter(testFile));
- _rmipa.setAuthenticationManager(createTestAuthenticationManager(true, null));
+ writer.write(user + ":" + password);
+ writer.newLine();
+ writer.flush();
+ writer.close();
- Subject newSubject = _rmipa.authenticate(_credentials);
- assertTrue("Subject must be readonly", newSubject.isReadOnly());
- assertTrue("Returned subject does not equal expected value",
- newSubject.equals(expectedSubject));
+ return testFile;
+ }
+ catch (IOException e)
+ {
+ fail("Unable to create temporary test password file." + e.getMessage());
+ }
+ return null;
}
+
+
+ //********** Test Methods *********//
+
- /**
- * Tests a unsuccessful authentication.
- */
- public void testUsernameOrPasswordInvalid()
+ public void testAuthenticate()
{
- _rmipa.setAuthenticationManager(createTestAuthenticationManager(false, null));
-
+ String[] credentials;
+ Subject newSubject;
+
+ // Test when no PD has been set
try
{
- _rmipa.authenticate(_credentials);
- fail("Exception not thrown");
+ credentials = new String[]{USERNAME, PASSWORD};
+ newSubject = _rmipa.authenticate(credentials);
+ fail("SecurityException expected due to lack of principal database");
}
catch (SecurityException se)
{
assertEquals("Unexpected exception message",
- RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
-
+ RMIPasswordAuthenticator.UNABLE_TO_LOOKUP, se.getMessage());
}
- }
- /**
- * Tests case where authentication system itself fails.
- */
- public void testAuthenticationFailure()
- {
- final Exception mockAuthException = new Exception("Mock Auth system failure");
- _rmipa.setAuthenticationManager(createTestAuthenticationManager(false, mockAuthException));
+ //The PrincipalDatabase's are tested primarily by their own tests, but
+ //minimal tests are done here to exercise their usage in this area.
+
+ // Test correct passwords are verified with an MD5 PD
+ try
+ {
+ _rmipa.setPrincipalDatabase(_md5Pd);
+ credentials = new String[]{USERNAME, PASSWORD};
+ newSubject = _rmipa.authenticate(credentials);
+ assertTrue("Returned subject does not equal expected value",
+ newSubject.equals(testSubject));
+ }
+ catch (Exception e)
+ {
+ fail("Unexpected Exception:" + e.getMessage());
+ }
+ // Test incorrect passwords are not verified with an MD5 PD
try
{
- _rmipa.authenticate(_credentials);
- fail("Exception not thrown");
+ credentials = new String[]{USERNAME, PASSWORD+"incorrect"};
+ newSubject = _rmipa.authenticate(credentials);
+ fail("SecurityException expected due to incorrect password");
}
catch (SecurityException se)
{
- assertEquals("Initial cause not found", mockAuthException, se.getCause());
+ assertEquals("Unexpected exception message",
+ RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
+ }
+
+ // Test non-existent accounts are not verified with an MD5 PD
+ try
+ {
+ credentials = new String[]{USERNAME+"invalid", PASSWORD};
+ newSubject = _rmipa.authenticate(credentials);
+ fail("SecurityException expected due to non-existant account");
+ }
+ catch (SecurityException se)
+ {
+ assertEquals("Unexpected exception message",
+ RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
}
- }
+ // Test correct passwords are verified with a Plain PD
+ try
+ {
+ _rmipa.setPrincipalDatabase(_plainPd);
+ credentials = new String[]{USERNAME, PASSWORD};
+ newSubject = _rmipa.authenticate(credentials);
+ assertTrue("Returned subject does not equal expected value",
+ newSubject.equals(testSubject));
+ }
+ catch (Exception e)
+ {
+ fail("Unexpected Exception");
+ }
- /**
- * Tests case where authentication manager is not set.
- */
- public void testNullAuthenticationManager()
- {
+ // Test incorrect passwords are not verified with a Plain PD
try
{
- _rmipa.authenticate(_credentials);
- fail("SecurityException expected due to lack of authentication manager");
+ credentials = new String[]{USERNAME, PASSWORD+"incorrect"};
+ newSubject = _rmipa.authenticate(credentials);
+ fail("SecurityException expected due to incorrect password");
}
catch (SecurityException se)
{
assertEquals("Unexpected exception message",
- RMIPasswordAuthenticator.UNABLE_TO_LOOKUP, se.getMessage());
+ RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
+ }
+
+ // Test non-existent accounts are not verified with an Plain PD
+ try
+ {
+ credentials = new String[]{USERNAME+"invalid", PASSWORD};
+ newSubject = _rmipa.authenticate(credentials);
+ fail("SecurityException expected due to non existant account");
+ }
+ catch (SecurityException se)
+ {
+ assertEquals("Unexpected exception message",
+ RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
}
- }
- /**
- * Tests case where arguments are non-Strings..
- */
- public void testWithNonStringArrayArgument()
- {
// Test handling of non-string credential's
- final Object[] objCredentials = new Object[]{USERNAME, PASSWORD};
try
{
- _rmipa.authenticate(objCredentials);
+ Object[] objCredentials = new Object[]{USERNAME, PASSWORD};
+ newSubject = _rmipa.authenticate(objCredentials);
fail("SecurityException expected due to non string[] credentials");
}
catch (SecurityException se)
@@ -146,18 +209,12 @@ public class RMIPasswordAuthenticatorTest extends TestCase
assertEquals("Unexpected exception message",
RMIPasswordAuthenticator.SHOULD_BE_STRING_ARRAY, se.getMessage());
}
- }
-
- /**
- * Tests case where there are too many, too few or null arguments.
- */
- public void testWithIllegalNumberOfArguments()
- {
- // Test handling of incorrect number of credentials
+
+ // Test handling of incorrect number of credential's
try
{
- _credentials = new String[]{USERNAME, PASSWORD, PASSWORD};
- _rmipa.authenticate(_credentials);
+ credentials = new String[]{USERNAME, PASSWORD, PASSWORD};
+ newSubject = _rmipa.authenticate(credentials);
fail("SecurityException expected due to supplying wrong number of credentials");
}
catch (SecurityException se)
@@ -166,12 +223,12 @@ public class RMIPasswordAuthenticatorTest extends TestCase
RMIPasswordAuthenticator.SHOULD_HAVE_2_ELEMENTS, se.getMessage());
}
- // Test handling of null credentials
+ // Test handling of null credential's
try
{
//send a null array
- _credentials = null;
- _rmipa.authenticate(_credentials);
+ credentials = null;
+ newSubject = _rmipa.authenticate(credentials);
fail("SecurityException expected due to not supplying an array of credentials");
}
catch (SecurityException se)
@@ -183,8 +240,8 @@ public class RMIPasswordAuthenticatorTest extends TestCase
try
{
//send a null password
- _credentials = new String[]{USERNAME, null};
- _rmipa.authenticate(_credentials);
+ credentials = new String[]{USERNAME, null};
+ newSubject = _rmipa.authenticate(credentials);
fail("SecurityException expected due to sending a null password");
}
catch (SecurityException se)
@@ -196,8 +253,8 @@ public class RMIPasswordAuthenticatorTest extends TestCase
try
{
//send a null username
- _credentials = new String[]{null, PASSWORD};
- _rmipa.authenticate(_credentials);
+ credentials = new String[]{null, PASSWORD};
+ newSubject = _rmipa.authenticate(credentials);
fail("SecurityException expected due to sending a null username");
}
catch (SecurityException se)
@@ -207,54 +264,4 @@ public class RMIPasswordAuthenticatorTest extends TestCase
}
}
- private AuthenticationManager createTestAuthenticationManager(final boolean successfulAuth, final Exception exception)
- {
- return new AuthenticationManager()
- {
- 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) 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);
- }
- }
- };
- }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/CRAMMD5HexServerTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/CRAMMD5HexServerTest.java
deleted file mode 100644
index 86e4e23750..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/CRAMMD5HexServerTest.java
+++ /dev/null
@@ -1,228 +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.sasl;
-
-import java.io.File;
-import java.io.IOException;
-import java.security.MessageDigest;
-import java.security.Principal;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-import javax.security.auth.login.AccountNotFoundException;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
-import junit.framework.TestCase;
-
-import org.apache.commons.codec.binary.Hex;
-import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
-import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexInitialiser;
-import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexSaslServer;
-import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexServerFactory;
-
-/**
- * Test for the CRAM-MD5-HEX SASL mechanism.
- *
- * This test case focuses on testing {@link CRAMMD5HexSaslServer} but also exercises
- * collaborators {@link CRAMMD5HexInitialiser} and {@link Base64MD5PasswordFilePrincipalDatabase}
- */
-public class CRAMMD5HexServerTest extends TestCase
-{
-
- private SaslServer _saslServer; // Class under test
- private CRAMMD5HexServerFactory _saslFactory;
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
-
- CRAMMD5HexInitialiser _initializer = new CRAMMD5HexInitialiser();
-
- //Use properties to create a PrincipalDatabase
- Base64MD5PasswordFilePrincipalDatabase db = createTestPrincipalDatabase();
- assertEquals("Unexpected number of test users in the db", 2, db.getUsers().size());
-
- _initializer.initialise(db);
-
- _saslFactory = new CRAMMD5HexServerFactory();
-
- _saslServer = _saslFactory.createSaslServer(CRAMMD5HexSaslServer.MECHANISM,
- "AMQP",
- "localhost",
- _initializer.getProperties(),
- _initializer.getCallbackHandler());
- assertNotNull("Unable to create saslServer with mechanism type " + CRAMMD5HexSaslServer.MECHANISM, _saslServer);
-
- }
-
- public void testSuccessfulAuth() throws Exception
- {
-
- final byte[] serverChallenge = _saslServer.evaluateResponse(new byte[0]);
-
- // Generate client response
- final byte[] clientResponse = generateClientResponse("knownuser", "guest", serverChallenge);
-
-
- byte[] nextServerChallenge = _saslServer.evaluateResponse(clientResponse);
- assertTrue("Exchange must be flagged as complete after successful authentication", _saslServer.isComplete());
- assertNull("Next server challenge must be null after successful authentication", nextServerChallenge);
-
- }
-
- public void testKnownUserPresentsWrongPassword() throws Exception
- {
- byte[] serverChallenge = _saslServer.evaluateResponse(new byte[0]);
-
-
- final byte[] clientResponse = generateClientResponse("knownuser", "wrong!", serverChallenge);
- try
- {
- _saslServer.evaluateResponse(clientResponse);
- fail("Exception not thrown");
- }
- catch (SaslException se)
- {
- // PASS
- }
- assertFalse("Exchange must not be flagged as complete after unsuccessful authentication", _saslServer.isComplete());
- }
-
- public void testUnknownUser() throws Exception
- {
- final byte[] serverChallenge = _saslServer.evaluateResponse(new byte[0]);
-
-
- final byte[] clientResponse = generateClientResponse("unknownuser", "guest", serverChallenge);
-
- try
- {
- _saslServer.evaluateResponse(clientResponse);
- fail("Exception not thrown");
- }
- catch (SaslException se)
- {
- assertExceptionHasUnderlyingAsCause(AccountNotFoundException.class, se);
- // PASS
- }
- assertFalse("Exchange must not be flagged as complete after unsuccessful authentication", _saslServer.isComplete());
- }
-
- /**
- *
- * Demonstrates QPID-3158. A defect meant that users with some valid password were failing to
- * authenticate when using the .NET 0-8 client (uses this SASL mechanism).
- * It so happens that password "guest2" was one of the affected passwords.
- *
- * @throws Exception
- */
- public void testSuccessfulAuthReproducingQpid3158() throws Exception
- {
- byte[] serverChallenge = _saslServer.evaluateResponse(new byte[0]);
-
- // Generate client response
- byte[] resp = generateClientResponse("qpid3158user", "guest2", serverChallenge);
-
- byte[] nextServerChallenge = _saslServer.evaluateResponse(resp);
- assertTrue("Exchange must be flagged as complete after successful authentication", _saslServer.isComplete());
- assertNull("Next server challenge must be null after successful authentication", nextServerChallenge);
- }
-
- /**
- * Since we don't have a CRAM-MD5-HEX implementation client implementation in Java, this method
- * provides the implementation for first principals.
- *
- * @param userId user id
- * @param clearTextPassword clear text password
- * @param serverChallenge challenge from server
- *
- * @return challenge response
- */
- private byte[] generateClientResponse(final String userId, final String clearTextPassword, final byte[] serverChallenge) throws Exception
- {
- byte[] digestedPasswordBytes = MessageDigest.getInstance("MD5").digest(clearTextPassword.getBytes());
- char[] hexEncodedDigestedPassword = Hex.encodeHex(digestedPasswordBytes);
- byte[] hexEncodedDigestedPasswordBytes = new String(hexEncodedDigestedPassword).getBytes();
-
-
- Mac hmacMd5 = Mac.getInstance("HmacMD5");
- hmacMd5.init(new SecretKeySpec(hexEncodedDigestedPasswordBytes, "HmacMD5"));
- final byte[] messageAuthenticationCode = hmacMd5.doFinal(serverChallenge);
-
- // Build client response
- String responseAsString = userId + " " + new String(Hex.encodeHex(messageAuthenticationCode));
- byte[] resp = responseAsString.getBytes();
- return resp;
- }
-
- /**
- * Creates a test principal database.
- *
- * @return
- * @throws IOException
- */
- private Base64MD5PasswordFilePrincipalDatabase createTestPrincipalDatabase() throws IOException
- {
- Base64MD5PasswordFilePrincipalDatabase db = new Base64MD5PasswordFilePrincipalDatabase();
- File file = File.createTempFile("passwd", "db");
- file.deleteOnExit();
- db.setPasswordFile(file.getCanonicalPath());
- db.createPrincipal( createTestPrincipal("knownuser"), "guest".toCharArray());
- db.createPrincipal( createTestPrincipal("qpid3158user"), "guest2".toCharArray());
- return db;
- }
-
- private Principal createTestPrincipal(final String name)
- {
- return new Principal()
- {
- public String getName()
- {
- return name;
- }
- };
- }
-
- private void assertExceptionHasUnderlyingAsCause(final Class<? extends Throwable> expectedUnderlying, Throwable e)
- {
- assertNotNull(e);
- int infiniteLoopGuard = 0; // Guard against loops in the cause chain
- boolean foundExpectedUnderlying = false;
- while (e.getCause() != null && infiniteLoopGuard++ < 10)
- {
- if (expectedUnderlying.equals(e.getCause().getClass()))
- {
- foundExpectedUnderlying = true;
- break;
- }
- e = e.getCause();
- }
-
- if (!foundExpectedUnderlying)
- {
- fail("Not found expected underlying exception " + expectedUnderlying + " as underlying cause of " + e.getClass());
- }
- }
-
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java
deleted file mode 100644
index 076b7c9248..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.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.auth.sasl;
-
-import junit.framework.TestCase;
-
-public class GroupPrincipalTest extends TestCase
-{
- public void testGetName()
- {
- final GroupPrincipal principal = new GroupPrincipal("group");
- assertEquals("group", principal.getName());
- }
-
- public void testAddRejected()
- {
- final GroupPrincipal principal = new GroupPrincipal("group");
- final UsernamePrincipal user = new UsernamePrincipal("name");
-
- try
- {
- principal.addMember(user);
- fail("Exception not thrown");
- }
- catch (UnsupportedOperationException uso)
- {
- // PASS
- }
- }
-
- public void testEqualitySameName()
- {
- final String string = "string";
- final GroupPrincipal principal1 = new GroupPrincipal(string);
- final GroupPrincipal principal2 = new GroupPrincipal(string);
- assertTrue(principal1.equals(principal2));
- }
-
- public void testEqualityEqualName()
- {
- final GroupPrincipal principal1 = new GroupPrincipal(new String("string"));
- final GroupPrincipal principal2 = new GroupPrincipal(new String("string"));
- assertTrue(principal1.equals(principal2));
- }
-
- public void testInequalityDifferentGroupPrincipals()
- {
- GroupPrincipal principal1 = new GroupPrincipal("string1");
- GroupPrincipal principal2 = new GroupPrincipal("string2");
- assertFalse(principal1.equals(principal2));
- }
-
- public void testInequalityNonGroupPrincipal()
- {
- GroupPrincipal principal = new GroupPrincipal("string");
- assertFalse(principal.equals(new UsernamePrincipal("string")));
- }
-
- public void testInequalityNull()
- {
- GroupPrincipal principal = new GroupPrincipal("string");
- assertFalse(principal.equals(null));
- }
-
-
-
-
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java
deleted file mode 100644
index 541f14d923..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.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.auth.sasl;
-
-import java.security.Principal;
-import javax.security.auth.Subject;
-import junit.framework.TestCase;
-
-/**
- * Tests the UsernamePrincipal.
- *
- */
-public class UsernamePrincipalTest extends TestCase
-{
- public void testEqualitySameObject()
- {
- final UsernamePrincipal principal = new UsernamePrincipal("string");
- assertTrue(principal.equals(principal));
- }
-
- public void testEqualitySameName()
- {
- final String string = "string";
- final UsernamePrincipal principal1 = new UsernamePrincipal(string);
- final UsernamePrincipal principal2 = new UsernamePrincipal(string);
- assertTrue(principal1.equals(principal2));
- }
-
- public void testEqualityEqualName()
- {
- final UsernamePrincipal principal1 = new UsernamePrincipal(new String("string"));
- final UsernamePrincipal principal2 = new UsernamePrincipal(new String("string"));
- assertTrue(principal1.equals(principal2));
- }
-
- public void testInequalityDifferentUserPrincipals()
- {
- UsernamePrincipal principal1 = new UsernamePrincipal("string1");
- UsernamePrincipal principal2 = new UsernamePrincipal("string2");
- assertFalse(principal1.equals(principal2));
- }
-
- public void testInequalityNonUserPrincipal()
- {
- UsernamePrincipal principal = new UsernamePrincipal("string");
- assertFalse(principal.equals(new String("string")));
- }
-
- public void testInequalityNull()
- {
- 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/qpid/java/broker/src/test/java/org/apache/qpid/server/stats/StatisticsCounterTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/stats/StatisticsCounterTest.java
deleted file mode 100644
index fbaa1342c9..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/stats/StatisticsCounterTest.java
+++ /dev/null
@@ -1,144 +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.stats;
-
-import junit.framework.TestCase;
-
-/**
- * Unit tests for the {@link StatisticsCounter} class.
- */
-public class StatisticsCounterTest extends TestCase
-{
- /**
- * Check that statistics counters are created correctly.
- */
- public void testCreate()
- {
- long before = System.currentTimeMillis();
- StatisticsCounter counter = new StatisticsCounter("name", 1234L);
- long after = System.currentTimeMillis();
-
- assertTrue(before <= counter.getStart());
- assertTrue(after >= counter.getStart());
- assertTrue(counter.getName().startsWith("name-"));
- assertEquals(1234L, counter.getPeriod());
- }
-
- /**
- * Check that totals add up correctly.
- */
- public void testTotal()
- {
- StatisticsCounter counter = new StatisticsCounter("test", 1000L);
- long start = counter.getStart();
- for (int i = 0; i < 100; i++)
- {
- counter.registerEvent(i, start + i);
- }
- assertEquals(99 * 50, counter.getTotal()); // cf. Gauss
- }
-
- /**
- * Test totals add up correctly even when messages are delivered
- * out-of-order.
- */
- public void testTotalOutOfOrder()
- {
- StatisticsCounter counter = new StatisticsCounter("test", 1000L);
- long start = counter.getStart();
- assertEquals(0, counter.getTotal());
- counter.registerEvent(10, start + 2500);
- assertEquals(10, counter.getTotal());
- counter.registerEvent(20, start + 1500);
- assertEquals(30, counter.getTotal());
- counter.registerEvent(10, start + 500);
- assertEquals(40, counter.getTotal());
- }
-
- /**
- * Test that the peak rate is reported correctly.
- */
- public void testPeak() throws Exception
- {
- StatisticsCounter counter = new StatisticsCounter("test", 1000L);
- long start = counter.getStart();
- assertEquals(0.0, counter.getPeak());
- Thread.sleep(500);
- counter.registerEvent(1000, start + 500);
- Thread.sleep(1000);
- assertEquals(1000.0, counter.getPeak());
- counter.registerEvent(2000, start + 1500);
- Thread.sleep(1000);
- assertEquals(2000.0, counter.getPeak());
- counter.registerEvent(1000, start + 2500);
- Thread.sleep(1000);
- assertEquals(2000.0, counter.getPeak());
- }
-
- /**
- * Test that peak rate is reported correctly for out-of-order messages,
- * and the total is also unaffected.
- */
- public void testPeakOutOfOrder() throws Exception
- {
- StatisticsCounter counter = new StatisticsCounter("test", 1000L);
- long start = counter.getStart();
- assertEquals(0.0, counter.getPeak());
- counter.registerEvent(1000, start + 2500);
- Thread.sleep(1500);
- assertEquals(0.0, counter.getPeak());
- counter.registerEvent(2000, start + 1500);
- Thread.sleep(1000L);
- assertEquals(0.0, counter.getPeak());
- counter.registerEvent(1000, start + 500);
- Thread.sleep(1500);
- assertEquals(4000.0, counter.getPeak());
- Thread.sleep(2000);
- assertEquals(4000.0, counter.getPeak());
- counter.registerEvent(1000, start + 500);
- assertEquals(4000.0, counter.getPeak());
- Thread.sleep(2000);
- counter.registerEvent(1000);
- assertEquals(4000.0, counter.getPeak());
- assertEquals(6000, counter.getTotal());
- }
-
- /**
- * Test the current rate is generated correctly.
- */
- public void testRate() throws Exception
- {
- StatisticsCounter counter = new StatisticsCounter("test", 1000L);
- assertEquals(0.0, counter.getRate());
- Thread.sleep(500);
- counter.registerEvent(1000);
- Thread.sleep(1000);
- assertEquals(1000.0, counter.getRate());
- counter.registerEvent(2000);
- Thread.sleep(1000);
- assertEquals(2000.0, counter.getRate());
- counter.registerEvent(1000);
- Thread.sleep(1000);
- assertEquals(1000.0, counter.getRate());
- Thread.sleep(1000);
- assertEquals(0.0, counter.getRate());
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
index 3acd064fd7..3ebe631f62 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
@@ -122,7 +122,6 @@ public class MessageStoreTest extends InternalBrokerBaseCase
}
catch (Exception e)
{
- e.printStackTrace();
fail(e.getMessage());
}
}
@@ -590,7 +589,7 @@ public class MessageStoreTest extends InternalBrokerBaseCase
headerBody.classId = BasicConsumeBodyImpl.CLASS_ID;
headerBody.bodySize = 0;
- headerBody.setProperties(properties);
+ headerBody.properties = properties;
try
{
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java
index 2d41eb9899..a75cbe8662 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java
@@ -102,7 +102,7 @@ public class ReferenceCountingTest extends QpidTestCase
ContentHeaderBody chb = new ContentHeaderBody();
BasicContentHeaderProperties bchp = new BasicContentHeaderProperties();
bchp.setDeliveryMode((byte)2);
- chb.setProperties(bchp);
+ chb.properties = bchp;
return chb;
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java
index 6fbc627d8c..1ec134e90e 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java
@@ -22,7 +22,6 @@ package org.apache.qpid.server.subscription;
*/
import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -46,7 +45,6 @@ public class MockSubscription implements Subscription
private State _state = State.ACTIVE;
private ArrayList<QueueEntry> messages = new ArrayList<QueueEntry>();
private final Lock _stateChangeLock = new ReentrantLock();
- private List<QueueEntry> _acceptEntries = null;
private final QueueEntry.SubscriptionAcquiredState _owningState = new QueueEntry.SubscriptionAcquiredState(this);
private final QueueEntry.SubscriptionAssignedState _assignedState = new QueueEntry.SubscriptionAssignedState(this);
@@ -56,15 +54,6 @@ public class MockSubscription implements Subscription
// Create a simple ID that increments for ever new Subscription
private final long _subscriptionID = idGenerator.getAndIncrement();
- public MockSubscription()
- {
- }
-
- public MockSubscription(List<QueueEntry> acceptEntries)
- {
- _acceptEntries = acceptEntries;
- }
-
public void close()
{
_closed = true;
@@ -130,15 +119,8 @@ public class MockSubscription implements Subscription
_stateChangeLock.lock();
}
- public boolean hasInterest(QueueEntry entry)
+ public boolean hasInterest(QueueEntry msg)
{
- if(_acceptEntries != null)
- {
- //simulate selector behaviour, only signal
- //interest in the dictated queue entries
- return _acceptEntries.contains(entry);
- }
-
return true;
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionListTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionListTest.java
deleted file mode 100644
index c4d1a1e614..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionListTest.java
+++ /dev/null
@@ -1,429 +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.subscription;
-
-import org.apache.qpid.server.subscription.SubscriptionList.SubscriptionNode;
-import org.apache.qpid.server.subscription.SubscriptionList.SubscriptionNodeIterator;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-public class SubscriptionListTest extends QpidTestCase
-{
- private SubscriptionList _subList;
- private MockSubscription _sub1;
- private MockSubscription _sub2;
- private MockSubscription _sub3;
- private SubscriptionNode _node;
-
- protected void setUp()
- {
- _subList = new SubscriptionList();
-
- _sub1 = new MockSubscription();
- _sub2 = new MockSubscription();
- _sub3 = new MockSubscription();
-
- _subList.add(_sub1);
- _subList.add(_sub2);
- _subList.add(_sub3);
-
- _node = _subList.getHead();
- }
-
- /**
- * Test that if the first (non-head) node in the list is deleted (but is still present),
- * it is not returned when searching through the list for the next viable node, and the
- * subsequent viable node is returned instead.
- */
- public void testFindNextSkipsFirstDeletedNode()
- {
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub1).delete());
-
- assertNotNull("Returned node should not be null", _node = _node.findNext());
- assertEquals("Should have returned node for 2nd subscription", _sub2, _node.getSubscription());
-
- assertNotNull("Returned node should not be null", _node = _node.findNext());
- assertEquals("Should have returned node for 3rd subscription", _sub3, _node.getSubscription());
- }
-
- /**
- * Test that if a central node in the list is deleted (but is still present),
- * it is not returned when searching through the list for the next viable node,
- * and the subsequent viable node is returned instead.
- */
- public void testFindNextSkipsCentralDeletedNode()
- {
- assertNotNull("Returned node should not be null", _node = _node.findNext());
-
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub2).delete());
-
- assertNotNull("Returned node should not be null", _node = _node.findNext());
- assertEquals("Should have returned node for 3rd subscription", _sub3, _node.getSubscription());
- }
-
- /**
- * Test that if the last node in the list is deleted (but is still present),
- * it is not returned when searching through the list for the next viable node,
- * and null is returned instead.
- */
- public void testFindNextSkipsLastDeletedNode()
- {
- assertNotNull("Returned node should not be null", _node = _node.findNext());
- assertEquals("Should have returned node for 1st subscription", _sub1, _node.getSubscription());
-
- assertNotNull("Returned node should not be null", _node = _node.findNext());
- assertEquals("Should have returned node for 2nd subscription", _sub2, _node.getSubscription());
-
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub3).delete());
-
- assertNull("Returned node should be null", _node = _node.findNext());
- }
-
- /**
- * Test that if multiple nodes in the list are deleted (but still present), they
- * are not returned when searching through the list for the next viable node,
- * and the subsequent viable node is returned instead.
- */
- public void testFindNextSkipsMultipleDeletedNode()
- {
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub1).delete());
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub2).delete());
-
- assertNotNull("Returned node should not be null", _node = _node.findNext());
- assertEquals("Should have returned node for 3rd subscription", _sub3, _node.getSubscription());
- }
-
- /**
- * Test that if a node in the list is marked 'deleted' it is still present in the list
- * until actually removed. counter-test to verify above testing of getNext() method.
- */
- public void testDeletedNodeStillPresent()
- {
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub1).delete());
-
- assertNotNull("Node marked deleted should still be present", getNodeForSubscription(_subList, _sub1));
- assertEquals("All 3 nodes are still expected to be present", 3, countNodes(_subList));
- }
-
- /**
- * Traverses the list nodes in a non-mutating fashion, returning the first node which matches the given
- * Subscription, or null if none is found.
- */
- private SubscriptionNode getNodeForSubscription(final SubscriptionList list, final Subscription sub)
- {
- SubscriptionNode node = list.getHead();
- while (node != null && node.getSubscription() != sub)
- {
- node = node.nextNode();
- }
-
- return node;
- }
-
- /**
- * Counts the number of (non-head) nodes in the list.
- */
- private int countNodes(final SubscriptionList list)
- {
- SubscriptionNode node = list.getHead();
- int count;
- for(count = -1; node != null; count++)
- {
- node = node.nextNode();
- }
-
- return count;
- }
-
- /**
- * Tests that the head is returned as expected, and isn't the node for the first subscription.
- */
- public void testGetHead()
- {
- assertNotNull("List head should be non null", _node);
- assertNotSame("Head should not be node for first subscription",
- _node, getNodeForSubscription(_subList, _sub1));
- }
-
- /**
- * Tests that the size is returned correctly in the face of additions and removals.
- */
- public void testGetSize()
- {
- SubscriptionList subList = new SubscriptionList();
-
- assertEquals("Unexpected size result", 0, subList.size());
-
- Subscription sub1 = new MockSubscription();
- Subscription sub2 = new MockSubscription();
- Subscription sub3 = new MockSubscription();
-
- subList.add(sub1);
- assertEquals("Unexpected size result", 1, subList.size());
-
- subList.add(sub2);
- assertEquals("Unexpected size result", 2, subList.size());
-
- subList.add(sub3);
- assertEquals("Unexpected size result", 3, subList.size());
-
- assertTrue("Removing subscription from list should have succeeded", subList.remove(sub1));
- assertEquals("Unexpected size result", 2, subList.size());
-
- assertTrue("Removing subscription from list should have succeeded", subList.remove(sub2));
- assertEquals("Unexpected size result", 1, subList.size());
-
- assertTrue("Removing subscription from list should have succeeded", subList.remove(sub3));
- assertEquals("Unexpected size result", 0, subList.size());
- }
-
- /**
- * Test that if the first (non-head) node in the list is removed it is no longer
- * present in the node structure of the list at all.
- */
- public void testRemoveFirstNode()
- {
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub1));
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub1));
- assertNull("Should not have been a node present for the removed subscription", getNodeForSubscription(_subList, _sub1));
- assertEquals("Unexpected number of nodes", 2, countNodes(_subList));
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub2));
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub3));
- }
-
- /**
- * Test that if a central node in the list is removed it is no longer
- * present in the node structure of the list at all.
- */
- public void testRemoveCentralNode()
- {
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub2));
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub2));
- assertNull("Should not have been a node present for the removed subscription", getNodeForSubscription(_subList, _sub2));
- assertEquals("Unexpected number of nodes", 2, countNodes(_subList));
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub1));
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub3));
- }
-
- /**
- * Test that if the subscription contained in the last node of the list is removed
- * it is no longer present in the node structure of the list at all. However,
- * as the last node in the structure can't actually be removed a dummy will instead
- * be present.
- */
- public void testRemoveLastNode()
- {
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub3));
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub3));
- assertNull("Should not have been a node present for the removed subscription", getNodeForSubscription(_subList, _sub3));
-
- //We actually expect 3 nodes to remain this time, because the last node cant be removed for thread safety reasons,
- //however a dummy final node can be used as substitute to allow removal of the subscription node.
- assertEquals("Unexpected number of nodes", 2 + 1, countNodes(_subList));
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub1));
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub2));
- }
-
- /**
- * Test that if the subscription not contained in the list is requested to be removed
- * that the removal fails
- */
- public void testRemoveNonExistantNode()
- {
- Subscription sub4 = new MockSubscription();
- assertNull("Should not have been a node present for the subscription", getNodeForSubscription(_subList, sub4));
- assertFalse("Removing subscription node should not have succeeded", _subList.remove(sub4));
- assertEquals("Unexpected number of nodes", 3, countNodes(_subList));
- }
-
- /**
- * Test that if a subscription node which occurs later in the main list than the marked node is
- * removed from the list after the marked node is also removed, then the marker node doesn't
- * serve to retain the subsequent nodes in the list structure (and thus memory) despite their
- * removal.
- */
- public void testDeletedMarkedNodeDoesntLeakSubsequentlyDeletedNodes()
- {
- //get the nodes out the list for the 1st and 3rd subscriptions
- SubscriptionNode sub1Node = getNodeForSubscription(_subList, _sub1);
- assertNotNull("Should have been a node present for the subscription", sub1Node);
- SubscriptionNode sub3Node = getNodeForSubscription(_subList, _sub3);
- assertNotNull("Should have been a node present for the subscription", sub3Node);
-
- //mark the first subscription node
- assertTrue("should have succeeded in updating the marked node",
- _subList.updateMarkedNode(_subList.getMarkedNode(), sub1Node));
-
- //remove the 1st subscription from the list
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub1));
- //verify the 1st subscription is no longer the marker node (replaced by a dummy), or in the main list structure
- assertNotSame("Unexpected marker node", sub1Node, _subList.getMarkedNode());
- assertNull("Should not have been a node present in the list structure for the marked-but-removed sub1 node",
- getNodeForSubscription(_subList, _sub1));
-
- //remove the 2nd subscription from the list
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub2));
-
- //verify the marker node isn't leaking subsequently removed nodes, by ensuring the very next node
- //in its list structure is now the 3rd subscription (since the 2nd was removed too)
- assertEquals("Unexpected next node", sub3Node, _subList.getMarkedNode().nextNode());
-
- //remove the 3rd and final/tail subscription
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub3));
-
- //verify the marker node isn't leaking subsequently removed nodes, by ensuring the very next node
- //in its list structure is now the dummy tail (since the 3rd subscription was removed, and a dummy
- //tail was inserted) and NOT the 3rd sub node.
- assertNotSame("Unexpected next node", sub3Node, _subList.getMarkedNode().nextNode());
- assertTrue("Unexpected next node", _subList.getMarkedNode().nextNode().isDeleted());
- assertNull("Next non-deleted node from the marker should now be the list end, i.e. null", _subList.getMarkedNode().findNext());
- }
-
- /**
- * Test that the marked node 'findNext' behaviour is as expected after a subscription is added
- * to the list following the tail subscription node being removed while it is the marked node.
- * That is, that the new subscriptions node is returned by getMarkedNode().findNext().
- */
- public void testMarkedNodeFindsNewSubscriptionAfterRemovingTailWhilstMarked()
- {
- //get the node out the list for the 3rd subscription
- SubscriptionNode sub3Node = getNodeForSubscription(_subList, _sub3);
- assertNotNull("Should have been a node present for the subscription", sub3Node);
-
- //mark the 3rd subscription node
- assertTrue("should have succeeded in updating the marked node",
- _subList.updateMarkedNode(_subList.getMarkedNode(), sub3Node));
-
- //verify calling findNext on the marked node returns null, i.e. the end of the list has been reached
- assertEquals("Unexpected node after marked node", null, _subList.getMarkedNode().findNext());
-
- //remove the 3rd(marked) subscription from the list
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub3));
-
- //add a new 4th subscription to the list
- Subscription sub4 = new MockSubscription();
- _subList.add(sub4);
-
- //get the node out the list for the 4th subscription
- SubscriptionNode sub4Node = getNodeForSubscription(_subList, sub4);
- assertNotNull("Should have been a node present for the subscription", sub4Node);
-
- //verify the marked node (which is now a dummy substitute for the 3rd subscription) returns
- //the 4th subscriptions node as the next non-deleted node.
- assertEquals("Unexpected next node", sub4Node, _subList.getMarkedNode().findNext());
- }
-
- /**
- * Test that setting the marked node to null doesn't cause problems during remove operations
- */
- public void testRemoveWithNullMarkedNode()
- {
- //set the marker to null
- assertTrue("should have succeeded in updating the marked node",
- _subList.updateMarkedNode(_subList.getMarkedNode(), null));
-
- //remove the 1st subscription from the main list
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub1));
-
- //verify the 1st subscription is no longer in the main list structure
- assertNull("Should not have been a node present in the main list structure for sub1",
- getNodeForSubscription(_subList, _sub1));
- assertEquals("Unexpected number of nodes", 2, countNodes(_subList));
- }
-
- /**
- * Tests that after the first (non-head) node of the list is marked deleted but has not
- * yet been removed, the iterator still skips it.
- */
- public void testIteratorSkipsFirstDeletedNode()
- {
- //'delete' but dont remove the node for the 1st subscription
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub1).delete());
- assertNotNull("Should still have been a node present for the deleted subscription",
- getNodeForSubscription(_subList, _sub1));
-
- SubscriptionNodeIterator iter = _subList.iterator();
-
- //verify the iterator returns the 2nd subscriptions node
- assertTrue("Iterator should have been able to advance", iter.advance());
- assertEquals("Iterator returned unexpected SubscriptionNode", _sub2, iter.getNode().getSubscription());
-
- //verify the iterator returns the 3rd subscriptions node and not the 2nd.
- assertTrue("Iterator should have been able to advance", iter.advance());
- assertEquals("Iterator returned unexpected SubscriptionNode", _sub3, iter.getNode().getSubscription());
- }
-
- /**
- * Tests that after a central node of the list is marked deleted but has not yet been removed,
- * the iterator still skips it.
- */
- public void testIteratorSkipsCentralDeletedNode()
- {
- //'delete' but dont remove the node for the 2nd subscription
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub2).delete());
- assertNotNull("Should still have been a node present for the deleted subscription",
- getNodeForSubscription(_subList, _sub2));
-
- SubscriptionNodeIterator iter = _subList.iterator();
-
- //verify the iterator returns the 1st subscriptions node
- assertTrue("Iterator should have been able to advance", iter.advance());
- assertEquals("Iterator returned unexpected SubscriptionNode", _sub1, iter.getNode().getSubscription());
-
- //verify the iterator returns the 3rd subscriptions node and not the 2nd.
- assertTrue("Iterator should have been able to advance", iter.advance());
- assertEquals("Iterator returned unexpected SubscriptionNode", _sub3, iter.getNode().getSubscription());
- }
-
- /**
- * Tests that after the last node of the list is marked deleted but has not yet been removed,
- * the iterator still skips it.
- */
- public void testIteratorSkipsDeletedFinalNode()
- {
- //'delete' but dont remove the node for the 3rd subscription
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub3).delete());
- assertNotNull("Should still have been a node present for the deleted 3rd subscription",
- getNodeForSubscription(_subList, _sub3));
-
- SubscriptionNodeIterator iter = _subList.iterator();
-
- //verify the iterator returns the 1st subscriptions node
- assertTrue("Iterator should have been able to advance", iter.advance());
- assertEquals("Iterator returned unexpected SubscriptionNode", _sub1, iter.getNode().getSubscription());
-
- //verify the iterator returns the 2nd subscriptions node
- assertTrue("Iterator should have been able to advance", iter.advance());
- assertEquals("Iterator returned unexpected SubscriptionNode", _sub2, iter.getNode().getSubscription());
-
- //verify the iterator can no longer advance and does not return a subscription node
- assertFalse("Iterator should not have been able to advance", iter.advance());
- assertEquals("Iterator returned unexpected SubscriptionNode", null, iter.getNode());
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockAction.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockAction.java
index 15c135ea2c..975e3e91b9 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockAction.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockAction.java
@@ -32,11 +32,13 @@ class MockAction implements Action
private boolean _rollbackFired = false;
private boolean _postCommitFired = false;
+ @Override
public void postCommit()
{
_postCommitFired = true;
}
+ @Override
public void onRollback()
{
_rollbackFired = true;
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java
index 422105e410..64c62fd029 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java
@@ -46,56 +46,67 @@ class MockServerMessage implements ServerMessage
this.persistent = persistent;
}
+ @Override
public boolean isPersistent()
{
return persistent;
}
+ @Override
public MessageReference newReference()
{
throw new NotImplementedException();
}
+ @Override
public boolean isImmediate()
{
throw new NotImplementedException();
}
+ @Override
public long getSize()
{
throw new NotImplementedException();
}
+ @Override
public SessionConfig getSessionConfig()
{
throw new NotImplementedException();
}
+ @Override
public String getRoutingKey()
{
throw new NotImplementedException();
}
+ @Override
public AMQMessageHeader getMessageHeader()
{
throw new NotImplementedException();
}
+ @Override
public long getExpiration()
{
throw new NotImplementedException();
}
+ @Override
public int getContent(ByteBuffer buf, int offset)
{
throw new NotImplementedException();
}
+ @Override
public long getArrivalTime()
{
throw new NotImplementedException();
}
+ @Override
public Long getMessageNumber()
{
return 0L;
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java
index ff372532ac..5700bba9f8 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java
@@ -61,6 +61,7 @@ class MockStoreTransaction implements Transaction
return _state;
}
+ @Override
public void enqueueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
{
if (_throwExceptionOnQueueOp)
@@ -82,6 +83,8 @@ class MockStoreTransaction implements Transaction
return _numberOfEnqueuedMessages;
}
+
+ @Override
public void dequeueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
{
if (_throwExceptionOnQueueOp)
@@ -92,16 +95,19 @@ class MockStoreTransaction implements Transaction
_numberOfDequeuedMessages++;
}
+ @Override
public void commitTran() throws AMQStoreException
{
_state = TransactionState.COMMITTED;
}
+ @Override
public StoreFuture commitTranAsync() throws AMQStoreException
{
throw new NotImplementedException();
}
+ @Override
public void abortTran() throws AMQStoreException
{
_state = TransactionState.ABORTED;
@@ -111,11 +117,14 @@ class MockStoreTransaction implements Transaction
{
return new TransactionLog()
{
+
+ @Override
public void configureTransactionLog(String name, TransactionLogRecoveryHandler recoveryHandler,
Configuration storeConfiguration, LogSubject logSubject) throws Exception
{
}
-
+
+ @Override
public Transaction newTransaction()
{
storeTransaction.setState(TransactionState.STARTED);
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java
index ff94942457..925b161118 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java
@@ -243,7 +243,7 @@ public class InternalBrokerBaseCase extends QpidTestCase
//Make Message Persistent
properties.setDeliveryMode((byte) 2);
- _headerBody.setProperties(properties);
+ _headerBody.properties = properties;
channel.publishContentHeader(_headerBody);
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
index 8fa820ad95..af8997cf40 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
@@ -20,70 +20,27 @@
*/
package org.apache.qpid.server.util;
-import java.util.Properties;
-
import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.server.configuration.ServerConfiguration;
-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.configuration.plugins.ConfigurationPlugin;
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.PrincipalDatabaseAuthenticationManager;
+import org.apache.qpid.server.security.auth.database.PropertiesPrincipalDatabaseManager;
+
+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()));
- super.initialise();
- }
-
- /**
- * @see org.apache.qpid.server.registry.ApplicationRegistry#createAuthenticationManager()
- */
- @Override
- protected AuthenticationManager createAuthenticationManager() throws ConfigurationException
+ protected void createDatabaseManager(ServerConfiguration configuration) throws Exception
{
- final Properties users = new Properties();
+ Properties users = new Properties();
users.put("guest","guest");
users.put("admin","admin");
-
- final PropertiesPrincipalDatabase ppd = new PropertiesPrincipalDatabase(users);
-
- 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 pdam;
+ _databaseManager = new PropertiesPrincipalDatabaseManager("testPasswordFile", users);
}
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/HouseKeepingTaskTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/HouseKeepingTaskTest.java
deleted file mode 100644
index 98bf381712..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/HouseKeepingTaskTest.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.server.virtualhost;
-
-import java.util.concurrent.CountDownLatch;
-
-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.test.utils.QpidTestCase;
-
-public class HouseKeepingTaskTest extends QpidTestCase
-{
- /**
- * Tests that the abstract HouseKeepingTask properly cleans up any LogActor
- * it adds to the CurrentActor stack by verifying the CurrentActor set
- * before task execution is the CurrentActor after execution.
- */
- public void testCurrentActorStackBalance() throws Exception
- {
- //create and set a test actor
- LogActor testActor = new TestLogActor(new NullRootMessageLogger());
- CurrentActor.set(testActor);
-
- //verify it is returned correctly before executing a HouseKeepingTask
- assertEquals("Expected LogActor was not returned", testActor, CurrentActor.get());
-
- final CountDownLatch latch = new CountDownLatch(1);
- HouseKeepingTask testTask = new HouseKeepingTask(new MockVirtualHost("HouseKeepingTaskTestVhost"))
- {
- @Override
- public void execute()
- {
- latch.countDown();
- }
- };
-
- //run the test HouseKeepingTask using the current Thread to influence its CurrentActor stack
- testTask.run();
-
- assertEquals("The expected LogActor was not returned, the CurrentActor stack has become unbalanced",
- testActor, CurrentActor.get());
- assertEquals("HouseKeepingTask execute() method was not run", 0, latch.getCount());
-
- //clean up the test actor
- CurrentActor.remove();
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java
deleted file mode 100644
index 7aa314bf22..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java
+++ /dev/null
@@ -1,271 +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;
-
-import java.util.UUID;
-
-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.management.ManagedObject;
-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.DurableConfigurationStore;
-import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.server.store.TransactionLog;
-
-public class MockVirtualHost implements VirtualHost
-{
- private String _name;
-
- public MockVirtualHost(String name)
- {
- _name = name;
- }
-
- public void close()
- {
-
- }
-
- public void createBrokerConnection(String transport, String host, int port,
- String vhost, boolean durable, String authMechanism,
- String username, String password)
- {
-
- }
-
- public IApplicationRegistry getApplicationRegistry()
- {
- return null;
- }
-
- public AuthenticationManager getAuthenticationManager()
- {
- return null;
- }
-
- public BindingFactory getBindingFactory()
- {
- return null;
- }
-
- public UUID getBrokerId()
- {
- return null;
- }
-
- public ConfigStore getConfigStore()
- {
- return null;
- }
-
- public VirtualHostConfiguration getConfiguration()
- {
- return null;
- }
-
- public IConnectionRegistry getConnectionRegistry()
- {
- return null;
- }
-
- public DurableConfigurationStore getDurableConfigurationStore()
- {
- return null;
- }
-
- public ExchangeFactory getExchangeFactory()
- {
- return null;
- }
-
- public ExchangeRegistry getExchangeRegistry()
- {
- return null;
- }
-
- public int getHouseKeepingActiveCount()
- {
- return 0;
- }
-
- public long getHouseKeepingCompletedTaskCount()
- {
- return 0;
- }
-
- public int getHouseKeepingPoolSize()
- {
- return 0;
- }
-
- public long getHouseKeepingTaskCount()
- {
- return 0;
- }
-
- public ManagedObject getManagedObject()
- {
- return null;
- }
-
- public MessageStore getMessageStore()
- {
- return null;
- }
-
- public String getName()
- {
- return _name;
- }
-
- public QueueRegistry getQueueRegistry()
- {
- return null;
- }
-
- public SecurityManager getSecurityManager()
- {
- return null;
- }
-
- public TransactionLog getTransactionLog()
- {
- return null;
- }
-
- public void removeBrokerConnection(BrokerLink brokerLink)
- {
-
- }
-
- public void scheduleHouseKeepingTask(long period, HouseKeepingTask task)
- {
-
- }
-
- public void setHouseKeepingPoolSize(int newSize)
- {
-
- }
-
- public BrokerConfig getBroker()
- {
- return null;
- }
-
- public String getFederationTag()
- {
- return null;
- }
-
- public void setBroker(BrokerConfig brokerConfig)
- {
-
- }
-
- public VirtualHostConfigType getConfigType()
- {
- return null;
- }
-
- public long getCreateTime()
- {
- return 0;
- }
-
- public UUID getId()
- {
- return null;
- }
-
- public ConfiguredObject<VirtualHostConfigType, VirtualHostConfig> getParent()
- {
- return null;
- }
-
- public boolean isDurable()
- {
- return false;
- }
-
- public StatisticsCounter getDataDeliveryStatistics()
- {
- return null;
- }
-
- public StatisticsCounter getDataReceiptStatistics()
- {
- return null;
- }
-
- public StatisticsCounter getMessageDeliveryStatistics()
- {
- return null;
- }
-
- public StatisticsCounter getMessageReceiptStatistics()
- {
- return null;
- }
-
- public void initialiseStatistics()
- {
-
- }
-
- public boolean isStatisticsEnabled()
- {
- return false;
- }
-
- public void registerMessageDelivered(long messageSize)
- {
-
- }
-
- public void registerMessageReceived(long messageSize, long timestamp)
- {
-
- }
-
- public void resetStatistics()
- {
-
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
-
- }
-} \ No newline at end of file
diff --git a/qpid/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java b/qpid/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java
index a39799a6b6..902b86f80b 100644
--- a/qpid/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java
+++ b/qpid/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java
@@ -481,7 +481,7 @@ public class GenerateLogMessages
// Only check the text inside the braces '{}'
int typeIndexEnd = parametersString[index].indexOf("}", typeIndex);
String typeString = parametersString[index].substring(typeIndex, typeIndexEnd);
- if (typeString.contains("number") || typeString.contains("choice"))
+ if (typeString.contains("number"))
{
type = "Number";
}
diff --git a/qpid/java/build.deps b/qpid/java/build.deps
index cfbd122527..aebd381bbc 100644
--- a/qpid/java/build.deps
+++ b/qpid/java/build.deps
@@ -17,6 +17,8 @@
# under the License.
#
+backport-util-concurrent=lib/backport-util-concurrent-2.2.jar
+
commons-beanutils-core=lib/commons-beanutils-core-1.8.0.jar
commons-cli=lib/commons-cli-1.0.jar
commons-codec=lib/commons-codec-1.3.jar
@@ -25,43 +27,88 @@ commons-configuration=lib/commons-configuration-1.6.jar
commons-digester=lib/commons-digester-1.8.1.jar
commons-lang=lib/commons-lang-2.2.jar
commons-logging=lib/commons-logging-1.0.4.jar
+commons-pool=lib/commons-pool-1.4.jar
derby-db=lib/derby-10.6.1.0.jar
geronimo-jms=lib/geronimo-jms_1.1_spec-1.0.jar
junit=lib/junit-3.8.1.jar
+junit4=lib/junit-4.4.jar
+
+jline=lib/jline-0.9.94.jar
log4j=lib/log4j-1.2.12.jar
-mina-core=lib/mina-core-1.1.7.jar
-mina-filter-ssl=lib/mina-filter-ssl-1.1.7.jar
+mina-core=lib/mina-core-1.0.1.jar
+mina-filter-ssl=lib/mina-filter-ssl-1.0.1.jar
slf4j-api=lib/slf4j-api-1.6.1.jar
slf4j-log4j=lib/slf4j-log4j12-1.6.1.jar
xalan=lib/xalan-2.7.0.jar
+muse-core=lib/muse-core-2.2.0.jar
+muse-platform-mini=lib/muse-platform-mini-2.2.0.jar
+muse-util=lib/muse-util-2.2.0.jar
+muse-util-qname=lib/muse-util-qname-2.2.0.jar
+muse-util-xml=lib/muse-util-xml-2.2.0.jar
+muse-wsa-soap=lib/muse-wsa-soap-2.2.0.jar
+muse-wsdm-muws-adv-api=lib/muse-wsdm-muws-adv-api-2.2.0.jar
+muse-wsdm-muws-adv-impl=lib/muse-wsdm-muws-adv-impl-2.2.0.jar
+muse-wsdm-muws-api=lib/muse-wsdm-muws-api-2.2.0.jar
+muse-wsdm-muws-impl=lib/muse-wsdm-muws-impl-2.2.0.jar
+muse-wsdm-wef-api=lib/muse-wsdm-wef-api-2.2.0.jar
+muse-wsdm-wef-impl=lib/muse-wsdm-wef-impl-2.2.0.jar
+muse-wsn-api=lib/muse-wsn-api-2.2.0.jar
+muse-wsn-impl=lib/muse-wsn-impl-2.2.0.jar
+muse-wsrf-api=lib/muse-wsrf-api-2.2.0.jar
+muse-wsrf-impl=lib/muse-wsrf-impl-2.2.0.jar
+muse-wsrf-rmd=lib/muse-wsrf-rmd-2.2.0.jar
+muse-wsx-api=lib/muse-wsx-api-2.2.0.jar
+muse-wsx-impl=lib/muse-wsx-impl-2.2.0.jar
+wsdl4j=lib/wsdl4j-1.6.1.jar
+xercesImpl=lib/xercesImpl-2.8.1.jar
+xml-apis=lib/xml-apis-1.3.03.jar
+javassist=lib/javassist.jar
jetty=lib/jetty-6.1.14.jar
jetty-util=lib/jetty-util-6.1.14.jar
jetty-servlet-tester=lib/jetty-servlet-tester-6.1.14.jar
+jetty-bootstrap=lib/start.jar
+jsp-api=lib/jsp-api-2.1.jar
+jsp-impl=lib/jsp-2.1.jar
+core-lib=lib/core-3.1.1.jar
servlet-api=lib/servlet-api.jar
+muse.libs = ${muse-core} ${muse-platform-mini} ${muse-util} ${muse-util-qname} \
+${muse-util-xml} ${muse-wsa-soap} ${muse-wsdm-muws-adv-api} ${muse-wsdm-muws-adv-impl} \
+${muse-wsdm-muws-api} ${muse-wsdm-muws-impl} ${muse-wsdm-wef-api} ${muse-wsdm-wef-impl} \
+${muse-wsn-api} ${muse-wsn-impl} ${muse-wsrf-api} ${muse-wsrf-impl} ${muse-wsrf-rmd} \
+${muse-wsx-api} ${muse-wsx-impl} ${wsdl4j} ${xercesImpl} ${xml-apis} ${jetty} ${jetty-util} ${jetty-bootstrap}
+
+jsp.libs = ${jsp-api} ${jsp-impl} ${core-lib}
+
osgi-core=lib/org.osgi.core-1.0.0.jar
felix-framework=lib/org.apache.felix.framework-2.0.5.jar
+geronimo-servlet=lib/geronimo-servlet_2.5_spec-1.2.jar
felix.libs=${osgi-core} ${felix-framework}
commons-configuration.libs = ${commons-beanutils-core} ${commons-digester} \
${commons-codec} ${commons-lang} ${commons-collections} ${commons-configuration}
-common.libs=${slf4j-api} ${mina-core} ${mina-filter-ssl}
+common.libs=${slf4j-api} ${backport-util-concurrent} ${mina-core} ${mina-filter-ssl}
client.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}
-broker-plugins.libs=${felix.libs} ${log4j} ${commons-configuration.libs}
+broker-plugins.libs=${felix.libs} ${log4j} ${commons-configuration.libs}
+management-client.libs=${jsp.libs} ${log4j} ${slf4j-log4j} ${slf4j-api} \
+ ${commons-pool} ${geronimo-servlet} ${muse.libs} ${javassist} ${xalan}
+
+management-agent.libs=${commons-logging}
+management-console.libs=${commons-logging}
junit-toolkit.libs=${log4j} ${junit} ${slf4j-api}
test.libs=${slf4j-log4j} ${junit-toolkit.libs}
@@ -128,6 +175,9 @@ management-eclipse-plugin.platform-libs=${ecl-equinox-launcher-win32-win32-x86}
management-eclipse-plugin.libs=${management-eclipse-plugin.core-libs} ${management-eclipse-plugin.platform-libs}
+
+management-tools-qpid-cli.libs=${jline} ${commons-configuration.libs}
+
common.test.libs=${test.libs}
broker.test.libs=${test.libs}
client.test.libs=${test.libs}
@@ -139,5 +189,9 @@ systests.libs=${test.libs}
broker-plugins.test.libs=${test.libs}
broker-plugins-experimental-info.test.libs=${test.libs} ${servlet-api} ${jetty} ${jetty-util} ${jetty-servlet-tester}
+management-client.test.libs=${muse.libs} ${test.libs} ${log4j} ${javassist} ${geronimo-servlet} ${commons-pool}
+management-console.test.libs=${junit4} ${slf4j-log4j} ${log4j}
+management-agent.test.libs=${junit}
management-eclipse-plugin.test.libs=${systests.libs}
+management-tools-qpid-cli.test.libs=${junit4} ${slf4j-log4j} ${log4j}
management-common.test.libs=${test.libs}
diff --git a/qpid/java/build.xml b/qpid/java/build.xml
index b8441af3a5..9031166d76 100644
--- a/qpid/java/build.xml
+++ b/qpid/java/build.xml
@@ -22,17 +22,18 @@
<import file="common.xml"/>
+
<findSubProjects name="broker-plugins" dir="broker-plugins"/>
- <findSubProjects name="client-plugins" dir="client-plugins" erroronmissingdir="false"/>
- <findSubProjects name="management" dir="management" excludes="common,example"/>
+ <findSubProjects name="management" dir="management" excludes="common,example,tools/qpid-cli"/>
<property name="modules.core" value="junit-toolkit common management/common broker client tools"/>
<property name="modules.examples" value="client/example management/example"/>
<property name="modules.tests" value="systests perftests integrationtests testkit"/>
<property name="modules.management" value="${management}"/>
- <property name="modules.plugin" value="${broker-plugins} ${client-plugins}"/>
+ <property name="modules.plugin" value="${broker-plugins}"/>
+ <property name="modules.management.tools" value="management/tools/qpid-cli"/>
<property name="modules" value="${modules.core} ${modules.examples}
- ${modules.management} ${modules.tests} ${modules.plugin}"/>
+ ${modules.management} ${modules.management.tools} ${modules.tests} ${modules.plugin}"/>
<property name="qpid.jar" location="${build.lib}/qpid-all.jar"/>
<basename property="qpid.jar.name" file="${qpid.jar}"/>
@@ -92,10 +93,6 @@
<fail if="failed" message="TEST SUITE FAILED"/>
</target>
-
- <target name="report-module" description="generate junitreport for modules">
- <iterate target="report-module"/>
- </target>
<target name="jar" description="create module jars">
<iterate target="jar"/>
@@ -216,18 +213,7 @@
<include name="**/*.ser"/>
</fileset>
</cobertura-merge>
- <cobertura-report format="xml"
- destdir="${build.coveragereport}"
- datafile="${build.coveragereport}/cobertura.ser"
- >
- <fileset dir="${project.root}/common/src/main/java" includes="**/*.java" />
- <fileset dir="${project.root}/build/scratch/common/src" includes="**/*.java" />
- <fileset dir="${project.root}/broker/src/main/java" includes="**/*.java" />
- <fileset dir="${project.root}/build/scratch/broker/src" includes="**/*.java" />
- <fileset dir="${project.root}/client/src/main/java" includes="**/*.java" />
- <fileset dir="${project.root}/build/scratch/client/src" includes="**/*.java" />
- </cobertura-report>
- <cobertura-report format="html"
+ <cobertura-report format="html"
destdir="${build.coveragereport}"
datafile="${build.coveragereport}/cobertura.ser"
>
@@ -291,7 +277,4 @@
</findbugs>
</target>
- <target name="eclipse" description="build eclipse project and classpath files">
- <iterate target="eclipse"/>
- </target>
</project>
diff --git a/qpid/java/client/README.txt b/qpid/java/client/README.txt
index b9cde71db3..57a98cc978 100644
--- a/qpid/java/client/README.txt
+++ b/qpid/java/client/README.txt
@@ -24,7 +24,7 @@ run more easily.
E.g, in order to run the Hello example, you would add the client+example library
files to the java classpath and launch the example like follows:
-java -cp "lib/qpid-all.jar:example/lib/qpid-client-example-<version>.jar" \
+java -cp "lib/qpid-all.jar:example/lib/qpid-client-examples-<version>.jar" \
org.apache.qpid.example.Hello
NOTE: The client uses the SL4FJ API for its logging. You must supply a logging
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java
index 0734704e59..c4edd9034f 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java
@@ -33,6 +33,7 @@ import java.util.Properties;
* It is equivalent to a PropertyFile of value:
*
* connectionfactory.local=amqp://guest:guest@clientid/test?brokerlist='localhost'
+ * connectionfactory.vm=amqp://guest:guest@clientid/test?brokerlist='vm://:1'
*
* queue.queue=example.MyQueue
* topic.topic=example.hierarical.topic
@@ -49,7 +50,7 @@ public class ConnectionSetup
final static String QUEUE_NAME = "example.MyQueue";
public static final String TOPIC_JNDI_NAME = "topic";
- final static String TOPIC_NAME = "usa.news";
+ final static String TOPIC_NAME = "example.hierarical.topic";
private Context _ctx;
@@ -60,6 +61,7 @@ public class ConnectionSetup
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
properties.put("connectionfactory." + CONNECTION_JNDI_NAME, CONNECTION_NAME);
+ properties.put("connectionfactory." + "vm", "amqp://guest:guest@clientid/test?brokerlist='vm://:1'");
properties.put("queue." + QUEUE_JNDI_NAME, QUEUE_NAME);
properties.put("topic." + TOPIC_JNDI_NAME, TOPIC_NAME);
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java
index ac3829d49e..dd936e429f 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java
@@ -71,7 +71,7 @@ public class Publisher extends Client
public static void main(String[] args)
{
- String destination = args.length > 2 ? args[1] : "usa.news";
+ String destination = args.length > 2 ? args[1] : null;
int msgCount = args.length > 2 ? Integer.parseInt(args[2]) : 100;
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/transport/ExistingSocketConnectorDemo.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/transport/ExistingSocketConnectorDemo.java
new file mode 100644
index 0000000000..d7eb138523
--- /dev/null
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/transport/ExistingSocketConnectorDemo.java
@@ -0,0 +1,171 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.transport;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.transport.TransportConnection;
+import org.apache.qpid.jms.ConnectionListener;
+import org.apache.qpid.url.URLSyntaxException;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.nio.channels.SocketChannel;
+import java.util.UUID;
+
+/**
+ * This is a simple application that demonstrates how you can use the Qpid AMQP interfaces to use existing sockets as
+ * the transport for the Client API.
+ *
+ * The Demo here runs twice:
+ * 1. Just to show a simple publish and receive.
+ * 2. To demonstrate how to use existing sockets and utilise the underlying client failover mechnaism.
+ */
+public class ExistingSocketConnectorDemo implements ConnectionListener
+{
+ private static boolean DEMO_FAILOVER = false;
+
+ public static void main(String[] args) throws IOException, URLSyntaxException, AMQException, JMSException
+ {
+ System.out.println("Testing socket connection to localhost:5672.");
+
+ new ExistingSocketConnectorDemo();
+
+ System.out.println("Testing socket connection failover between localhost:5672 and localhost:5673.");
+
+ DEMO_FAILOVER = true;
+
+ new ExistingSocketConnectorDemo();
+ }
+
+ Connection _connection;
+ MessageProducer _producer;
+ Session _session;
+
+ String Socket1_ID = UUID.randomUUID().toString();
+ String Socket2_ID = UUID.randomUUID().toString();
+
+
+
+ /** Here we can see the broker we are connecting to is set to be 'socket:///' signifying we will provide the socket. */
+ public final String CONNECTION = "amqp://guest:guest@id/test?brokerlist='socket://" + Socket1_ID + ";socket://" + Socket2_ID + "'";
+
+
+ public ExistingSocketConnectorDemo() throws IOException, URLSyntaxException, AMQException, JMSException
+ {
+
+ Socket socket = SocketChannel.open().socket();
+ socket.connect(new InetSocketAddress("localhost", 5672));
+
+ TransportConnection.registerOpenSocket(Socket1_ID, socket);
+
+
+ _connection = new AMQConnection(CONNECTION);
+
+ _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer consumer = _session.createConsumer(_session.createQueue("Queue"));
+
+ _producer = _session.createProducer(_session.createQueue("Queue"));
+
+ _connection.start();
+
+ if (!DEMO_FAILOVER)
+ {
+ _producer.send(_session.createTextMessage("Simple Test"));
+ }
+ else
+ {
+ // Using the Qpid interfaces we can set a listener that allows us to demonstrate failover
+ ((AMQConnection) _connection).setConnectionListener(this);
+
+ System.out.println("Testing failover: Please ensure second broker running on localhost:5673 and shutdown broker on 5672.");
+ }
+
+ //We do a blocking receive here so that we can demonstrate failover.
+ Message message = consumer.receive();
+
+ System.out.println("Recevied :" + message);
+
+ _connection.close();
+ }
+
+ // ConnectionListener Interface
+
+ public void bytesSent(long count)
+ {
+ //not used in this example
+ }
+ public void bytesReceived(long count)
+ {
+ //not used in this example
+ }
+
+ public boolean preFailover(boolean redirect)
+ {
+ /**
+ * This method is called before the underlying client library starts to reconnect. This gives us the opportunity
+ * to set a new socket for the failover to occur on.
+ */
+ try
+ {
+ Socket socket = SocketChannel.open().socket();
+
+ socket.connect(new InetSocketAddress("localhost", 5673));
+
+ // This is the new method to pass in an open socket for the connection to use.
+ TransportConnection.registerOpenSocket(Socket2_ID, socket);
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ public boolean preResubscribe()
+ {
+ //not used in this example - but must return true to allow the resubscription of existing clients.
+ return true;
+ }
+
+ public void failoverComplete()
+ {
+ // Now that failover has completed we can send a message that the receiving thread will pick up
+ try
+ {
+ _producer.send(_session.createTextMessage("Simple Failover Test"));
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/client/src/main/java/client.bnd b/qpid/java/client/src/main/java/client.bnd
index 98696dc7d8..0ddd163d4f 100755
--- a/qpid/java/client/src/main/java/client.bnd
+++ b/qpid/java/client/src/main/java/client.bnd
@@ -17,7 +17,7 @@
# under the License.
#
-ver: 0.13.0
+ver: 0.9.0
Bundle-SymbolicName: qpid-client
Bundle-Version: ${ver}
diff --git a/qpid/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java b/qpid/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java
new file mode 100644
index 0000000000..98716c0c3c
--- /dev/null
+++ b/qpid/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java
@@ -0,0 +1,478 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.mina.transport.socket.nio;
+
+import edu.emory.mathcs.backport.java.util.concurrent.Executor;
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoConnectorConfig;
+import org.apache.mina.common.IoHandler;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.common.support.BaseIoConnector;
+import org.apache.mina.common.support.DefaultConnectFuture;
+import org.apache.mina.util.NamePreservingRunnable;
+import org.apache.mina.util.NewThreadExecutor;
+import org.apache.mina.util.Queue;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * {@link IoConnector} for socket transport (TCP/IP).
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 627427 $, $Date: 2008-02-13 14:39:10 +0000 (Wed, 13 Feb 2008) $
+ */
+public class ExistingSocketConnector extends BaseIoConnector
+{
+ /** @noinspection StaticNonFinalField */
+ private static volatile int nextId = 0;
+
+ private final Object lock = new Object();
+ private final int id = nextId++;
+ private final String threadName = "SocketConnector-" + id;
+ private SocketConnectorConfig defaultConfig = new SocketConnectorConfig();
+ private final Queue connectQueue = new Queue();
+ private final SocketIoProcessor[] ioProcessors;
+ private final int processorCount;
+ private final Executor executor;
+
+ /** @noinspection FieldAccessedSynchronizedAndUnsynchronized */
+ private Selector selector;
+ private Worker worker;
+ private int processorDistributor = 0;
+ private int workerTimeout = 60; // 1 min.
+ private Socket _openSocket = null;
+
+ /** Create a connector with a single processing thread using a NewThreadExecutor */
+ public ExistingSocketConnector()
+ {
+ this(1, new NewThreadExecutor());
+ }
+
+ /**
+ * Create a connector with the desired number of processing threads
+ *
+ * @param processorCount Number of processing threads
+ * @param executor Executor to use for launching threads
+ */
+ public ExistingSocketConnector(int processorCount, Executor executor)
+ {
+ if (processorCount < 1)
+ {
+ throw new IllegalArgumentException("Must have at least one processor");
+ }
+
+ this.executor = executor;
+ this.processorCount = processorCount;
+ ioProcessors = new SocketIoProcessor[processorCount];
+
+ for (int i = 0; i < processorCount; i++)
+ {
+ ioProcessors[i] = new SocketIoProcessor("SocketConnectorIoProcessor-" + id + "." + i, executor);
+ }
+ }
+
+ /**
+ * How many seconds to keep the connection thread alive between connection requests
+ *
+ * @return Number of seconds to keep connection thread alive
+ */
+ public int getWorkerTimeout()
+ {
+ return workerTimeout;
+ }
+
+ /**
+ * Set how many seconds the connection worker thread should remain alive once idle before terminating itself.
+ *
+ * @param workerTimeout Number of seconds to keep thread alive. Must be >=0
+ */
+ public void setWorkerTimeout(int workerTimeout)
+ {
+ if (workerTimeout < 0)
+ {
+ throw new IllegalArgumentException("Must be >= 0");
+ }
+ this.workerTimeout = workerTimeout;
+ }
+
+ public ConnectFuture connect(SocketAddress address, IoHandler handler, IoServiceConfig config)
+ {
+ return connect(address, null, handler, config);
+ }
+
+ public ConnectFuture connect(SocketAddress address, SocketAddress localAddress,
+ IoHandler handler, IoServiceConfig config)
+ {
+ /** Changes here from the Mina OpenSocketConnector.
+ * Ignoreing all address as they are not needed */
+
+ if (handler == null)
+ {
+ throw new NullPointerException("handler");
+ }
+
+
+ if (config == null)
+ {
+ config = getDefaultConfig();
+ }
+
+ if (_openSocket == null)
+ {
+ throw new IllegalArgumentException("Specifed Socket not active");
+ }
+
+ boolean success = false;
+
+ try
+ {
+ DefaultConnectFuture future = new DefaultConnectFuture();
+ newSession(_openSocket, handler, config, future);
+ success = true;
+ return future;
+ }
+ catch (IOException e)
+ {
+ return DefaultConnectFuture.newFailedFuture(e);
+ }
+ finally
+ {
+ if (!success && _openSocket != null)
+ {
+ try
+ {
+ _openSocket.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ }
+ }
+ }
+
+ public IoServiceConfig getDefaultConfig()
+ {
+ return defaultConfig;
+ }
+
+ /**
+ * Sets the config this connector will use by default.
+ *
+ * @param defaultConfig the default config.
+ *
+ * @throws NullPointerException if the specified value is <code>null</code>.
+ */
+ public void setDefaultConfig(SocketConnectorConfig defaultConfig)
+ {
+ if (defaultConfig == null)
+ {
+ throw new NullPointerException("defaultConfig");
+ }
+ this.defaultConfig = defaultConfig;
+ }
+
+ private synchronized void startupWorker() throws IOException
+ {
+ if (worker == null)
+ {
+ selector = Selector.open();
+ worker = new Worker();
+ executor.execute(new NamePreservingRunnable(worker));
+ }
+ }
+
+ private void registerNew()
+ {
+ if (connectQueue.isEmpty())
+ {
+ return;
+ }
+
+ for (; ;)
+ {
+ ConnectionRequest req;
+ synchronized (connectQueue)
+ {
+ req = (ConnectionRequest) connectQueue.pop();
+ }
+
+ if (req == null)
+ {
+ break;
+ }
+
+ SocketChannel ch = req.channel;
+ try
+ {
+ ch.register(selector, SelectionKey.OP_CONNECT, req);
+ }
+ catch (IOException e)
+ {
+ req.setException(e);
+ }
+ }
+ }
+
+ private void processSessions(Set keys)
+ {
+ Iterator it = keys.iterator();
+
+ while (it.hasNext())
+ {
+ SelectionKey key = (SelectionKey) it.next();
+
+ if (!key.isConnectable())
+ {
+ continue;
+ }
+
+ SocketChannel ch = (SocketChannel) key.channel();
+ ConnectionRequest entry = (ConnectionRequest) key.attachment();
+
+ boolean success = false;
+ try
+ {
+ ch.finishConnect();
+ newSession(ch, entry.handler, entry.config, entry);
+ success = true;
+ }
+ catch (Throwable e)
+ {
+ entry.setException(e);
+ }
+ finally
+ {
+ key.cancel();
+ if (!success)
+ {
+ try
+ {
+ ch.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ }
+ }
+ }
+
+ keys.clear();
+ }
+
+ private void processTimedOutSessions(Set keys)
+ {
+ long currentTime = System.currentTimeMillis();
+ Iterator it = keys.iterator();
+
+ while (it.hasNext())
+ {
+ SelectionKey key = (SelectionKey) it.next();
+
+ if (!key.isValid())
+ {
+ continue;
+ }
+
+ ConnectionRequest entry = (ConnectionRequest) key.attachment();
+
+ if (currentTime >= entry.deadline)
+ {
+ entry.setException(new ConnectException());
+ try
+ {
+ key.channel().close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ finally
+ {
+ key.cancel();
+ }
+ }
+ }
+ }
+
+ private void newSession(Socket socket, IoHandler handler, IoServiceConfig config, ConnectFuture connectFuture)
+ throws IOException
+ {
+ SocketSessionImpl session = new SocketSessionImpl(this,
+ nextProcessor(),
+ getListeners(),
+ config,
+ socket.getChannel(),
+ handler,
+ socket.getRemoteSocketAddress());
+
+ newSession(session, config, connectFuture);
+ }
+
+ private void newSession(SocketChannel ch, IoHandler handler, IoServiceConfig config, ConnectFuture connectFuture)
+ throws IOException
+
+ {
+ SocketSessionImpl session = new SocketSessionImpl(this,
+ nextProcessor(),
+ getListeners(),
+ config,
+ ch,
+ handler,
+ ch.socket().getRemoteSocketAddress());
+
+ newSession(session, config, connectFuture);
+ }
+
+ private void newSession(SocketSessionImpl session, IoServiceConfig config, ConnectFuture connectFuture)
+ throws IOException
+ {
+ try
+ {
+ getFilterChainBuilder().buildFilterChain(session.getFilterChain());
+ config.getFilterChainBuilder().buildFilterChain(session.getFilterChain());
+ config.getThreadModel().buildFilterChain(session.getFilterChain());
+ }
+ catch (Throwable e)
+ {
+ throw (IOException) new IOException("Failed to create a session.").initCause(e);
+ }
+ session.getIoProcessor().addNew(session);
+ connectFuture.setSession(session);
+ }
+
+ private SocketIoProcessor nextProcessor()
+ {
+ return ioProcessors[processorDistributor++ % processorCount];
+ }
+
+ public void setOpenSocket(Socket openSocket)
+ {
+ _openSocket = openSocket;
+ }
+
+ private class Worker implements Runnable
+ {
+ private long lastActive = System.currentTimeMillis();
+
+ public void run()
+ {
+ Thread.currentThread().setName(ExistingSocketConnector.this.threadName);
+
+ for (; ;)
+ {
+ try
+ {
+ int nKeys = selector.select(1000);
+
+ registerNew();
+
+ if (nKeys > 0)
+ {
+ processSessions(selector.selectedKeys());
+ }
+
+ processTimedOutSessions(selector.keys());
+
+ if (selector.keys().isEmpty())
+ {
+ if (System.currentTimeMillis() - lastActive > workerTimeout * 1000L)
+ {
+ synchronized (lock)
+ {
+ if (selector.keys().isEmpty() &&
+ connectQueue.isEmpty())
+ {
+ worker = null;
+ try
+ {
+ selector.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ finally
+ {
+ selector = null;
+ }
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ lastActive = System.currentTimeMillis();
+ }
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e1)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e1);
+ }
+ }
+ }
+ }
+ }
+
+ private class ConnectionRequest extends DefaultConnectFuture
+ {
+ private final SocketChannel channel;
+ private final long deadline;
+ private final IoHandler handler;
+ private final IoServiceConfig config;
+
+ private ConnectionRequest(SocketChannel channel, IoHandler handler, IoServiceConfig config)
+ {
+ this.channel = channel;
+ long timeout;
+ if (config instanceof IoConnectorConfig)
+ {
+ timeout = ((IoConnectorConfig) config).getConnectTimeoutMillis();
+ }
+ else
+ {
+ timeout = ((IoConnectorConfig) getDefaultConfig()).getConnectTimeoutMillis();
+ }
+ this.deadline = System.currentTimeMillis() + timeout;
+ this.handler = handler;
+ this.config = config;
+ }
+ }
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java
index 999b22299c..a201f7d61e 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java
@@ -72,17 +72,6 @@ public class AMQAnyDestination extends AMQDestination implements Queue, Topic
public String getTopicName() throws JMSException
{
- if (getRoutingKey() != null)
- {
- return getRoutingKey().asString();
- }
- else if (getSubject() != null)
- {
- return getSubject();
- }
- else
- {
- return null;
- }
+ return super.getRoutingKey().toString();
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
index c8576bf00d..ee52cd50af 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
@@ -56,7 +56,9 @@ public class AMQBrokerDetails implements BrokerDetails
if (transport != null)
{
//todo this list of valid transports should be enumerated somewhere
- if (!(transport.equalsIgnoreCase(BrokerDetails.TCP)))
+ if ((!(transport.equalsIgnoreCase(BrokerDetails.VM) ||
+ transport.equalsIgnoreCase(BrokerDetails.TCP) ||
+ transport.equalsIgnoreCase(BrokerDetails.SOCKET))))
{
if (transport.equalsIgnoreCase("localhost"))
{
@@ -103,21 +105,6 @@ public class AMQBrokerDetails implements BrokerDetails
if (host == null)
{
host = "";
-
- String auth = connection.getAuthority();
- if (auth != null)
- {
- // contains both host & port myhost:5672
- if (auth.contains(":"))
- {
- host = auth.substring(0,auth.indexOf(":"));
- }
- else
- {
- host = auth;
- }
- }
-
}
setHost(host);
@@ -180,7 +167,10 @@ public class AMQBrokerDetails implements BrokerDetails
}
else
{
- setPort(port);
+ if (!_transport.equalsIgnoreCase(SOCKET))
+ {
+ setPort(port);
+ }
}
String queryString = connection.getQuery();
@@ -296,9 +286,17 @@ public class AMQBrokerDetails implements BrokerDetails
sb.append(_transport);
sb.append("://");
- sb.append(_host);
- sb.append(':');
- sb.append(_port);
+
+ if (!(_transport.equalsIgnoreCase(VM)))
+ {
+ sb.append(_host);
+ }
+
+ if (!(_transport.equalsIgnoreCase(SOCKET)))
+ {
+ sb.append(':');
+ sb.append(_port);
+ }
sb.append(printOptionsURL());
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
index 4a62f443f1..ab59fee020 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
@@ -111,7 +111,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
/** Maps from session id (Integer) to AMQSession instance */
private final ChannelToSessionMap _sessions = new ChannelToSessionMap();
- private final String _clientName;
+ private String _clientName;
/** The user name to use for authentication */
private String _username;
@@ -126,7 +126,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
private ConnectionListener _connectionListener;
- private final ConnectionURL _connectionURL;
+ private ConnectionURL _connectionURL;
/**
* Whether this connection is started, i.e. whether messages are flowing to consumers. It has no meaning for message
@@ -173,8 +173,8 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
//Indicates the sync publish options (persistent|all)
//By default it's async publish
private String _syncPublish = "";
-
- // Indicates whether to use the old map message format or the
+
+ // Indicates whether to use the old map message format or the
// new amqp-0-10 encoded format.
private boolean _useLegacyMapMessageFormat;
@@ -257,11 +257,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
*/
public AMQConnection(ConnectionURL connectionURL, SSLConfiguration sslConfig) throws AMQException
{
- if (connectionURL == null)
- {
- throw new IllegalArgumentException("Connection must be specified");
- }
-
// set this connection maxPrefetch
if (connectionURL.getOption(ConnectionURL.OPTIONS_MAXPREFETCH) != null)
{
@@ -269,7 +264,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
else
{
- // use the default value set for all connections
+ // use the defaul value set for all connections
_maxPrefetch = Integer.parseInt(System.getProperties().getProperty(ClientProperties.MAX_PREFETCH_PROP_NAME,
ClientProperties.MAX_PREFETCH_DEFAULT));
}
@@ -283,7 +278,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
else
{
- // use the default value set for all connections
+ // use the defaul value set for all connections
_syncPersistence = Boolean.getBoolean(ClientProperties.SYNC_PERSISTENT_PROP_NAME);
if (_syncPersistence)
{
@@ -298,7 +293,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
else
{
- // use the default value set for all connections
+ // use the defaul value set for all connections
_syncAck = Boolean.getBoolean(ClientProperties.SYNC_ACK_PROP_NAME);
}
@@ -311,7 +306,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
// use the default value set for all connections
_syncPublish = System.getProperty((ClientProperties.SYNC_PUBLISH_PROP_NAME),_syncPublish);
}
-
+
if (connectionURL.getOption(ConnectionURL.OPTIONS_USE_LEGACY_MAP_MESSAGE_FORMAT) != null)
{
_useLegacyMapMessageFormat = Boolean.parseBoolean(
@@ -322,16 +317,16 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
// use the default value set for all connections
_useLegacyMapMessageFormat = Boolean.getBoolean(ClientProperties.USE_LEGACY_MAP_MESSAGE_FORMAT);
}
-
+
String amqpVersion = System.getProperty((ClientProperties.AMQP_VERSION), "0-10");
_logger.debug("AMQP version " + amqpVersion);
-
+
_failoverPolicy = new FailoverPolicy(connectionURL, this);
BrokerDetails brokerDetails = _failoverPolicy.getCurrentBrokerDetails();
- if ("0-8".equals(amqpVersion))
+ if (brokerDetails.getTransport().equals(BrokerDetails.VM) || "0-8".equals(amqpVersion))
{
_delegate = new AMQConnectionDelegate_8_0(this);
- }
+ }
else if ("0-9".equals(amqpVersion))
{
_delegate = new AMQConnectionDelegate_0_9(this);
@@ -351,6 +346,11 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
_sslConfiguration = sslConfig;
+ if (connectionURL == null)
+ {
+ throw new IllegalArgumentException("Connection must be specified");
+ }
+
_connectionURL = connectionURL;
_clientName = connectionURL.getClientName();
@@ -418,7 +418,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
brokerDetails = _failoverPolicy.getNextBrokerDetails();
}
}
- verifyClientID();
if (_logger.isDebugEnabled())
{
@@ -505,7 +504,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
Class partypes[] = new Class[1];
partypes[0] = AMQConnection.class;
_delegate = (AMQConnectionDelegate) c.getConstructor(partypes).newInstance(this);
- //Update our session to use this new protocol version
+ //Update our session to use this new protocol version
_protocolHandler.getProtocolSession().setProtocolVersion(_delegate.getProtocolVersion());
}
@@ -536,6 +535,14 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
}
+ protected AMQConnection(String username, String password, String clientName, String virtualHost)
+ {
+ _clientName = clientName;
+ _username = username;
+ _password = password;
+ setVirtualHost(virtualHost);
+ }
+
private void setVirtualHost(String virtualHost)
{
if (virtualHost != null && virtualHost.startsWith("/"))
@@ -689,6 +696,20 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
}
+ private void reopenChannel(int channelId, int prefetchHigh, int prefetchLow, boolean transacted)
+ throws AMQException, FailoverException
+ {
+ try
+ {
+ createChannelOverWire(channelId, prefetchHigh, prefetchLow, transacted);
+ }
+ catch (AMQException e)
+ {
+ deregisterSession(channelId);
+ throw new AMQException(null, "Error reopening channel " + channelId + " after failover: " + e, e);
+ }
+ }
+
public void setFailoverPolicy(FailoverPolicy policy)
{
_failoverPolicy = policy;
@@ -1075,7 +1096,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
_username = id;
}
-
+
public String getPassword()
{
return _password;
@@ -1251,7 +1272,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
je.setLinkedException((Exception) cause);
}
-
+
je.initCause(cause);
}
@@ -1284,7 +1305,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
_logger.info("Not a hard-error connection not closing: " + cause);
}
-
+
// deliver the exception if there is a listener
if (_exceptionListener != null)
{
@@ -1294,7 +1315,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
_logger.error("Throwable Received but no listener set: " + cause);
}
-
+
// if we are closing the connection, close sessions first
if (closer)
{
@@ -1351,20 +1372,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
return buf.toString();
}
- /**
- * Returns connection url.
- * @return connection url
- */
- public ConnectionURL getConnectionURL()
- {
- return _connectionURL;
- }
-
- /**
- * Returns stringified connection url. This url is suitable only for display
- * as {@link AMQConnectionURL#toString()} converts any password to asterisks.
- * @return connection url
- */
public String toURL()
{
return _connectionURL.toString();
@@ -1435,18 +1442,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
return _delegate.getProtocolVersion();
}
-
- public String getBrokerUUID()
- {
- if(getProtocolVersion().equals(ProtocolVersion.v0_10))
- {
- return ((AMQConnectionDelegate_0_10)_delegate).getUUID();
- }
- else
- {
- return null;
- }
- }
+
public boolean isFailingOver()
{
return (_protocolHandler.getFailoverLatch() != null);
@@ -1489,24 +1485,9 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
return _sessions.getNextChannelId();
}
-
+
public boolean isUseLegacyMapMessageFormat()
{
return _useLegacyMapMessageFormat;
}
-
- private void verifyClientID() throws AMQException
- {
- if (Boolean.getBoolean(ClientProperties.QPID_VERIFY_CLIENT_ID))
- {
- try
- {
- _delegate.verifyClientID();
- }
- catch(JMSException e)
- {
- throw new AMQException(AMQConstant.ALREADY_EXISTS,"ClientID must be unique",e);
- }
- }
- }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java
index 5acdaaa185..9560bd5c7c 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java
@@ -57,12 +57,10 @@ public interface AMQConnectionDelegate
void closeConnection(long timeout) throws JMSException, AMQException;
<T, E extends Exception> T executeRetrySupport(FailoverProtectedOperation<T,E> operation) throws E;
-
+
int getMaxChannelID();
int getMinChannelID();
ProtocolVersion getProtocolVersion();
-
- void verifyClientID() throws JMSException;
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java
index cb531d4fca..b0bd8f8e97 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java
@@ -47,7 +47,6 @@ import org.apache.qpid.transport.ConnectionException;
import org.apache.qpid.transport.ConnectionListener;
import org.apache.qpid.transport.ConnectionSettings;
import org.apache.qpid.transport.ProtocolVersionException;
-import org.apache.qpid.transport.SessionDetachCode;
import org.apache.qpid.transport.TransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,11 +57,7 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
* This class logger.
*/
private static final Logger _logger = LoggerFactory.getLogger(AMQConnectionDelegate_0_10.class);
-
- /**
- * The name of the UUID property
- */
- private static final String UUID_NAME = "qpid.federation_tag";
+
/**
* The AMQ Connection.
*/
@@ -74,12 +69,6 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
org.apache.qpid.transport.Connection _qpidConnection;
private ConnectionException exception = null;
- static
- {
- // Register any configured SASL client factories.
- org.apache.qpid.client.security.DynamicSaslRegistrar.registerSaslProviders();
- }
-
//--- constructor
public AMQConnectionDelegate_0_10(AMQConnection conn)
{
@@ -91,14 +80,7 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
/**
* create a Session and start it if required.
*/
-
public Session createSession(boolean transacted, int acknowledgeMode, int prefetchHigh, int prefetchLow)
- throws JMSException
- {
- return createSession(transacted,acknowledgeMode,prefetchHigh,prefetchLow,null);
- }
-
- public Session createSession(boolean transacted, int acknowledgeMode, int prefetchHigh, int prefetchLow, String name)
throws JMSException
{
_conn.checkNotClosed();
@@ -113,7 +95,7 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
try
{
session = new AMQSession_0_10(_qpidConnection, _conn, channelId, transacted, acknowledgeMode, prefetchHigh,
- prefetchLow,name);
+ prefetchLow);
_conn.registerSession(channelId, session);
if (_conn._started)
{
@@ -229,8 +211,6 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
public void resubscribeSessions() throws JMSException, AMQException, FailoverException
{
- _logger.info("Resuming connection");
- getQpidConnection().resume();
List<AMQSession> sessions = new ArrayList<AMQSession>(_conn.getSessions().values());
_logger.info(String.format("Resubscribing sessions = %s sessions.size=%d", sessions, sessions.size()));
for (AMQSession s : sessions)
@@ -347,11 +327,6 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
return ProtocolVersion.v0_10;
}
- public String getUUID()
- {
- return (String)_qpidConnection.getServerProperties().get(UUID_NAME);
- }
-
private void retriveConnectionSettings(ConnectionSettings conSettings, BrokerDetails brokerDetail)
{
@@ -466,31 +441,12 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
else
{
heartbeat = Integer.getInteger(ClientProperties.HEARTBEAT,ClientProperties.HEARTBEAT_DEFAULT);
- }
+ }
return heartbeat;
}
-
+
protected org.apache.qpid.transport.Connection getQpidConnection()
{
return _qpidConnection;
}
-
- public void verifyClientID() throws JMSException
- {
- int prefetch = (int)_conn.getMaxPrefetch();
- AMQSession_0_10 ssn = (AMQSession_0_10)createSession(false, 1,prefetch,prefetch,_conn.getClientID());
- org.apache.qpid.transport.Session ssn_0_10 = ssn.getQpidSession();
- try
- {
- ssn_0_10.awaitOpen();
- }
- catch(Exception e)
- {
- if (ssn_0_10.getDetachCode() != null &&
- ssn_0_10.getDetachCode() == SessionDetachCode.SESSION_BUSY)
- {
- throw new JMSException("ClientID must be unique");
- }
- }
- }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
index 0cd1d49224..40b332d216 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
@@ -39,6 +39,7 @@ import org.apache.qpid.client.failover.FailoverRetrySupport;
import org.apache.qpid.client.protocol.AMQProtocolSession;
import org.apache.qpid.client.state.AMQState;
import org.apache.qpid.client.state.StateWaiter;
+import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.framing.BasicQosBody;
import org.apache.qpid.framing.BasicQosOkBody;
import org.apache.qpid.framing.ChannelOpenBody;
@@ -48,11 +49,6 @@ 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.ssl.SSLContextFactory;
-import org.apache.qpid.transport.ConnectionSettings;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.apache.qpid.transport.network.OutgoingNetworkTransport;
-import org.apache.qpid.transport.network.Transport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -93,21 +89,15 @@ public class AMQConnectionDelegate_8_0 implements AMQConnectionDelegate
StateWaiter waiter = _conn._protocolHandler.createWaiter(openOrClosedStates);
- ConnectionSettings settings = new ConnectionSettings();
- settings.setHost(brokerDetail.getHost());
- settings.setPort(brokerDetail.getPort());
- settings.setProtocol(brokerDetail.getTransport());
-
- SSLConfiguration sslConfig = _conn.getSSLConfiguration();
- SSLContextFactory sslFactory = null;
- if (sslConfig != null)
+ // TODO: use system property thingy for this
+ if (System.getProperty("UseTransportIo", "false").equals("false"))
{
- sslFactory = new SSLContextFactory(sslConfig.getKeystorePath(), sslConfig.getKeystorePassword(), sslConfig.getCertType());
+ TransportConnection.getInstance(brokerDetail).connect(_conn._protocolHandler, brokerDetail);
+ }
+ else
+ {
+ _conn.getProtocolHandler().createIoTransportSession(brokerDetail);
}
-
- OutgoingNetworkTransport transport = Transport.getOutgoingTransportInstance(getProtocolVersion());
- NetworkConnection network = transport.connect(settings, _conn._protocolHandler, sslFactory);
- _conn._protocolHandler.setNetworkConnection(network);
_conn._protocolHandler.getProtocolSession().init();
// this blocks until the connection has been set up or when an error
// has prevented the connection being set up
@@ -332,9 +322,4 @@ public class AMQConnectionDelegate_8_0 implements AMQConnectionDelegate
{
return ProtocolVersion.v8_0;
}
-
- public void verifyClientID() throws JMSException
- {
- // NOOP
- }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java
index f9f50d9150..93b4c51a8f 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java
@@ -27,14 +27,18 @@ import java.util.Map;
import org.apache.qpid.client.url.URLParser;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.jms.BrokerDetails;
import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.url.URLHelper;
import org.apache.qpid.url.URLSyntaxException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class AMQConnectionURL implements ConnectionURL
{
-
+ private static final Logger _logger = LoggerFactory.getLogger(AMQConnectionURL.class);
+
private String _url;
private String _failoverMethod;
private Map<String, String> _failoverOptions;
@@ -291,4 +295,17 @@ public class AMQConnectionURL implements ConnectionURL
return sb.toString();
}
+
+ public static void main(String[] args) throws URLSyntaxException
+ {
+ String url2 =
+ "amqp://ritchiem:bob@temp/testHost?brokerlist='tcp://localhost:5672;tcp://fancyserver:3000/',failover='roundrobin'";
+ // "amqp://user:pass@clientid/virtualhost?brokerlist='tcp://host:1?option1=\'value\',option2=\'value\';vm://:3?option1=\'value\'',failover='method?option1=\'value\',option2='value''";
+
+ ConnectionURL connectionurl2 = new AMQConnectionURL(url2);
+
+ System.out.println(url2);
+ System.out.println(connectionurl2);
+
+ }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
index 3ef32fb008..eb9682a3cf 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
@@ -21,6 +21,8 @@
package org.apache.qpid.client;
import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import javax.jms.Destination;
@@ -32,6 +34,8 @@ import javax.naming.StringRefAddr;
import org.apache.qpid.client.messaging.address.AddressHelper;
import org.apache.qpid.client.messaging.address.Link;
import org.apache.qpid.client.messaging.address.Node;
+import org.apache.qpid.client.messaging.address.QpidExchangeOptions;
+import org.apache.qpid.client.messaging.address.QpidQueueOptions;
import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
@@ -74,6 +78,11 @@ public abstract class AMQDestination implements Destination, Referenceable
private boolean _exchangeExistsChecked;
+ private byte[] _byteEncoding;
+ private static final int IS_DURABLE_MASK = 0x1;
+ private static final int IS_EXCLUSIVE_MASK = 0x2;
+ private static final int IS_AUTODELETE_MASK = 0x4;
+
public static final int QUEUE_TYPE = 1;
public static final int TOPIC_TYPE = 2;
public static final int UNKNOWN_TYPE = 3;
@@ -314,11 +323,7 @@ public abstract class AMQDestination implements Destination, Referenceable
{
if(_urlAsShortString == null)
{
- if (_url == null)
- {
- toURL();
- }
- _urlAsShortString = new AMQShortString(_url);
+ toURL();
}
return _urlAsShortString;
}
@@ -365,6 +370,7 @@ public abstract class AMQDestination implements Destination, Referenceable
// calculated URL now out of date
_url = null;
_urlAsShortString = null;
+ _byteEncoding = null;
}
public AMQShortString getRoutingKey()
@@ -502,10 +508,59 @@ public abstract class AMQDestination implements Destination, Referenceable
sb.deleteCharAt(sb.length() - 1);
url = sb.toString();
_url = url;
+ _urlAsShortString = new AMQShortString(url);
}
return url;
}
+ public byte[] toByteEncoding()
+ {
+ byte[] encoding = _byteEncoding;
+ if(encoding == null)
+ {
+ int size = _exchangeClass.length() + 1 +
+ _exchangeName.length() + 1 +
+ 0 + // in place of the destination name
+ (_queueName == null ? 0 : _queueName.length()) + 1 +
+ 1;
+ encoding = new byte[size];
+ int pos = 0;
+
+ pos = _exchangeClass.writeToByteArray(encoding, pos);
+ pos = _exchangeName.writeToByteArray(encoding, pos);
+
+ encoding[pos++] = (byte)0;
+
+ if(_queueName == null)
+ {
+ encoding[pos++] = (byte)0;
+ }
+ else
+ {
+ pos = _queueName.writeToByteArray(encoding,pos);
+ }
+ byte options = 0;
+ if(_isDurable)
+ {
+ options |= IS_DURABLE_MASK;
+ }
+ if(_isExclusive)
+ {
+ options |= IS_EXCLUSIVE_MASK;
+ }
+ if(_isAutoDelete)
+ {
+ options |= IS_AUTODELETE_MASK;
+ }
+ encoding[pos] = options;
+
+
+ _byteEncoding = encoding;
+
+ }
+ return encoding;
+ }
+
public boolean equals(Object o)
{
if (this == o)
@@ -559,6 +614,53 @@ public abstract class AMQDestination implements Destination, Referenceable
null); // factory location
}
+
+ public static Destination createDestination(byte[] byteEncodedDestination)
+ {
+ AMQShortString exchangeClass;
+ AMQShortString exchangeName;
+ AMQShortString routingKey;
+ AMQShortString queueName;
+ boolean isDurable;
+ boolean isExclusive;
+ boolean isAutoDelete;
+
+ int pos = 0;
+ exchangeClass = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
+ pos+= exchangeClass.length() + 1;
+ exchangeName = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
+ pos+= exchangeName.length() + 1;
+ routingKey = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
+ pos+= (routingKey == null ? 0 : routingKey.length()) + 1;
+ queueName = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
+ pos+= (queueName == null ? 0 : queueName.length()) + 1;
+ int options = byteEncodedDestination[pos];
+ isDurable = (options & IS_DURABLE_MASK) != 0;
+ isExclusive = (options & IS_EXCLUSIVE_MASK) != 0;
+ isAutoDelete = (options & IS_AUTODELETE_MASK) != 0;
+
+ if (exchangeClass.equals(ExchangeDefaults.DIRECT_EXCHANGE_CLASS))
+ {
+ return new AMQQueue(exchangeName,routingKey,queueName,isExclusive,isAutoDelete,isDurable);
+ }
+ else if (exchangeClass.equals(ExchangeDefaults.TOPIC_EXCHANGE_CLASS))
+ {
+ return new AMQTopic(exchangeName,routingKey,isAutoDelete,queueName,isDurable);
+ }
+ else if (exchangeClass.equals(ExchangeDefaults.HEADERS_EXCHANGE_CLASS))
+ {
+ return new AMQHeadersExchange(routingKey);
+ }
+ else
+ {
+ return new AMQAnyDestination(exchangeName,exchangeClass,
+ routingKey,isExclusive,
+ isAutoDelete,queueName,
+ isDurable, new AMQShortString[0]);
+ }
+
+ }
+
public static Destination createDestination(BindingURL binding)
{
AMQShortString type = binding.getExchangeClass();
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
index 25562cfff7..1f940b62f0 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
@@ -567,8 +567,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
close(-1);
}
- public abstract AMQException getLastException();
-
public void checkNotClosed() throws JMSException
{
try
@@ -577,20 +575,16 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
}
catch (IllegalStateException ise)
{
- AMQException ex = getLastException();
- if (ex != null)
- {
- IllegalStateException ssnClosed = new IllegalStateException(
- "Session has been closed", ex.getErrorCode().toString());
+ // if the Connection has closed then we should throw any exception that has occurred that we were not waiting for
+ AMQStateManager manager = _connection.getProtocolHandler().getStateManager();
- ssnClosed.setLinkedException(ex);
- ssnClosed.initCause(ex);
- throw ssnClosed;
- }
- else
+ if (manager.getCurrentState().equals(AMQState.CONNECTION_CLOSED) && manager.getLastException() != null)
{
- throw ise;
+ ise.setLinkedException(manager.getLastException());
+ ise.initCause(ise.getLinkedException());
}
+
+ throw ise;
}
}
@@ -1049,29 +1043,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
throws JMSException
{
checkNotClosed();
- Topic origTopic = checkValidTopic(topic, true);
-
+ AMQTopic origTopic = checkValidTopic(topic, true);
AMQTopic dest = AMQTopic.createDurableTopic(origTopic, name, _connection);
- if (dest.getDestSyntax() == DestSyntax.ADDR &&
- !dest.isAddressResolved())
- {
- try
- {
- handleAddressBasedDestination(dest,false,true);
- if (dest.getAddressType() != AMQDestination.TOPIC_TYPE)
- {
- throw new JMSException("Durable subscribers can only be created for Topics");
- }
- dest.getSourceNode().setDurable(true);
- }
- catch(AMQException e)
- {
- JMSException ex = new JMSException("Error when verifying destination");
- ex.initCause(e);
- ex.setLinkedException(e);
- throw ex;
- }
- }
String messageSelector = ((selector == null) || (selector.trim().length() == 0)) ? null : selector;
@@ -1083,9 +1056,15 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
// Not subscribed to this name in the current session
if (subscriber == null)
{
- // After the address is resolved routing key will not be null.
- AMQShortString topicName = dest.getRoutingKey();
-
+ AMQShortString topicName;
+ if (topic instanceof AMQTopic)
+ {
+ topicName = ((AMQTopic) topic).getRoutingKey();
+ } else
+ {
+ topicName = new AMQShortString(topic.getTopicName());
+ }
+
if (_strictAMQP)
{
if (_strictAMQPFATAL)
@@ -1246,6 +1225,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
else
{
AMQQueue queue = new AMQQueue(queueName);
+ queue.setCreate(AddressOption.ALWAYS);
return queue;
}
@@ -1327,8 +1307,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public QueueReceiver createQueueReceiver(Destination destination) throws JMSException
{
checkValidDestination(destination);
- Queue dest = validateQueue(destination);
- C consumer = (C) createConsumer(dest);
+ AMQQueue dest = (AMQQueue) destination;
+ C consumer = (C) createConsumer(destination);
return new QueueReceiverAdaptor(dest, consumer);
}
@@ -1346,8 +1326,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public QueueReceiver createQueueReceiver(Destination destination, String messageSelector) throws JMSException
{
checkValidDestination(destination);
- Queue dest = validateQueue(destination);
- C consumer = (C) createConsumer(dest, messageSelector);
+ AMQQueue dest = (AMQQueue) destination;
+ C consumer = (C) createConsumer(destination, messageSelector);
return new QueueReceiverAdaptor(dest, consumer);
}
@@ -1364,7 +1344,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public QueueReceiver createReceiver(Queue queue) throws JMSException
{
checkNotClosed();
- Queue dest = validateQueue(queue);
+ AMQQueue dest = (AMQQueue) queue;
C consumer = (C) createConsumer(dest);
return new QueueReceiverAdaptor(dest, consumer);
@@ -1383,23 +1363,11 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public QueueReceiver createReceiver(Queue queue, String messageSelector) throws JMSException
{
checkNotClosed();
- Queue dest = validateQueue(queue);
+ AMQQueue dest = (AMQQueue) queue;
C consumer = (C) createConsumer(dest, messageSelector);
return new QueueReceiverAdaptor(dest, consumer);
}
-
- private Queue validateQueue(Destination dest) throws InvalidDestinationException
- {
- if (dest instanceof AMQDestination && dest instanceof javax.jms.Queue)
- {
- return (Queue)dest;
- }
- else
- {
- throw new InvalidDestinationException("The destination object used is not from this provider or of type javax.jms.Queue");
- }
- }
public QueueSender createSender(Queue queue) throws JMSException
{
@@ -1440,7 +1408,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public TopicSubscriber createSubscriber(Topic topic) throws JMSException
{
checkNotClosed();
- Topic dest = checkValidTopic(topic);
+ AMQTopic dest = checkValidTopic(topic);
// AMQTopic dest = new AMQTopic(topic.getTopicName());
return new TopicSubscriberAdaptor(dest, (C) createExclusiveConsumer(dest));
@@ -1460,7 +1428,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public TopicSubscriber createSubscriber(Topic topic, String messageSelector, boolean noLocal) throws JMSException
{
checkNotClosed();
- Topic dest = checkValidTopic(topic);
+ AMQTopic dest = checkValidTopic(topic);
// AMQTopic dest = new AMQTopic(topic.getTopicName());
return new TopicSubscriberAdaptor(dest, (C) createExclusiveConsumer(dest, messageSelector, noLocal));
@@ -2427,7 +2395,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
/*
* I could have combined the last 3 methods, but this way it improves readability
*/
- protected Topic checkValidTopic(Topic topic, boolean durable) throws JMSException
+ protected AMQTopic checkValidTopic(Topic topic, boolean durable) throws JMSException
{
if (topic == null)
{
@@ -2446,17 +2414,17 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
("Cannot create a durable subscription with a temporary topic: " + topic);
}
- if (!(topic instanceof AMQDestination && topic instanceof javax.jms.Topic))
+ if (!(topic instanceof AMQTopic))
{
throw new javax.jms.InvalidDestinationException(
"Cannot create a subscription on topic created for another JMS Provider, class of topic provided is: "
+ topic.getClass().getName());
}
- return topic;
+ return (AMQTopic) topic;
}
- protected Topic checkValidTopic(Topic topic) throws JMSException
+ protected AMQTopic checkValidTopic(Topic topic) throws JMSException
{
return checkValidTopic(topic, false);
}
@@ -2851,7 +2819,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
declareQueue(amqd, protocolHandler, consumer.isNoLocal(), nowait);
}
- bindQueue(amqd.getAMQQueueName(), amqd.getRoutingKey(), consumer.getArguments(), amqd.getExchangeName(), amqd, nowait);
}
AMQShortString queueName = amqd.getAMQQueueName();
@@ -2859,6 +2826,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
// store the consumer queue name
consumer.setQueuename(queueName);
+ bindQueue(queueName, amqd.getRoutingKey(), consumer.getArguments(), amqd.getExchangeName(), amqd, nowait);
+
// If IMMEDIATE_PREFETCH is not required then suspsend the channel to delay prefetch
if (!_immediatePrefetch)
{
@@ -3481,9 +3450,4 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
return _closing.get()|| _connection.isClosing();
}
-
- public boolean isDeclareExchanges()
- {
- return DECLARE_EXCHANGES;
- }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java
index 75d96d67af..517a7a5ce8 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java
@@ -47,8 +47,6 @@ import org.apache.qpid.client.message.AMQMessageDelegateFactory;
import org.apache.qpid.client.message.FieldTableSupport;
import org.apache.qpid.client.message.MessageFactoryRegistry;
import org.apache.qpid.client.message.UnprocessedMessage_0_10;
-import org.apache.qpid.client.messaging.address.Link;
-import org.apache.qpid.client.messaging.address.Link.Reliability;
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;
@@ -58,7 +56,6 @@ import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.protocol.AMQConstant;
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;
@@ -159,20 +156,13 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
*/
AMQSession_0_10(org.apache.qpid.transport.Connection qpidConnection, AMQConnection con, int channelId,
boolean transacted, int acknowledgeMode, MessageFactoryRegistry messageFactoryRegistry,
- int defaultPrefetchHighMark, int defaultPrefetchLowMark,String name)
+ int defaultPrefetchHighMark, int defaultPrefetchLowMark)
{
super(con, channelId, transacted, acknowledgeMode, messageFactoryRegistry, defaultPrefetchHighMark,
defaultPrefetchLowMark);
_qpidConnection = qpidConnection;
- if (name == null)
- {
- _qpidSession = _qpidConnection.createSession(1);
- }
- else
- {
- _qpidSession = _qpidConnection.createSession(name,1);
- }
+ _qpidSession = _qpidConnection.createSession(1);
_qpidSession.setSessionListener(this);
if (_transacted)
{
@@ -199,12 +189,11 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
* @param qpidConnection The connection
*/
AMQSession_0_10(org.apache.qpid.transport.Connection qpidConnection, AMQConnection con, int channelId,
- boolean transacted, int acknowledgeMode, int defaultPrefetchHigh, int defaultPrefetchLow,
- String name)
+ boolean transacted, int acknowledgeMode, int defaultPrefetchHigh, int defaultPrefetchLow)
{
this(qpidConnection, con, channelId, transacted, acknowledgeMode, MessageFactoryRegistry.newDefaultRegistry(),
- defaultPrefetchHigh, defaultPrefetchLow,name);
+ defaultPrefetchHigh, defaultPrefetchLow);
}
private void addUnacked(int id)
@@ -325,7 +314,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
public void sendQueueBind(final AMQShortString queueName, final AMQShortString routingKey,
final FieldTable arguments, final AMQShortString exchangeName,
final AMQDestination destination, final boolean nowait)
- throws AMQException
+ throws AMQException, FailoverException
{
if (destination.getDestSyntax() == DestSyntax.BURL)
{
@@ -611,16 +600,10 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
(Map<? extends String, ? extends Object>) consumer.getDestination().getLink().getSubscription().getArgs());
}
- boolean acceptModeNone = getAcknowledgeMode() == NO_ACKNOWLEDGE;
-
- if (consumer.getDestination().getLink() != null)
- {
- acceptModeNone = consumer.getDestination().getLink().getReliability() == Link.Reliability.UNRELIABLE;
- }
getQpidSession().messageSubscribe
(queueName.toString(), String.valueOf(tag),
- acceptModeNone ? MessageAcceptMode.NONE : MessageAcceptMode.EXPLICIT,
+ getAcknowledgeMode() == NO_ACKNOWLEDGE ? MessageAcceptMode.NONE : MessageAcceptMode.EXPLICIT,
preAcquire ? MessageAcquireMode.PRE_ACQUIRED : MessageAcquireMode.NOT_ACQUIRED, null, 0, arguments,
consumer.isExclusive() ? Option.EXCLUSIVE : Option.NONE);
}
@@ -784,7 +767,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
else
{
QueueNode node = (QueueNode)amqd.getSourceNode();
- getQpidSession().queueDeclare(queueName.toString(), node.getAlternateExchange() ,
+ getQpidSession().queueDeclare(queueName.toString(), "" ,
node.getDeclareArgs(),
node.isAutoDelete() ? Option.AUTO_DELETE : Option.NONE,
node.isDurable() ? Option.DURABLE : Option.NONE,
@@ -921,26 +904,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
setCurrentException(exc);
}
- public void closed(Session ssn)
- {
- try
- {
- super.closed(null);
- if (flushTask != null)
- {
- flushTask.cancel();
- flushTask = null;
- }
- } catch (Exception e)
- {
- _logger.error("Error closing JMS session", e);
- }
- }
-
- public AMQException getLastException()
- {
- return getCurrentException();
- }
+ public void closed(Session ssn) {}
protected AMQShortString declareQueue(final AMQDestination amqd, final AMQProtocolHandler protocolHandler,
final boolean noLocal, final boolean nowait)
@@ -1056,9 +1020,11 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
code = ee.getErrorCode().getValue();
}
AMQException amqe = new AMQException(AMQConstant.getConstant(code), se.getMessage(), se.getCause());
+
+ _connection.exceptionReceived(amqe);
+
_currentException = amqe;
}
- _connection.exceptionReceived(_currentException);
}
public AMQMessageDelegateFactory getMessageDelegateFactory()
@@ -1102,37 +1068,22 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
return match;
}
- public boolean isQueueExist(AMQDestination dest,QueueNode node,boolean assertNode) throws AMQException
+ public boolean isQueueExist(AMQDestination dest,QueueNode node,boolean assertNode)
{
boolean match = true;
- try
+ QueueQueryResult result = getQpidSession().queueQuery(dest.getAddressName(), Option.NONE).get();
+ match = dest.getAddressName().equals(result.getQueue());
+
+ if (match && assertNode)
{
- QueueQueryResult result = getQpidSession().queueQuery(dest.getAddressName(), Option.NONE).get();
- match = dest.getAddressName().equals(result.getQueue());
-
- if (match && assertNode)
- {
- match = (result.getDurable() == node.isDurable()) &&
- (result.getAutoDelete() == node.isAutoDelete()) &&
- (result.getExclusive() == node.isExclusive()) &&
- (matchProps(result.getArguments(),node.getDeclareArgs()));
- }
- else if (match)
- {
- // should I use the queried details to update the local data structure.
- }
+ match = (result.getDurable() == node.isDurable()) &&
+ (result.getAutoDelete() == node.isAutoDelete()) &&
+ (result.getExclusive() == node.isExclusive()) &&
+ (matchProps(result.getArguments(),node.getDeclareArgs()));
}
- catch(SessionException e)
+ else if (match)
{
- if (e.getException().getErrorCode() == ExecutionErrorCode.RESOURCE_DELETED)
- {
- match = false;
- }
- else
- {
- throw new AMQException(AMQConstant.getConstant(e.getException().getErrorCode().getValue()),
- "Error querying queue",e);
- }
+ // should I use the queried details to update the local data structure.
}
return match;
@@ -1198,22 +1149,6 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
int type = resolveAddressType(dest);
- if (type == AMQDestination.QUEUE_TYPE &&
- dest.getLink().getReliability() == Reliability.UNSPECIFIED)
- {
- dest.getLink().setReliability(Reliability.AT_LEAST_ONCE);
- }
- else if (type == AMQDestination.TOPIC_TYPE &&
- dest.getLink().getReliability() == Reliability.UNSPECIFIED)
- {
- dest.getLink().setReliability(Reliability.UNRELIABLE);
- }
- else if (type == AMQDestination.TOPIC_TYPE &&
- dest.getLink().getReliability() == Reliability.AT_LEAST_ONCE)
- {
- throw new AMQException("AT-LEAST-ONCE is not yet supported for Topics");
- }
-
switch (type)
{
case AMQDestination.QUEUE_TYPE:
@@ -1227,8 +1162,6 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
{
setLegacyFiledsForQueueType(dest);
send0_10QueueDeclare(dest,null,false,noWait);
- sendQueueBind(dest.getAMQQueueName(), dest.getRoutingKey(),
- null,dest.getExchangeName(),dest, false);
break;
}
}
@@ -1337,8 +1270,6 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
dest.getQueueName(),// should have one by now
dest.getSubject(),
Collections.<String,Object>emptyMap()));
- sendQueueBind(dest.getAMQQueueName(), dest.getRoutingKey(),
- null,dest.getExchangeName(),dest, false);
}
public void setLegacyFiledsForQueueType(AMQDestination dest)
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java
index c010e4c7ed..f41b1c94fa 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java
@@ -38,7 +38,6 @@ import org.apache.qpid.client.message.ReturnMessage;
import org.apache.qpid.client.message.UnprocessedMessage;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.client.state.AMQState;
-import org.apache.qpid.client.state.AMQStateManager;
import org.apache.qpid.client.state.listener.SpecificMethodFrameListener;
import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.framing.AMQFrame;
@@ -585,35 +584,4 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
queueName == null ? null : new AMQShortString(queueName),
bindingKey == null ? null : new AMQShortString(bindingKey));
}
-
-
- 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 = _connection.getProtocolHandler()
- .getStateManager();
-
- Exception e = manager.getLastException();
- if (manager.getCurrentState().equals(AMQState.CONNECTION_CLOSED)
- && e != null)
- {
- if (e instanceof AMQException)
- {
- return (AMQException) e;
- }
- else
- {
- AMQException amqe = new AMQException(AMQConstant
- .getConstant(AMQConstant.INTERNAL_ERROR.getCode()),
- e.getMessage(), e.getCause());
- return amqe;
- }
- }
- else
- {
- return null;
- }
- }
-
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
index 780dbcafc2..6217cb534a 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
@@ -22,7 +22,6 @@ package org.apache.qpid.client;
import java.net.URISyntaxException;
-import javax.jms.InvalidDestinationException;
import javax.jms.JMSException;
import javax.jms.Topic;
@@ -96,47 +95,39 @@ public class AMQTopic extends AMQDestination implements Topic
super(exchangeName, exchangeClass, routingKey, isExclusive, isAutoDelete, queueName, isDurable,bindingKeys);
}
- public static AMQTopic createDurableTopic(Topic topic, String subscriptionName, AMQConnection connection)
+ public static AMQTopic createDurableTopic(AMQTopic topic, String subscriptionName, AMQConnection connection)
throws JMSException
{
- if (topic instanceof AMQDestination && topic instanceof javax.jms.Topic)
+ if (topic.getDestSyntax() == DestSyntax.ADDR)
{
- AMQDestination qpidTopic = (AMQDestination)topic;
- if (qpidTopic.getDestSyntax() == DestSyntax.ADDR)
+ try
{
- try
- {
- AMQTopic t = new AMQTopic(qpidTopic.getAddress());
- 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);
-
- // The legacy fields are also populated just in case.
- t.setQueueName(queueName);
- t.setAutoDelete(false);
- t.setDurable(true);
- return t;
- }
- catch(Exception e)
- {
- JMSException ex = new JMSException("Error creating durable topic");
- ex.initCause(e);
- ex.setLinkedException(e);
- throw ex;
- }
+ AMQTopic t = new AMQTopic(topic.getAddress());
+ 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);
+
+ // The legacy fields are also populated just in case.
+ t.setQueueName(queueName);
+ t.setAutoDelete(false);
+ t.setDurable(true);
+ return t;
}
- else
+ catch(Exception e)
{
- return new AMQTopic(qpidTopic.getExchangeName(), qpidTopic.getRoutingKey(), false,
- getDurableTopicQueueName(subscriptionName, connection),
- true);
+ JMSException ex = new JMSException("Error creating durable topic");
+ ex.initCause(e);
+ ex.setLinkedException(e);
+ throw ex;
}
}
else
{
- throw new InvalidDestinationException("The destination object used is not from this provider or of type javax.jms.Topic");
+ return new AMQTopic(topic.getExchangeName(), topic.getRoutingKey(), false,
+ getDurableTopicQueueName(subscriptionName, connection),
+ true);
}
}
@@ -147,17 +138,13 @@ public class AMQTopic extends AMQDestination implements Topic
public String getTopicName() throws JMSException
{
- if (getRoutingKey() != null)
+ if (super.getRoutingKey() == null && super.getSubject() != null)
{
- return getRoutingKey().asString();
- }
- else if (getSubject() != null)
- {
- return getSubject();
+ return super.getSubject();
}
else
{
- return null;
+ return super.getRoutingKey().toString();
}
}
@@ -176,18 +163,12 @@ public class AMQTopic extends AMQDestination implements Topic
public AMQShortString getRoutingKey()
{
- if (super.getRoutingKey() != null)
- {
- return super.getRoutingKey();
- }
- else if (getSubject() != null)
+ if (super.getRoutingKey() == null && super.getSubject() != null)
{
- return new AMQShortString(getSubject());
+ return new AMQShortString(super.getSubject());
}
else
{
- setRoutingKey(new AMQShortString(""));
- setSubject("");
return super.getRoutingKey();
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
index 5d32863f2f..0a78403268 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
@@ -571,7 +571,6 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
if (!_session.isClosed() || _session.isClosing())
{
sendCancel();
- cleanupQueue();
}
}
catch (AMQException e)
@@ -609,8 +608,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
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java
index 964c238946..b5f3501e5a 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java
@@ -19,11 +19,8 @@ package org.apache.qpid.client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.qpid.client.AMQDestination.AddressOption;
import org.apache.qpid.client.AMQDestination.DestSyntax;
-import org.apache.qpid.client.failover.FailoverException;
import org.apache.qpid.client.message.*;
-import org.apache.qpid.client.messaging.address.Node.QueueNode;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
@@ -512,18 +509,4 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
return _exclusive;
}
}
-
- void cleanupQueue() throws AMQException, FailoverException
- {
- AMQDestination dest = this.getDestination();
- if (dest != null && dest.getDestSyntax() == AMQDestination.DestSyntax.ADDR)
- {
- if (dest.getDelete() == AddressOption.ALWAYS ||
- dest.getDelete() == AddressOption.RECEIVER )
- {
- ((AMQSession_0_10) getSession()).getQpidSession().queueDelete(
- this.getDestination().getQueueName());
- }
- }
- }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java
index 00acd5e866..cdbf57769d 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java
@@ -88,8 +88,4 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMe
return receive();
}
- void cleanupQueue() throws AMQException, FailoverException
- {
-
- }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java
index 5821fee7ff..53c0457120 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java
@@ -19,7 +19,6 @@ package org.apache.qpid.client;
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.nio.ByteBuffer;
import java.util.HashMap;
@@ -31,13 +30,9 @@ import javax.jms.JMSException;
import javax.jms.Message;
import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQDestination.AddressOption;
import org.apache.qpid.client.AMQDestination.DestSyntax;
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.messaging.address.Node.QueueNode;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.transport.DeliveryProperties;
import org.apache.qpid.transport.Header;
@@ -73,15 +68,12 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
{
if (destination.getDestSyntax() == DestSyntax.BURL)
{
- if (getSession().isDeclareExchanges())
- {
- String name = destination.getExchangeName().toString();
- ((AMQSession_0_10) getSession()).getQpidSession().exchangeDeclare
- (name,
- destination.getExchangeClass().toString(),
- null, null,
- name.startsWith("amq.") ? Option.PASSIVE : Option.NONE);
- }
+ String name = destination.getExchangeName().toString();
+ ((AMQSession_0_10) getSession()).getQpidSession().exchangeDeclare
+ (name,
+ destination.getExchangeClass().toString(),
+ null, null,
+ name.startsWith("amq.") ? Option.PASSIVE : Option.NONE);
}
else
{
@@ -179,7 +171,7 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
if (destination.getDestSyntax() == AMQDestination.DestSyntax.ADDR &&
(destination.getSubject() != null ||
- (messageProps.getApplicationHeaders() != null && messageProps.getApplicationHeaders().get(QpidMessageProperties.QPID_SUBJECT) != null))
+ (messageProps.getApplicationHeaders() != null && messageProps.getApplicationHeaders().get("qpid.subject") != null))
)
{
Map<String,Object> appProps = messageProps.getApplicationHeaders();
@@ -189,16 +181,16 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
messageProps.setApplicationHeaders(appProps);
}
- if (appProps.get(QpidMessageProperties.QPID_SUBJECT) == null)
+ if (appProps.get("qpid.subject") == null)
{
// use default subject in address string
- appProps.put(QpidMessageProperties.QPID_SUBJECT,destination.getSubject());
+ appProps.put("qpid.subject",destination.getSubject());
}
- if (destination.getAddressType() == AMQDestination.TOPIC_TYPE)
+ if (destination.getTargetNode().getType() == AMQDestination.TOPIC_TYPE)
{
deliveryProp.setRoutingKey((String)
- messageProps.getApplicationHeaders().get(QpidMessageProperties.QPID_SUBJECT));
+ messageProps.getApplicationHeaders().get("qpid.subject"));
}
}
@@ -218,9 +210,6 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
deliveryMode == DeliveryMode.PERSISTENT)
);
- boolean unreliable = (destination.getDestSyntax() == DestSyntax.ADDR) &&
- (destination.getLink().getReliability() == Reliability.UNRELIABLE);
-
org.apache.mina.common.ByteBuffer data = message.getData();
ByteBuffer buffer = data == null ? ByteBuffer.allocate(0) : data.buf().slice();
@@ -228,7 +217,7 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
MessageAcceptMode.NONE,
MessageAcquireMode.PRE_ACQUIRED,
new Header(deliveryProp, messageProps),
- buffer, sync ? SYNC : NONE, unreliable ? UNRELIABLE : NONE);
+ buffer, sync ? SYNC : NONE);
if (sync)
{
ssn.sync();
@@ -250,21 +239,5 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
{
return _session.isQueueBound(destination);
}
-
- @Override
- public void close()
- {
- super.close();
- AMQDestination dest = _destination;
- if (dest != null && dest.getDestSyntax() == AMQDestination.DestSyntax.ADDR)
- {
- if (dest.getDelete() == AddressOption.ALWAYS ||
- dest.getDelete() == AddressOption.SENDER )
- {
- ((AMQSession_0_10) getSession()).getQpidSession().queueDelete(
- _destination.getQueueName());
- }
- }
- }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java b/qpid/java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java
index 2fdb35de49..2b7e3d44da 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java
@@ -1,23 +1,3 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.ArrayList;
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java b/qpid/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java
index e81e754da2..7cc548915c 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java
@@ -23,7 +23,6 @@ package org.apache.qpid.client;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
-import java.util.List;
import org.apache.qpid.framing.AMQShortString;
@@ -35,18 +34,6 @@ public enum CustomJMSXProperty
JMSXGroupSeq,
JMSXUserID;
- private static List<String> _names;
-
- static
- {
- CustomJMSXProperty[] properties = values();
- _names = new ArrayList<String>(properties.length);
- for(CustomJMSXProperty property : properties)
- {
- _names.add(property.toString());
- }
-
- }
private final AMQShortString _nameAsShortString;
@@ -60,8 +47,20 @@ public enum CustomJMSXProperty
return _nameAsShortString;
}
- public static Enumeration asEnumeration()
+ private static Enumeration _names;
+
+ public static synchronized Enumeration asEnumeration()
{
- return Collections.enumeration(_names);
+ if(_names == null)
+ {
+ CustomJMSXProperty[] properties = values();
+ ArrayList<String> nameList = new ArrayList<String>(properties.length);
+ for(CustomJMSXProperty property : properties)
+ {
+ nameList.add(property.toString());
+ }
+ _names = Collections.enumeration(nameList);
+ }
+ return _names;
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java b/qpid/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java
index 5cf767ac35..3bb5707417 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java
@@ -30,11 +30,9 @@ import org.apache.qpid.common.QpidProperties;
public class QpidConnectionMetaData implements ConnectionMetaData
{
- private AMQConnection con;
QpidConnectionMetaData(AMQConnection conn)
{
- this.con = conn;
}
public int getJMSMajorVersion() throws JMSException
@@ -64,12 +62,12 @@ public class QpidConnectionMetaData implements ConnectionMetaData
public int getProviderMajorVersion() throws JMSException
{
- return con.getProtocolVersion().getMajorVersion();
+ return 0;
}
public int getProviderMinorVersion() throws JMSException
{
- return con.getProtocolVersion().getMinorVersion();
+ return 8;
}
public String getProviderVersion() throws JMSException
@@ -80,7 +78,8 @@ public class QpidConnectionMetaData implements ConnectionMetaData
private String getProtocolVersion()
{
- return con.getProtocolVersion().toString();
+ // TODO - Implement based on connection negotiated protocol
+ return "0.8";
}
public String getBrokerVersion()
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java b/qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java
index 295c6a4091..27783bcacf 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java
@@ -50,25 +50,25 @@ public class QueueSenderAdapter implements QueueSender
public void send(Message msg) throws JMSException
{
- checkQueuePreConditions(_queue);
+ checkPreConditions();
_delegate.send(msg);
}
public void send(Queue queue, Message msg) throws JMSException
{
- checkQueuePreConditions(queue);
+ checkPreConditions(queue);
_delegate.send(queue, msg);
}
public void publish(Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException
{
- checkQueuePreConditions(_queue);
+ checkPreConditions();
_delegate.send(msg, deliveryMode, priority, timeToLive);
}
public void send(Queue queue, Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException
{
- checkQueuePreConditions(queue);
+ checkPreConditions(queue);
_delegate.send(queue, msg, deliveryMode, priority, timeToLive);
}
@@ -122,19 +122,19 @@ public class QueueSenderAdapter implements QueueSender
public void send(Destination dest, Message msg) throws JMSException
{
- checkQueuePreConditions((Queue) dest);
+ checkPreConditions((Queue) dest);
_delegate.send(dest, msg);
}
public void send(Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException
{
- checkQueuePreConditions(_queue);
+ checkPreConditions();
_delegate.send(msg, deliveryMode, priority, timeToLive);
}
public void send(Destination dest, Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException
{
- checkQueuePreConditions((Queue) dest);
+ checkPreConditions((Queue) dest);
_delegate.send(dest, msg, deliveryMode, priority, timeToLive);
}
@@ -170,6 +170,11 @@ public class QueueSenderAdapter implements QueueSender
private void checkPreConditions() throws JMSException
{
+ checkPreConditions(_queue);
+ }
+
+ private void checkPreConditions(Queue queue) throws JMSException
+ {
if (closed)
{
throw new javax.jms.IllegalStateException("Publisher is closed");
@@ -181,43 +186,39 @@ public class QueueSenderAdapter implements QueueSender
{
throw new javax.jms.IllegalStateException("Invalid Session");
}
- }
- private void checkQueuePreConditions(Queue queue) throws JMSException
- {
- checkPreConditions() ;
-
- if (queue == null)
- {
- throw new UnsupportedOperationException("Queue is null.");
- }
-
- if (!(queue instanceof AMQDestination))
- {
- throw new InvalidDestinationException("Queue: " + queue + " is not a valid Qpid queue");
- }
-
- AMQDestination destination = (AMQDestination) queue;
- if (!destination.isCheckedForQueueBinding() && checkQueueBeforePublish())
- {
- if (_delegate.getSession().isStrictAMQP())
- {
- _delegate._logger.warn("AMQP does not support destination validation before publish, ");
- destination.setCheckedForQueueBinding(true);
- }
- else
- {
- if (_delegate.isBound(destination))
- {
- destination.setCheckedForQueueBinding(true);
- }
- else
- {
- throw new InvalidDestinationException("Queue: " + queue
- + " is not a valid destination (no bindings on server");
- }
- }
- }
+ if (queue == null)
+ {
+ throw new UnsupportedOperationException("Queue is null.");
+ }
+
+ if (!(queue instanceof AMQDestination))
+ {
+ throw new InvalidDestinationException("Queue: " + queue + " is not a valid Qpid queue");
+ }
+
+ AMQDestination destination = (AMQDestination) queue;
+ if (!destination.isCheckedForQueueBinding() && checkQueueBeforePublish())
+ {
+
+ if (_delegate.getSession().isStrictAMQP())
+ {
+ _delegate._logger.warn("AMQP does not support destination validation before publish, ");
+ destination.setCheckedForQueueBinding(true);
+ }
+ else
+ {
+ if (_delegate.isBound(destination))
+ {
+ destination.setCheckedForQueueBinding(true);
+ }
+ else
+ {
+ throw new InvalidDestinationException("Queue: " + queue
+ + " is not a valid destination (no bindings on server");
+ }
+ }
+ }
}
private boolean checkQueueBeforePublish()
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java b/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java
index 5b94b342eb..8a75082202 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java
@@ -21,14 +21,10 @@ import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
+import org.apache.qpid.AMQInvalidArgumentException;
import org.apache.qpid.dtx.XidImpl;
-import org.apache.qpid.transport.DtxXaStatus;
-import org.apache.qpid.transport.ExecutionErrorCode;
-import org.apache.qpid.transport.Future;
-import org.apache.qpid.transport.Option;
-import org.apache.qpid.transport.RecoverResult;
-import org.apache.qpid.transport.SessionException;
-import org.apache.qpid.transport.XaResult;
+import org.apache.qpid.transport.*;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -215,28 +211,9 @@ public class XAResourceImpl implements XAResource
* @throws XAException An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL.
*/
public boolean isSameRM(XAResource xaResource) throws XAException
- {
- if(this == xaResource)
- {
- return true;
- }
- if(!(xaResource instanceof XAResourceImpl))
- {
- return false;
- }
-
- XAResourceImpl other = (XAResourceImpl)xaResource;
-
- String myUUID = ((AMQSession_0_10)_xaSession).getAMQConnection().getBrokerUUID();
- String otherUUID = ((AMQSession_0_10)other._xaSession).getAMQConnection().getBrokerUUID();
-
- if(_logger.isDebugEnabled())
- {
- _logger.debug("Comparing my UUID " + myUUID + " with other UUID " + otherUUID);
- }
-
- return (myUUID != null && otherUUID != null && myUUID.equals(otherUUID));
-
+ {
+ // TODO : get the server identity of xaResource and compare it with our own one
+ return false;
}
/**
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java b/qpid/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java
index 6b9121811d..354b67cd35 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java
@@ -52,7 +52,7 @@ public class XASessionImpl extends AMQSession_0_10 implements XASession, XATopic
{
super(qpidConnection, con, channelId, false, // this is not a transacted session
Session.AUTO_ACKNOWLEDGE, // the ack mode is transacted
- MessageFactoryRegistry.newDefaultRegistry(), defaultPrefetchHigh, defaultPrefetchLow,null);
+ MessageFactoryRegistry.newDefaultRegistry(), defaultPrefetchHigh, defaultPrefetchLow);
createSession();
_xaResource = new XAResourceImpl(this);
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
index 2b49bb8f81..c81ad6422f 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
@@ -226,7 +226,7 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener<Co
{
Object instance = mechanismClass.newInstance();
AMQCallbackHandler cbh = (AMQCallbackHandler) instance;
- cbh.initialise(protocolSession.getAMQConnection().getConnectionURL());
+ cbh.initialise(protocolSession);
return cbh;
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java
index 182b7b65d8..92e61984d2 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java
@@ -22,12 +22,10 @@
package org.apache.qpid.client.message;
import java.lang.ref.SoftReference;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@@ -634,16 +632,6 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
{
return new String(_messageProps.getUserId());
}
- else if (QpidMessageProperties.AMQP_0_10_APP_ID.equals(propertyName) &&
- _messageProps.getAppId() != null)
- {
- return new String(_messageProps.getAppId());
- }
- else if (QpidMessageProperties.AMQP_0_10_ROUTING_KEY.equals(propertyName) &&
- _deliveryProps.getRoutingKey() != null)
- {
- return _deliveryProps.getRoutingKey();
- }
else
{
checkPropertyName(propertyName);
@@ -682,19 +670,7 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
public Enumeration getPropertyNames() throws JMSException
{
- List<String> props = new ArrayList<String>();
- Map<String, Object> propertyMap = getApplicationHeaders();
- for (String prop: getApplicationHeaders().keySet())
- {
- Object value = propertyMap.get(prop);
- if (value instanceof Boolean || value instanceof Number
- || value instanceof String)
- {
- props.add(prop);
- }
- }
-
- return java.util.Collections.enumeration(props);
+ return java.util.Collections.enumeration(getApplicationHeaders().keySet());
}
public void setBooleanProperty(String propertyName, boolean b) throws JMSException
@@ -750,14 +726,7 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
{
checkPropertyName(propertyName);
checkWritableProperties();
- if (QpidMessageProperties.AMQP_0_10_APP_ID.equals(propertyName))
- {
- _messageProps.setAppId(value.getBytes());
- }
- else
- {
- setApplicationHeader(propertyName, value);
- }
+ setApplicationHeader(propertyName, value);
}
private static final Set<Class> ALLOWED = new HashSet();
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessage.java
index 7f735e0722..6e22292ee0 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessage.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessage.java
@@ -23,7 +23,6 @@ package org.apache.qpid.client.message;
import java.util.List;
import java.util.Map;
-import java.util.UUID;
import javax.jms.JMSException;
import javax.jms.MessageFormatException;
@@ -66,7 +65,7 @@ public class AMQPEncodedMapMessage extends JMSMapMessage
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))
+ || (value instanceof List) || (value instanceof Map) || (value == null))
{
_map.put(propName, value);
}
@@ -110,7 +109,7 @@ public class AMQPEncodedMapMessage extends JMSMapMessage
}
// for testing
- public Map<String,Object> getMap()
+ Map<String,Object> getMap()
{
return _map;
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java
index 40c1df0c5d..e719c9a4b2 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java
@@ -99,7 +99,7 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
}
AMQMessageDelegate delegate = new AMQMessageDelegate_0_8(messageNbr,
- (BasicContentHeaderProperties) contentHeader.getProperties(),
+ (BasicContentHeaderProperties) contentHeader.properties,
exchange, routingKey);
return createMessage(delegate, data);
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java
index cdb75fc9a9..4e4061cf4d 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java
@@ -104,7 +104,7 @@ public class MessageFactoryRegistry
AMQShortString routingKey, ContentHeaderBody contentHeader, List bodies)
throws AMQException, JMSException
{
- BasicContentHeaderProperties properties = (BasicContentHeaderProperties) contentHeader.getProperties();
+ BasicContentHeaderProperties properties = (BasicContentHeaderProperties) contentHeader.properties;
// Get the message content type. This may be null for pure AMQP messages, but will always be set for JMS over
// AMQP. When the type is null, it can only be assumed that the message is a byte message.
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java b/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java
index 368ec60525..00503cc650 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java
@@ -27,7 +27,6 @@ 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;
@@ -55,7 +54,7 @@ public class AddressHelper
public static final String EXCLUSIVE = "exclusive";
public static final String AUTO_DELETE = "auto-delete";
public static final String TYPE = "type";
- public static final String ALT_EXCHANGE = "alternate-exchange";
+ public static final String ALT_EXCHANGE = "alt-exchange";
public static final String BINDINGS = "bindings";
public static final String BROWSE = "browse";
public static final String MODE = "mode";
@@ -232,9 +231,14 @@ public class AddressHelper
private boolean getDurability(Map map)
{
- Accessor access = new MapAccessor(map);
- Boolean result = access.getBoolean(DURABLE);
- return (result == null) ? false : result.booleanValue();
+ if (map != null && map.get(DURABLE) != null)
+ {
+ return Boolean.parseBoolean((String)map.get(DURABLE));
+ }
+ else
+ {
+ return false;
+ }
}
/**
@@ -258,7 +262,7 @@ public class AddressHelper
}
}
- public Link getLink() throws Exception
+ public Link getLink()
{
Link link = new Link();
link.setSubscription(new Subscription());
@@ -268,25 +272,6 @@ public class AddressHelper
: linkProps.getBoolean(DURABLE));
link.setName(linkProps.getString(NAME));
- String reliability = linkProps.getString(RELIABILITY);
- if ( reliability != null)
- {
- if (reliability.equalsIgnoreCase("unreliable"))
- {
- link.setReliability(Reliability.UNRELIABLE);
- }
- else if (reliability.equalsIgnoreCase("at-least-once"))
- {
- link.setReliability(Reliability.AT_LEAST_ONCE);
- }
- else
- {
- throw new Exception("The reliability mode '" +
- reliability + "' is not yet supported");
- }
-
- }
-
if (((Map) address.getOptions().get(LINK)).get(CAPACITY) instanceof Map)
{
MapAccessor capacityProps = new MapAccessor(
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java b/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java
index 5f97d625b4..a7d19d1bd5 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java
@@ -20,8 +20,6 @@
*/
package org.apache.qpid.client.messaging.address;
-import static org.apache.qpid.client.messaging.address.Link.Reliability.UNSPECIFIED;
-
import java.util.HashMap;
import java.util.Map;
@@ -31,8 +29,6 @@ public class Link
{
public enum FilterType { SQL92, XQUERY, SUBJECT }
- public enum Reliability { UNRELIABLE, AT_MOST_ONCE, AT_LEAST_ONCE, EXACTLY_ONCE, UNSPECIFIED }
-
protected String name;
protected String _filter;
protected FilterType _filterType = FilterType.SUBJECT;
@@ -42,18 +38,7 @@ public class Link
protected int _producerCapacity = 0;
protected Node node;
protected Subscription subscription;
- protected Reliability reliability = UNSPECIFIED;
- public Reliability getReliability()
- {
- return reliability;
- }
-
- public void setReliability(Reliability reliability)
- {
- this.reliability = reliability;
- }
-
public Node getNode()
{
return node;
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
index 34c6468629..eb5af119b2 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
@@ -57,6 +57,7 @@ import org.apache.qpid.framing.HeartbeatBody;
import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.framing.ProtocolInitiation;
import org.apache.qpid.framing.ProtocolVersion;
+import org.apache.qpid.jms.BrokerDetails;
import org.apache.qpid.pool.Job;
import org.apache.qpid.pool.ReferenceCountingExecutorService;
import org.apache.qpid.protocol.AMQConstant;
@@ -64,9 +65,8 @@ import org.apache.qpid.protocol.AMQMethodEvent;
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.network.NetworkConnection;
-import org.apache.qpid.transport.network.NetworkTransport;
+import org.apache.qpid.transport.NetworkDriver;
+import org.apache.qpid.transport.network.io.IoTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -172,13 +172,11 @@ public class AMQProtocolHandler implements ProtocolEngine
private Job _readJob;
private Job _writeJob;
private ReferenceCountingExecutorService _poolReference = ReferenceCountingExecutorService.getInstance();
+ private NetworkDriver _networkDriver;
private ProtocolVersion _suggestedProtocolVersion;
private long _writtenBytes;
private long _readBytes;
- private NetworkTransport _transport;
- private NetworkConnection _network;
- private Sender<ByteBuffer> _sender;
/**
* Creates a new protocol handler, associated with the specified client connection instance.
@@ -213,6 +211,21 @@ public class AMQProtocolHandler implements ProtocolEngine
}
/**
+ * Called when we want to create a new IoTransport session
+ * @param brokerDetail
+ */
+ public void createIoTransportSession(BrokerDetails brokerDetail)
+ {
+ _protocolSession = new AMQProtocolSession(this, _connection);
+ _stateManager.setProtocolSession(_protocolSession);
+ IoTransport.connect_0_9(getProtocolSession(),
+ brokerDetail.getHost(),
+ brokerDetail.getPort(),
+ brokerDetail.getBooleanProperty(BrokerDetails.OPTIONS_SSL));
+ _protocolSession.init();
+ }
+
+ /**
* Called when the network connection is closed. This can happen, either because the client explicitly requested
* that the connection be closed, in which case nothing is done, or because the connection died. In the case
* where the connection died, an attempt to failover automatically to a new connection may be started. The failover
@@ -302,7 +315,7 @@ public class AMQProtocolHandler implements ProtocolEngine
// failover:
HeartbeatDiagnostics.timeout();
_logger.warn("Timed out while waiting for heartbeat from peer.");
- _network.close();
+ _networkDriver.close();
}
public void writerIdle()
@@ -324,7 +337,7 @@ public class AMQProtocolHandler implements ProtocolEngine
{
_logger.info("Exception caught therefore going to attempt failover: " + cause, cause);
// this will attempt failover
- _network.close();
+ _networkDriver.close();
closed();
}
else
@@ -576,7 +589,7 @@ public class AMQProtocolHandler implements ProtocolEngine
{
public void run()
{
- _sender.send(buf);
+ _networkDriver.send(buf);
}
});
if (PROTOCOL_DEBUG)
@@ -597,7 +610,7 @@ public class AMQProtocolHandler implements ProtocolEngine
if (wait)
{
- _sender.flush();
+ _networkDriver.flush();
}
}
@@ -711,7 +724,7 @@ public class AMQProtocolHandler implements ProtocolEngine
try
{
syncWrite(frame, ConnectionCloseOkBody.class, timeout);
- _network.close();
+ _networkDriver.close();
closed();
}
catch (AMQTimeoutException e)
@@ -831,18 +844,17 @@ public class AMQProtocolHandler implements ProtocolEngine
public SocketAddress getRemoteAddress()
{
- return _network.getRemoteAddress();
+ return _networkDriver.getRemoteAddress();
}
public SocketAddress getLocalAddress()
{
- return _network.getLocalAddress();
+ return _networkDriver.getLocalAddress();
}
- public void setNetworkConnection(NetworkConnection network)
+ public void setNetworkDriver(NetworkDriver driver)
{
- _network = network;
- _sender = network.getSender();
+ _networkDriver = driver;
}
/** @param delay delay in seconds (not ms) */
@@ -850,15 +862,15 @@ public class AMQProtocolHandler implements ProtocolEngine
{
if (delay > 0)
{
- _network.setMaxWriteIdle(delay);
- _network.setMaxReadIdle(HeartbeatConfig.CONFIG.getTimeout(delay));
+ getNetworkDriver().setMaxWriteIdle(delay);
+ getNetworkDriver().setMaxReadIdle(HeartbeatConfig.CONFIG.getTimeout(delay));
HeartbeatDiagnostics.init(delay, HeartbeatConfig.CONFIG.getTimeout(delay));
}
}
- public NetworkConnection getNetworkConnection()
+ public NetworkDriver getNetworkDriver()
{
- return _network;
+ return _networkDriver;
}
public ProtocolVersion getSuggestedProtocolVersion()
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java b/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java
index 5b7d272506..7976760696 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java
@@ -148,6 +148,16 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession
return getAMQConnection().getVirtualHost();
}
+ public String getUsername()
+ {
+ return getAMQConnection().getUsername();
+ }
+
+ public String getPassword()
+ {
+ return getAMQConnection().getPassword();
+ }
+
public SaslClient getSaslClient()
{
return _saslClient;
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java
index 67dd1a58b6..fbca444208 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java
@@ -22,9 +22,9 @@ package org.apache.qpid.client.security;
import javax.security.auth.callback.CallbackHandler;
-import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.client.protocol.AMQProtocolSession;
public interface AMQCallbackHandler extends CallbackHandler
{
- void initialise(ConnectionURL connectionURL);
+ void initialise(AMQProtocolSession protocolSession);
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties b/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
index b903208927..1bff43142b 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
@@ -18,4 +18,3 @@
#
AMQPLAIN=org.apache.qpid.client.security.amqplain.AmqPlainSaslClientFactory
CRAM-MD5-HASHED=org.apache.qpid.client.security.crammd5hashed.CRAMMD5HashedSaslClientFactory
-ANONYMOUS=org.apache.qpid.client.security.anonymous.AnonymousSaslClientFactory
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
index 6ec83f0a23..66176dac3c 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
@@ -20,29 +20,30 @@
*/
package org.apache.qpid.client.security;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
+import org.apache.qpid.client.protocol.AMQProtocolSession;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
-import org.apache.qpid.jms.ConnectionURL;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
public class UsernameHashedPasswordCallbackHandler implements AMQCallbackHandler
{
- private ConnectionURL _connectionURL;
+ private static final Logger _logger = LoggerFactory.getLogger(UsernameHashedPasswordCallbackHandler.class);
- /**
- * @see org.apache.qpid.client.security.AMQCallbackHandler#initialise(org.apache.qpid.jms.ConnectionURL)
- */
- @Override
- public void initialise(ConnectionURL connectionURL)
+ private AMQProtocolSession _protocolSession;
+
+ public void initialise(AMQProtocolSession protocolSession)
{
- _connectionURL = connectionURL;
+ _protocolSession = protocolSession;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
@@ -52,13 +53,13 @@ public class UsernameHashedPasswordCallbackHandler implements AMQCallbackHandler
Callback cb = callbacks[i];
if (cb instanceof NameCallback)
{
- ((NameCallback) cb).setName(_connectionURL.getUsername());
+ ((NameCallback) cb).setName(_protocolSession.getUsername());
}
else if (cb instanceof PasswordCallback)
{
try
{
- ((PasswordCallback) cb).setPassword(getHash(_connectionURL.getPassword()));
+ ((PasswordCallback) cb).setPassword(getHash(_protocolSession.getPassword()));
}
catch (NoSuchAlgorithmException e)
{
@@ -98,5 +99,4 @@ public class UsernameHashedPasswordCallbackHandler implements AMQCallbackHandler
return hash;
}
-
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java
index ad088722c8..c50c62710f 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java
@@ -27,19 +27,15 @@ import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
-import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.client.protocol.AMQProtocolSession;
public class UsernamePasswordCallbackHandler implements AMQCallbackHandler
{
- private ConnectionURL _connectionURL;
+ private AMQProtocolSession _protocolSession;
- /**
- * @see org.apache.qpid.client.security.AMQCallbackHandler#initialise(org.apache.qpid.jms.ConnectionURL)
- */
- @Override
- public void initialise(final ConnectionURL connectionURL)
+ public void initialise(AMQProtocolSession protocolSession)
{
- _connectionURL = connectionURL;
+ _protocolSession = protocolSession;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
@@ -49,11 +45,11 @@ public class UsernamePasswordCallbackHandler implements AMQCallbackHandler
Callback cb = callbacks[i];
if (cb instanceof NameCallback)
{
- ((NameCallback)cb).setName(_connectionURL.getUsername());
+ ((NameCallback)cb).setName(_protocolSession.getUsername());
}
else if (cb instanceof PasswordCallback)
{
- ((PasswordCallback)cb).setPassword(_connectionURL.getPassword().toCharArray());
+ ((PasswordCallback)cb).setPassword(_protocolSession.getPassword().toCharArray());
}
else
{
@@ -61,5 +57,4 @@ public class UsernamePasswordCallbackHandler implements AMQCallbackHandler
}
}
}
-
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClient.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClient.java
deleted file mode 100644
index 0f56b2ef6c..0000000000
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClient.java
+++ /dev/null
@@ -1,52 +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.security.anonymous;
-
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslException;
-
-public class AnonymousSaslClient implements SaslClient
-{
- public String getMechanismName() {
- return "ANONYMOUS";
- }
- public boolean hasInitialResponse() {
- return true;
- }
- public byte[] evaluateChallenge(byte[] challenge) throws SaslException {
- return new byte[0];
- }
- public boolean isComplete() {
- return true;
- }
- public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
- {
- throw new IllegalStateException("No security layer supported");
- }
- public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
- {
- throw new IllegalStateException("No security layer supported");
- }
- public Object getNegotiatedProperty(String propName) {
- return null;
- }
- public void dispose() throws SaslException {}
-}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClientFactory.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClientFactory.java
deleted file mode 100644
index de698f87c6..0000000000
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClientFactory.java
+++ /dev/null
@@ -1,52 +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.security.anonymous;
-
-import java.util.Arrays;
-import java.util.Map;
-
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslClientFactory;
-import javax.security.sasl.SaslException;
-import javax.security.auth.callback.CallbackHandler;
-
-public class AnonymousSaslClientFactory implements SaslClientFactory
-{
- public SaslClient createSaslClient(String[] mechanisms, String authId,
- String protocol, String server,
- Map props, CallbackHandler cbh) throws SaslException
- {
- if (Arrays.asList(mechanisms).contains("ANONYMOUS")) {
- return new AnonymousSaslClient();
- } else {
- return null;
- }
- }
- public String[] getMechanismNames(Map props)
- {
- if (props == null || props.isEmpty()) {
- return new String[]{"ANONYMOUS"};
- } else {
- return new String[0];
- }
- }
-}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java
new file mode 100644
index 0000000000..1ac8f62e32
--- /dev/null
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java
@@ -0,0 +1,90 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.transport;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.SimpleByteBufferAllocator;
+import org.apache.qpid.client.SSLConfiguration;
+import org.apache.qpid.client.protocol.AMQProtocolHandler;
+import org.apache.qpid.jms.BrokerDetails;
+import org.apache.qpid.ssl.SSLContextFactory;
+import org.apache.qpid.transport.network.mina.MINANetworkDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SocketTransportConnection implements ITransportConnection
+{
+ private static final Logger _logger = LoggerFactory.getLogger(SocketTransportConnection.class);
+ private static final int DEFAULT_BUFFER_SIZE = 32 * 1024;
+
+ private SocketConnectorFactory _socketConnectorFactory;
+
+ static interface SocketConnectorFactory
+ {
+ IoConnector newSocketConnector();
+ }
+
+ public SocketTransportConnection(SocketConnectorFactory socketConnectorFactory)
+ {
+ _socketConnectorFactory = socketConnectorFactory;
+ }
+
+ public void connect(AMQProtocolHandler protocolHandler, BrokerDetails brokerDetail) throws IOException
+ {
+ ByteBuffer.setUseDirectBuffers(Boolean.getBoolean("amqj.enableDirectBuffers"));
+
+ // the MINA default is currently to use the pooled allocator although this may change in future
+ // once more testing of the performance of the simple allocator has been done
+ if (!Boolean.getBoolean("amqj.enablePooledAllocator"))
+ {
+ _logger.info("Using SimpleByteBufferAllocator");
+ ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
+ }
+
+ final IoConnector ioConnector = _socketConnectorFactory.newSocketConnector();
+ final InetSocketAddress address;
+
+ if (brokerDetail.getTransport().equals(BrokerDetails.SOCKET))
+ {
+ address = null;
+ }
+ else
+ {
+ address = new InetSocketAddress(brokerDetail.getHost(), brokerDetail.getPort());
+ _logger.info("Attempting connection to " + address);
+ }
+
+ SSLConfiguration sslConfig = protocolHandler.getConnection().getSSLConfiguration();
+ SSLContextFactory sslFactory = null;
+ if (sslConfig != null)
+ {
+ sslFactory = new SSLContextFactory(sslConfig.getKeystorePath(), sslConfig.getKeystorePassword(), sslConfig.getCertType());
+ }
+
+ MINANetworkDriver driver = new MINANetworkDriver(ioConnector);
+ driver.open(brokerDetail.getPort(), address.getAddress(), protocolHandler, null, sslFactory);
+ protocolHandler.setNetworkDriver(driver);
+ }
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java
new file mode 100644
index 0000000000..aef3a563af
--- /dev/null
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.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.client.transport;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.transport.socket.nio.ExistingSocketConnector;
+import org.apache.mina.transport.socket.nio.MultiThreadSocketConnector;
+import org.apache.mina.transport.socket.nio.SocketConnector;
+import org.apache.mina.transport.vmpipe.VmPipeAcceptor;
+import org.apache.mina.transport.vmpipe.VmPipeAddress;
+import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException;
+import org.apache.qpid.jms.BrokerDetails;
+import org.apache.qpid.protocol.ProtocolEngineFactory;
+import org.apache.qpid.thread.QpidThreadExecutor;
+import org.apache.qpid.transport.network.mina.MINANetworkDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The TransportConnection is a helper class responsible for connecting to an AMQ server. It sets up the underlying
+ * connector, which currently always uses TCP/IP sockets. It creates the "protocol handler" which deals with MINA
+ * protocol events. <p/> Could be extended in future to support different transport types by turning this into concrete
+ * class/interface combo.
+ */
+public class TransportConnection
+{
+ private static ITransportConnection _instance;
+
+ private static final Map _inVmPipeAddress = new HashMap();
+ private static VmPipeAcceptor _acceptor;
+ private static int _currentInstance = -1;
+ private static int _currentVMPort = -1;
+
+ private static final int TCP = 0;
+ private static final int VM = 1;
+ private static final int SOCKET = 2;
+
+ private static Logger _logger = LoggerFactory.getLogger(TransportConnection.class);
+
+ private static final String DEFAULT_QPID_SERVER = "org.apache.qpid.server.protocol.AMQProtocolEngineFactory";
+
+ private static Map<String, Socket> _openSocketRegister = new ConcurrentHashMap<String, Socket>();
+
+ public static void registerOpenSocket(String socketID, Socket openSocket)
+ {
+ _openSocketRegister.put(socketID, openSocket);
+ }
+
+ public static Socket removeOpenSocket(String socketID)
+ {
+ return _openSocketRegister.remove(socketID);
+ }
+
+ public static synchronized ITransportConnection getInstance(final BrokerDetails details) throws AMQTransportConnectionException
+ {
+ int transport = getTransport(details.getTransport());
+
+ if (transport == -1)
+ {
+ throw new AMQNoTransportForProtocolException(details, null, null);
+ }
+
+ switch (transport)
+ {
+ case SOCKET:
+ return new SocketTransportConnection(new SocketTransportConnection.SocketConnectorFactory()
+ {
+ public IoConnector newSocketConnector()
+ {
+ ExistingSocketConnector connector = new ExistingSocketConnector(1,new QpidThreadExecutor());
+
+ Socket socket = TransportConnection.removeOpenSocket(details.getHost());
+
+ if (socket != null)
+ {
+ _logger.info("Using existing Socket:" + socket);
+
+ ((ExistingSocketConnector) connector).setOpenSocket(socket);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Active Socket must be provided for broker " +
+ "with 'socket://<SocketID>' transport:" + details);
+ }
+ return connector;
+ }
+ });
+ case TCP:
+ return new SocketTransportConnection(new SocketTransportConnection.SocketConnectorFactory()
+ {
+ public IoConnector newSocketConnector()
+ {
+ SocketConnector result;
+ // FIXME - this needs to be sorted to use the new Mina MultiThread SA.
+ if (Boolean.getBoolean("qpidnio"))
+ {
+ _logger.warn("Using Qpid MultiThreaded NIO - " + (System.getProperties().containsKey("qpidnio")
+ ? "Qpid NIO is new default"
+ : "Sysproperty 'qpidnio' is set"));
+ result = new MultiThreadSocketConnector(1, new QpidThreadExecutor());
+ }
+ else
+ {
+ _logger.info("Using Mina NIO");
+ result = new SocketConnector(1, new QpidThreadExecutor()); // non-blocking connector
+ }
+ // Don't have the connector's worker thread wait around for other connections (we only use
+ // one SocketConnector per connection at the moment anyway). This allows short-running
+ // clients (like unit tests) to complete quickly.
+ result.setWorkerTimeout(0);
+ return result;
+ }
+ });
+ case VM:
+ {
+ return getVMTransport(details, Boolean.getBoolean("amqj.AutoCreateVMBroker"));
+ }
+ default:
+ throw new AMQNoTransportForProtocolException(details, "Transport not recognised:" + transport, null);
+ }
+ }
+
+ private static int getTransport(String transport)
+ {
+ if (transport.equals(BrokerDetails.SOCKET))
+ {
+ return SOCKET;
+ }
+
+ if (transport.equals(BrokerDetails.TCP))
+ {
+ return TCP;
+ }
+
+ if (transport.equals(BrokerDetails.VM))
+ {
+ return VM;
+ }
+
+ return -1;
+ }
+
+ private static ITransportConnection getVMTransport(BrokerDetails details, boolean AutoCreate)
+ throws AMQVMBrokerCreationException
+ {
+ int port = details.getPort();
+
+ synchronized (_inVmPipeAddress)
+ {
+ if (!_inVmPipeAddress.containsKey(port))
+ {
+ if (AutoCreate)
+ {
+ _logger.warn("Auto Creating InVM Broker on port:" + port);
+ createVMBroker(port);
+ }
+ else
+ {
+ throw new AMQVMBrokerCreationException(null, port, "VM Broker on port " + port
+ + " does not exist. Auto create disabled.", null);
+ }
+ }
+ }
+
+ return new VmPipeTransportConnection(port);
+ }
+
+ public static void createVMBroker(int port) throws AMQVMBrokerCreationException
+ {
+ synchronized(TransportConnection.class)
+ {
+ if (_acceptor == null)
+ {
+ _acceptor = new VmPipeAcceptor();
+
+ IoServiceConfig config = _acceptor.getDefaultConfig();
+ }
+ }
+ synchronized (_inVmPipeAddress)
+ {
+
+ if (!_inVmPipeAddress.containsKey(port))
+ {
+ _logger.info("Creating InVM Qpid.AMQP listening on port " + port);
+ IoHandlerAdapter provider = null;
+ try
+ {
+ VmPipeAddress pipe = new VmPipeAddress(port);
+
+ provider = createBrokerInstance(port);
+
+ _acceptor.bind(pipe, provider);
+
+ _inVmPipeAddress.put(port, pipe);
+ _logger.info("Created InVM Qpid.AMQP listening on port " + port);
+ }
+ catch (IOException e)
+ {
+ _logger.error("Got IOException.", e);
+
+ // Try and unbind provider
+ try
+ {
+ VmPipeAddress pipe = new VmPipeAddress(port);
+
+ try
+ {
+ _acceptor.unbind(pipe);
+ }
+ catch (Exception ignore)
+ {
+ // ignore
+ }
+
+ if (provider == null)
+ {
+ provider = createBrokerInstance(port);
+ }
+
+ _acceptor.bind(pipe, provider);
+ _inVmPipeAddress.put(port, pipe);
+ _logger.info("Created InVM Qpid.AMQP listening on port " + port);
+ }
+ catch (IOException justUseFirstException)
+ {
+ String because;
+ if (e.getCause() == null)
+ {
+ because = e.toString();
+ }
+ else
+ {
+ because = e.getCause().toString();
+ }
+
+ throw new AMQVMBrokerCreationException(null, port, because + " Stopped binding of InVM Qpid.AMQP", e);
+ }
+ }
+
+ }
+ else
+ {
+ _logger.info("InVM Qpid.AMQP on port " + port + " already exits.");
+ }
+ }
+ }
+
+ private static IoHandlerAdapter createBrokerInstance(int port) throws AMQVMBrokerCreationException
+ {
+ String protocolProviderClass = System.getProperty("amqj.protocolprovider.class", DEFAULT_QPID_SERVER);
+ _logger.info("Creating Qpid protocol provider: " + protocolProviderClass);
+
+ // can't use introspection to get Provider as it is a server class.
+ // need to go straight to IoHandlerAdapter but that requries the queues and exchange from the ApplicationRegistry which we can't access.
+
+ // get right constructor and pass in instancec ID - "port"
+ IoHandlerAdapter provider;
+ try
+ {
+ Class[] cnstr = {Integer.class};
+ Object[] params = {port};
+
+ provider = new MINANetworkDriver();
+ ProtocolEngineFactory engineFactory = (ProtocolEngineFactory) Class.forName(protocolProviderClass).getConstructor(cnstr).newInstance(params);
+ ((MINANetworkDriver) provider).setProtocolEngineFactory(engineFactory, true);
+ // Give the broker a second to create
+ _logger.info("Created VMBroker Instance:" + port);
+ }
+ catch (Exception e)
+ {
+ _logger.info("Unable to create InVM Qpid.AMQP on port " + port + ". Because: " + e.getCause());
+ String because;
+ if (e.getCause() == null)
+ {
+ because = e.toString();
+ }
+ else
+ {
+ because = e.getCause().toString();
+ }
+
+ AMQVMBrokerCreationException amqbce =
+ new AMQVMBrokerCreationException(null, port, because + " Stopped InVM Qpid.AMQP creation", e);
+ throw amqbce;
+ }
+
+ return provider;
+ }
+
+ public static void killAllVMBrokers()
+ {
+ _logger.info("Killing all VM Brokers");
+ synchronized(TransportConnection.class)
+ {
+ if (_acceptor != null)
+ {
+ _acceptor.unbindAll();
+ }
+ synchronized (_inVmPipeAddress)
+ {
+ _inVmPipeAddress.clear();
+ }
+ _acceptor = null;
+ }
+ _currentInstance = -1;
+ _currentVMPort = -1;
+ }
+
+ public static void killVMBroker(int port)
+ {
+ synchronized (_inVmPipeAddress)
+ {
+ VmPipeAddress pipe = (VmPipeAddress) _inVmPipeAddress.get(port);
+ if (pipe != null)
+ {
+ _logger.info("Killing VM Broker:" + port);
+ _inVmPipeAddress.remove(port);
+ // This does need to be sychronized as otherwise mina can hang
+ // if a new connection is made
+ _acceptor.unbind(pipe);
+ }
+ }
+ }
+
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java
new file mode 100644
index 0000000000..87cc2e7a5a
--- /dev/null
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.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.client.transport;
+
+import java.io.IOException;
+
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.transport.vmpipe.QpidVmPipeConnector;
+import org.apache.mina.transport.vmpipe.VmPipeAddress;
+import org.apache.mina.transport.vmpipe.VmPipeConnector;
+import org.apache.qpid.client.protocol.AMQProtocolHandler;
+import org.apache.qpid.jms.BrokerDetails;
+import org.apache.qpid.transport.network.mina.MINANetworkDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VmPipeTransportConnection implements ITransportConnection
+{
+ private static final Logger _logger = LoggerFactory.getLogger(VmPipeTransportConnection.class);
+
+ private int _port;
+
+ private MINANetworkDriver _networkDriver;
+
+ public VmPipeTransportConnection(int port)
+ {
+ _port = port;
+ }
+
+ public void connect(AMQProtocolHandler protocolHandler, BrokerDetails brokerDetail) throws IOException
+ {
+ final VmPipeConnector ioConnector = new QpidVmPipeConnector();
+
+ final VmPipeAddress address = new VmPipeAddress(_port);
+ _logger.info("Attempting connection to " + address);
+ _networkDriver = new MINANetworkDriver(ioConnector, protocolHandler);
+ protocolHandler.setNetworkDriver(_networkDriver);
+ ConnectFuture future = ioConnector.connect(address, _networkDriver);
+ // wait for connection to complete
+ future.join();
+ // we call getSession which throws an IOException if there has been an error connecting
+ future.getSession();
+ _networkDriver.setProtocolEngine(protocolHandler);
+ }
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java b/qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java
index 03167561ef..f3f74dd332 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java
@@ -45,7 +45,7 @@ public class URLParser
private void parseURL(String fullURL) throws URLSyntaxException
{
// Connection URL format
- // amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\',option=\'value\';tcp://host:port?option=\'value\'',failover='method?option=\'value\',option='value''"
+ // amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\',option=\'value\';vm://:3/virtualpath?option=\'value\'',failover='method?option=\'value\',option='value''"
// Options are of course optional except for requiring a single broker in the broker list.
try
{
@@ -195,7 +195,7 @@ public class URLParser
{
String brokerlist = _url.getOptions().get(AMQConnectionURL.OPTIONS_BROKERLIST);
- // brokerlist tcp://host:port?option='value',option='value';tcp://host:port/virtualpath?option='value'
+ // brokerlist tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value'
StringTokenizer st = new StringTokenizer(brokerlist, "" + URLHelper.BROKER_SEPARATOR);
while (st.hasMoreTokens())
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java b/qpid/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java
new file mode 100644
index 0000000000..dc0d9b8c78
--- /dev/null
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.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.client.vmbroker;
+
+import org.apache.qpid.client.transport.AMQTransportConnectionException;
+import org.apache.qpid.protocol.AMQConstant;
+
+/**
+ * AMQVMBrokerCreationException represents failure to create an in VM broker on the vm transport medium.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Represent failure to create an in VM broker.
+ * </table>
+ *
+ * @todo Error code never used. This is not an AMQException.
+ */
+public class AMQVMBrokerCreationException extends AMQTransportConnectionException
+{
+ private int _port;
+
+ /**
+ * @param port
+ *
+ * @deprecated
+ */
+ public AMQVMBrokerCreationException(int port)
+ {
+ this(null, port, "Unable to create vm broker", null);
+ }
+
+ public AMQVMBrokerCreationException(AMQConstant errorCode, int port, String message, Throwable cause)
+ {
+ super(errorCode, message, cause);
+ _port = port;
+ }
+
+ public String toString()
+ {
+ return super.toString() + " on port " + _port;
+ }
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java b/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java
index 574a1b3888..b7b6bd57bc 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java
@@ -19,7 +19,6 @@ package org.apache.qpid.filter;
import java.util.HashMap;
-import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import org.apache.qpid.AMQInternalException;
@@ -33,7 +32,7 @@ import org.slf4j.LoggerFactory;
public class PropertyExpression implements Expression
{
// Constants - defined the same as JMS
- private static enum JMSDeliveryMode { NON_PERSISTENT, PERSISTENT }
+ private static final int NON_PERSISTENT = 1;
private static final int DEFAULT_PRIORITY = 4;
private static final Logger _logger = LoggerFactory.getLogger(PropertyExpression.class);
@@ -80,24 +79,22 @@ public class PropertyExpression implements Expression
{
public Object evaluate(AbstractJMSMessage message)
{
-
- JMSDeliveryMode mode = JMSDeliveryMode.NON_PERSISTENT;
try
{
- mode = message.getJMSDeliveryMode() == DeliveryMode.PERSISTENT ?
- JMSDeliveryMode.PERSISTENT : JMSDeliveryMode.NON_PERSISTENT;
-
+ int mode = message.getJMSDeliveryMode();
if (_logger.isDebugEnabled())
{
_logger.debug("JMSDeliveryMode is :" + mode);
}
+
+ return mode;
}
catch (JMSException e)
{
_logger.warn("Error evaluating property",e);
}
- return mode.toString();
+ return NON_PERSISTENT;
}
});
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java
index 4db6a11e4d..6d81f728c9 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java
@@ -52,7 +52,9 @@ public interface BrokerDetails
public static final int DEFAULT_PORT = 5672;
+ public static final String SOCKET = "socket";
public static final String TCP = "tcp";
+ public static final String VM = "vm";
public static final String DEFAULT_TRANSPORT = TCP;
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
index 26641982d7..0e8ca60686 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
@@ -27,7 +27,7 @@ import java.util.List;
/**
Connection URL format
- amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\'&option=\'value\';tcp://host:port/virtualpath?option=\'value\''&failover='method?option=\'value\'&option='value''"
+ amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\'&option=\'value\';vm://:3/virtualpath?option=\'value\''&failover='method?option=\'value\'&option='value''"
Options are of course optional except for requiring a single broker in the broker list.
The option seperator is defined to be either '&' or ','
*/
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java
index 56abf03c81..7cdcd32306 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.jms;
+import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.jms.failover.FailoverExchangeMethod;
import org.apache.qpid.jms.failover.FailoverMethod;
import org.apache.qpid.jms.failover.FailoverRoundRobinServers;
@@ -50,7 +51,7 @@ public class FailoverPolicy
private long _lastMethodTime;
private long _lastFailTime;
- public FailoverPolicy(ConnectionURL connectionDetails, Connection conn)
+ public FailoverPolicy(ConnectionURL connectionDetails, AMQConnection conn)
{
FailoverMethod method;
@@ -82,7 +83,7 @@ public class FailoverPolicy
*/
if (failoverMethod.equals(FailoverMethod.SINGLE_BROKER))
{
- method = new FailoverSingleServer(connectionDetails);
+ method = new FailoverRoundRobinServers(connectionDetails);
}
else
{
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java
index ef30f2adbc..9e6000c472 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java
@@ -32,9 +32,9 @@ import javax.jms.Session;
import org.apache.qpid.client.AMQAnyDestination;
import org.apache.qpid.client.AMQBrokerDetails;
+import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.jms.BrokerDetails;
-import org.apache.qpid.jms.Connection;
import org.apache.qpid.jms.ConnectionURL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,7 +58,7 @@ public class FailoverExchangeMethod implements FailoverMethod, MessageListener
private static final Logger _logger = LoggerFactory.getLogger(FailoverExchangeMethod.class);
/** This is not safe to use until attainConnection is called */
- private Connection _conn;
+ private AMQConnection _conn;
/** Protects the broker list when modifications happens */
private Object _brokerListLock = new Object();
@@ -80,7 +80,7 @@ public class FailoverExchangeMethod implements FailoverMethod, MessageListener
/** Denotes the number of failed attempts **/
private int _failedAttemps = 0;
- public FailoverExchangeMethod(ConnectionURL connectionDetails, Connection conn)
+ public FailoverExchangeMethod(ConnectionURL connectionDetails, AMQConnection conn)
{
_connectionDetails = connectionDetails;
_originalBrokerDetail = _connectionDetails.getBrokerDetails(0);
diff --git a/qpid/java/client/src/test/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java b/qpid/java/client/src/test/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java
new file mode 100644
index 0000000000..5323ad28bf
--- /dev/null
+++ b/qpid/java/client/src/test/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.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.mina.transport.vmpipe.support;
+
+import org.apache.mina.common.IdleStatus;
+
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * This file is a patch to override MINA, because of the IdentityHashMap bug. Workaround to be supplied in MINA 1.0.7.
+ * This patched file will be removed once upgraded onto a newer MINA.
+ *
+ * Dectects idle sessions and fires <tt>sessionIdle</tt> events to them.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ */
+public class VmPipeIdleStatusChecker
+{
+ private static final VmPipeIdleStatusChecker INSTANCE = new VmPipeIdleStatusChecker();
+
+ public static VmPipeIdleStatusChecker getInstance()
+ {
+ return INSTANCE;
+ }
+
+ private final Map sessions = new HashMap(); // will use as a set
+
+ private final Worker worker = new Worker();
+
+ private VmPipeIdleStatusChecker()
+ {
+ worker.start();
+ }
+
+ public void addSession(VmPipeSessionImpl session)
+ {
+ synchronized (sessions)
+ {
+ sessions.put(session, session);
+ }
+ }
+
+ private class Worker extends Thread
+ {
+ private Worker()
+ {
+ super("VmPipeIdleStatusChecker");
+ setDaemon(true);
+ }
+
+ public void run()
+ {
+ for (;;)
+ {
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e)
+ { }
+
+ long currentTime = System.currentTimeMillis();
+
+ synchronized (sessions)
+ {
+ Iterator it = sessions.keySet().iterator();
+ while (it.hasNext())
+ {
+ VmPipeSessionImpl session = (VmPipeSessionImpl) it.next();
+ if (!session.isConnected())
+ {
+ it.remove();
+ }
+ else
+ {
+ notifyIdleSession(session, currentTime);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void notifyIdleSession(VmPipeSessionImpl session, long currentTime)
+ {
+ notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.BOTH_IDLE), IdleStatus.BOTH_IDLE,
+ Math.max(session.getLastIoTime(), session.getLastIdleTime(IdleStatus.BOTH_IDLE)));
+ notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.READER_IDLE), IdleStatus.READER_IDLE,
+ Math.max(session.getLastReadTime(), session.getLastIdleTime(IdleStatus.READER_IDLE)));
+ notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.WRITER_IDLE), IdleStatus.WRITER_IDLE,
+ Math.max(session.getLastWriteTime(), session.getLastIdleTime(IdleStatus.WRITER_IDLE)));
+ }
+
+ private void notifyIdleSession0(VmPipeSessionImpl session, long currentTime, long idleTime, IdleStatus status,
+ long lastIoTime)
+ {
+ if ((idleTime > 0) && (lastIoTime != 0) && ((currentTime - lastIoTime) >= idleTime))
+ {
+ session.increaseIdleCount(status);
+ session.getFilterChain().fireSessionIdle(session, status);
+ }
+ }
+
+}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java b/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java
index 5972bf3fae..da44822ec3 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java
@@ -79,6 +79,11 @@ public class MockAMQConnection extends AMQConnection
super(connectionURL, sslConfig);
}
+ protected MockAMQConnection(String username, String password, String clientName, String virtualHost)
+ {
+ super(username, password, clientName, virtualHost);
+ }
+
@Override
public ProtocolVersion makeBrokerConnection(BrokerDetails brokerDetail) throws IOException
{
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java b/qpid/java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java
index e159ceb148..f520a21ba0 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java
@@ -20,24 +20,23 @@
*/
package org.apache.qpid.client.protocol;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
import junit.framework.TestCase;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQAuthenticationException;
-import org.apache.qpid.client.MockAMQConnection;
-import org.apache.qpid.client.state.AMQState;
-import org.apache.qpid.framing.AMQBody;
import org.apache.qpid.framing.AMQFrame;
+import org.apache.qpid.framing.AMQBody;
import org.apache.qpid.framing.AMQMethodBody;
import org.apache.qpid.framing.amqp_8_0.BasicRecoverOkBodyImpl;
+import org.apache.qpid.AMQException;
import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.transport.TestNetworkConnection;
+import org.apache.qpid.transport.TestNetworkDriver;
+import org.apache.qpid.client.MockAMQConnection;
+import org.apache.qpid.client.AMQAuthenticationException;
+import org.apache.qpid.client.state.AMQState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
/**
* This is a test address QPID-1431 where frame listeners would fail to be notified of an incomming exception.
*
@@ -73,8 +72,8 @@ public class AMQProtocolHandlerTest extends TestCase
public void setUp() throws Exception
{
//Create a new ProtocolHandler with a fake connection.
- _handler = new AMQProtocolHandler(new MockAMQConnection("amqp://guest:guest@client/test?brokerlist='tcp://localhost:1'"));
- _handler.setNetworkConnection(new TestNetworkConnection());
+ _handler = new AMQProtocolHandler(new MockAMQConnection("amqp://guest:guest@client/test?brokerlist='vm://:1'"));
+ _handler.setNetworkDriver(new TestNetworkDriver());
AMQBody body = BasicRecoverOkBodyImpl.getFactory().newInstance(null, 1);
_blockFrame = new AMQFrame(0, body);
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java b/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java
deleted file mode 100644
index 9e23f722eb..0000000000
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.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.client.security;
-
-import java.security.MessageDigest;
-import java.util.Arrays;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-
-import junit.framework.TestCase;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.client.MockAMQConnection;
-import org.apache.qpid.client.protocol.AMQProtocolHandler;
-import org.apache.qpid.client.protocol.AMQProtocolSession;
-
-/**
- * Unit tests for the UsernameHashPasswordCallbackHandler. This callback handler is
- * used by the CRAM-MD5-HASHED SASL mechanism.
- *
- */
-public class UsernameHashedPasswordCallbackHandlerTest extends TestCase
-{
- private AMQCallbackHandler _callbackHandler = new UsernameHashedPasswordCallbackHandler(); // Class under test
- private static final String PROMPT_UNUSED = "unused";
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
-
- final String url = "amqp://username:password@client/test?brokerlist='tcp://localhost:1'";
- _callbackHandler.initialise(new AMQConnectionURL(url));
- }
-
- /**
- * Tests that the callback handler can correctly retrieve the username from the connection url.
- */
- public void testNameCallback() throws Exception
- {
- final String expectedName = "username";
- NameCallback nameCallback = new NameCallback(PROMPT_UNUSED);
-
- assertNull("Unexpected name before test", nameCallback.getName());
- _callbackHandler.handle(new Callback[] {nameCallback});
- assertEquals("Unexpected name", expectedName, nameCallback.getName());
- }
-
- /**
- * Tests that the callback handler can correctly retrieve the password from the connection url
- * and calculate a MD5.
- */
- public void testDigestedPasswordCallback() throws Exception
- {
- final char[] expectedPasswordDigested = getHashPassword("password");
-
- PasswordCallback passwordCallback = new PasswordCallback(PROMPT_UNUSED, false);
- assertNull("Unexpected password before test", passwordCallback.getPassword());
- _callbackHandler.handle(new Callback[] {passwordCallback});
- assertTrue("Unexpected password", Arrays.equals(expectedPasswordDigested, passwordCallback.getPassword()));
- }
-
- private char[] getHashPassword(final String password) throws Exception
- {
- MessageDigest md5Digester = MessageDigest.getInstance("MD5");
- final byte[] digest = md5Digester.digest(password.getBytes("UTF-8"));
-
- char[] hash = new char[digest.length];
-
- int index = 0;
- for (byte b : digest)
- {
- hash[index++] = (char) b;
- }
-
- return hash;
- }
-}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.java b/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.java
deleted file mode 100644
index 83ddfd72fa..0000000000
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.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.client.security;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-
-import junit.framework.TestCase;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.client.MockAMQConnection;
-import org.apache.qpid.client.protocol.AMQProtocolHandler;
-import org.apache.qpid.client.protocol.AMQProtocolSession;
-
-/**
- * Unit tests for the UsernamePasswordCallbackHandler.
- *
- */
-public class UsernamePasswordCallbackHandlerTest extends TestCase
-{
- private AMQCallbackHandler _callbackHandler = new UsernamePasswordCallbackHandler(); // Class under test
- private static final String PROMPT_UNUSED = "unused";
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
-
- final String url = "amqp://username:password@client/test?brokerlist='tcp://localhost:1'";
-
- _callbackHandler.initialise(new AMQConnectionURL(url));
- }
-
- /**
- * Tests that the callback handler can correctly retrieve the username from the connection url.
- */
- public void testNameCallback() throws Exception
- {
- final String expectedName = "username";
- NameCallback nameCallback = new NameCallback(PROMPT_UNUSED);
-
- assertNull("Unexpected name before test", nameCallback.getName());
- _callbackHandler.handle(new Callback[] {nameCallback});
- assertEquals("Unexpected name", expectedName, nameCallback.getName());
- }
-
- /**
- * Tests that the callback handler can correctly retrieve the password from the connection url.
- */
- public void testPasswordCallback() throws Exception
- {
- final String expectedPassword = "password";
- PasswordCallback passwordCallback = new PasswordCallback(PROMPT_UNUSED, false);
- assertNull("Unexpected password before test", passwordCallback.getPassword());
- _callbackHandler.handle(new Callback[] {passwordCallback});
- assertEquals("Unexpected password", expectedPassword, new String(passwordCallback.getPassword()));
- }
-}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/jms/FailoverPolicyTest.java b/qpid/java/client/src/test/java/org/apache/qpid/jms/FailoverPolicyTest.java
deleted file mode 100644
index 438995aedc..0000000000
--- a/qpid/java/client/src/test/java/org/apache/qpid/jms/FailoverPolicyTest.java
+++ /dev/null
@@ -1,338 +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.jms;
-
-import javax.jms.ConnectionConsumer;
-import javax.jms.ConnectionMetaData;
-import javax.jms.Destination;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.ServerSessionPool;
-import javax.jms.Topic;
-
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.jms.failover.FailoverExchangeMethod;
-import org.apache.qpid.jms.failover.FailoverMethod;
-import org.apache.qpid.jms.failover.FailoverRoundRobinServers;
-import org.apache.qpid.jms.failover.FailoverSingleServer;
-import org.apache.qpid.jms.failover.NoFailover;
-
-import junit.framework.TestCase;
-
-/**
- * Tests the ability of FailoverPolicy to instantiate the correct FailoverMethod.
- *
- * This test presently does <i>not</i> test {@link FailoverPolicy#FailoverPolicy(FailoverMethod) or
- * {@link FailoverPolicy#addMethod(FailoverMethod)} as it appears that this functionality
- * is no longer in use.
- *
- */
-public class FailoverPolicyTest extends TestCase
-{
- private FailoverPolicy _failoverPolicy = null; // class under test
- private String _url;
- private Connection _connection = null;
- private ConnectionURL _connectionUrl = null;
-
- /**
- * Tests single server method is selected for a brokerlist with one broker when
- * the failover option is not specified.
- */
- public void testBrokerListWithOneBrokerDefaultsToSingleServerPolicy() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverSingleServer);
- }
-
- /**
- * Tests round robin method is selected for a brokerlist with two brokers when
- * the failover option is not specified.
- */
- public void testBrokerListWithTwoBrokersDefaultsToRoundRobinPolicy() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672;tcp://localhost:5673'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverRoundRobinServers);
- }
-
- /**
- * Tests single server method is selected for a brokerlist with one broker when
- * the failover option passed as 'singlebroker'.
- */
- public void testExplictFailoverOptionSingleBroker() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='singlebroker'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverSingleServer);
- }
-
- /**
- * Tests round robin method is selected for a brokerlist with two brokers when
- * the failover option passed as 'roundrobin'.
- */
- public void testExplictFailoverOptionRoundrobin() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672;tcp://localhost:5673'&failover='roundrobin'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverRoundRobinServers);
- }
-
- /**
- * Tests no failover method is selected for a brokerlist with one broker when
- * the failover option passed as 'nofailover'.
- */
- public void testExplictFailoverOptionNofailover() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='nofailover'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof NoFailover);
- }
-
- /**
- * Tests failover exchange method is selected for a brokerlist with one broker when
- * the failover option passed as 'failover_exchange'.
- */
- public void testExplictFailoverOptionFailoverExchange() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='failover_exchange'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverExchangeMethod);
- }
-
- /**
- * Tests that a custom method can be selected for a brokerlist with one brokers when
- * the failover option passed as a qualified class-name.
- */
- public void testExplictFailoverOptionDynamicallyLoadedFailoverMethod() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='org.apache.qpid.jms.FailoverPolicyTest$MyFailoverMethod'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof MyFailoverMethod);
- }
-
- /**
- * Tests that an unknown method caused an exception.
- */
- public void testUnknownFailoverMethod() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='unknown'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- try
- {
- new FailoverPolicy(_connectionUrl, _connection);
- fail("Exception not thrown");
- }
- catch(IllegalArgumentException iae)
- {
- // PASS
- }
- }
-
- private Connection createStubConnection()
- {
- return new Connection()
- {
-
- @Override
- public Session createSession(boolean transacted,
- int acknowledgeMode, int prefetch) throws JMSException
- {
- return null;
- }
-
- @Override
- public Session createSession(boolean transacted,
- int acknowledgeMode, int prefetchHigh, int prefetchLow)
- throws JMSException
- {
- return null;
- }
-
- @Override
- public ConnectionListener getConnectionListener()
- {
- return null;
- }
-
- @Override
- public long getMaximumChannelCount() throws JMSException
- {
- return 0;
- }
-
- @Override
- public void setConnectionListener(ConnectionListener listener)
- {
- }
-
- @Override
- public void close() throws JMSException
- {
- }
-
- @Override
- public ConnectionConsumer createConnectionConsumer(
- Destination arg0, String arg1, ServerSessionPool arg2,
- int arg3) throws JMSException
- {
- return null;
- }
-
- @Override
- public ConnectionConsumer createDurableConnectionConsumer(
- Topic arg0, String arg1, String arg2,
- ServerSessionPool arg3, int arg4) throws JMSException
- {
- return null;
- }
-
- @Override
- public javax.jms.Session createSession(boolean arg0, int arg1)
- throws JMSException
- {
- return null;
- }
-
- @Override
- public String getClientID() throws JMSException
- {
- return null;
- }
-
- @Override
- public ExceptionListener getExceptionListener() throws JMSException
- {
- return null;
- }
-
- @Override
- public ConnectionMetaData getMetaData() throws JMSException
- {
- return null;
- }
-
- @Override
- public void setClientID(String arg0) throws JMSException
- {
- }
-
- @Override
- public void setExceptionListener(ExceptionListener arg0)
- throws JMSException
- {
- }
-
- @Override
- public void start() throws JMSException
- {
- }
-
- @Override
- public void stop() throws JMSException
- {
- }
- };
- }
-
- // Class used to test the ability of FailoverPolicy to load an implementation.
- static class MyFailoverMethod implements FailoverMethod
- {
- public MyFailoverMethod(ConnectionURL connectionDetails)
- {
- }
-
- @Override
- public void attainedConnection()
- {
- }
-
- @Override
- public boolean failoverAllowed()
- {
- return false;
- }
-
- @Override
- public BrokerDetails getCurrentBrokerDetails()
- {
- return null;
- }
-
- @Override
- public BrokerDetails getNextBrokerDetails()
- {
- return null;
- }
-
- @Override
- public String methodName()
- {
- return null;
- }
-
- @Override
- public void reset()
- {
- }
-
- @Override
- public void setBroker(BrokerDetails broker)
- {
- }
-
- @Override
- public void setRetries(int maxRetries)
- {
- }
- }
-
-}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java
index 9095f94960..1b27ff6300 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java
@@ -43,6 +43,15 @@ public class BrokerDetailsTest extends TestCase
assertTrue(broker.getProperty("immediatedelivery").equals("true"));
}
+ public void testVMBroker() throws URLSyntaxException
+ {
+ String url = "vm://:2";
+
+ AMQBrokerDetails broker = new AMQBrokerDetails(url);
+ assertTrue(broker.getTransport().equals("vm"));
+ assertEquals(broker.getPort(), 2);
+ }
+
public void testTransportsDefaultToTCP() throws URLSyntaxException
{
String url = "localhost:5672";
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java
index 4624b36fea..2be3720c20 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java
@@ -300,6 +300,53 @@ public class ConnectionURLTest extends TestCase
assertTrue(connectionurl.getOption("immediatedelivery").equals("true"));
}
+ public void testSinglevmURL() throws URLSyntaxException
+ {
+ String url = "amqp://guest:guest@/test?brokerlist='vm://:2'";
+
+ ConnectionURL connectionurl = new AMQConnectionURL(url);
+
+ assertTrue(connectionurl.getFailoverMethod() == null);
+ assertTrue(connectionurl.getUsername().equals("guest"));
+ assertTrue(connectionurl.getPassword().equals("guest"));
+ assertTrue(connectionurl.getVirtualHost().equals("/test"));
+
+ assertTrue(connectionurl.getBrokerCount() == 1);
+
+ BrokerDetails service = connectionurl.getBrokerDetails(0);
+
+ assertTrue(service.getTransport().equals("vm"));
+ assertTrue(service.getHost().equals(""));
+ assertTrue(service.getPort() == 2);
+
+ }
+
+ public void testFailoverVMURL() throws URLSyntaxException
+ {
+ String url = "amqp://ritchiem:bob@/test?brokerlist='vm://:2;vm://:3',failover='roundrobin'";
+
+ ConnectionURL connectionurl = new AMQConnectionURL(url);
+
+ assertTrue(connectionurl.getFailoverMethod().equals("roundrobin"));
+ assertTrue(connectionurl.getUsername().equals("ritchiem"));
+ assertTrue(connectionurl.getPassword().equals("bob"));
+ assertTrue(connectionurl.getVirtualHost().equals("/test"));
+
+ assertTrue(connectionurl.getBrokerCount() == 2);
+
+ BrokerDetails service = connectionurl.getBrokerDetails(0);
+
+ assertTrue(service.getTransport().equals("vm"));
+ assertTrue(service.getHost().equals(""));
+ assertTrue(service.getPort() == 2);
+
+ service = connectionurl.getBrokerDetails(1);
+ assertTrue(service.getTransport().equals("vm"));
+ assertTrue(service.getHost().equals(""));
+ assertTrue(service.getPort() == 3);
+ }
+
+
public void testNoVirtualHostURL()
{
String url = "amqp://user@?brokerlist='tcp://localhost:5672'";
@@ -440,6 +487,27 @@ public class ConnectionURLTest extends TestCase
}
+ public void testSocketProtocol() throws URLSyntaxException
+ {
+ String url = "amqp://guest:guest@id/test" + "?brokerlist='socket://VM-Unique-socketID'";
+
+ try
+ {
+ AMQConnectionURL curl = new AMQConnectionURL(url);
+ assertNotNull(curl);
+ assertEquals(1, curl.getBrokerCount());
+ assertNotNull(curl.getBrokerDetails(0));
+ assertEquals(BrokerDetails.SOCKET, curl.getBrokerDetails(0).getTransport());
+ assertEquals("VM-Unique-socketID", curl.getBrokerDetails(0).getHost());
+ assertEquals("URL does not toString as expected",
+ url.replace(":guest", ":********"), curl.toString());
+ }
+ catch (URLSyntaxException e)
+ {
+ fail(e.getMessage());
+ }
+ }
+
public void testSingleTransportMultiOptionOnBrokerURL() throws URLSyntaxException
{
String url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672?foo='jim'&bar='bob'&fred='jimmy'',routingkey='jim',timeout='200',immediatedelivery='true'";
@@ -481,37 +549,6 @@ public class ConnectionURLTest extends TestCase
assertTrue("String representation should contain options and values", url.toString().contains("maxprefetch='12345'"));
}
- public void testHostNamesWithUnderScore() throws URLSyntaxException
- {
- String url = "amqp://guest:guest@clientid/test?brokerlist='tcp://under_score:6672'";
-
- ConnectionURL connectionurl = new AMQConnectionURL(url);
-
- assertTrue(connectionurl.getUsername().equals("guest"));
- assertTrue(connectionurl.getPassword().equals("guest"));
- assertTrue(connectionurl.getVirtualHost().equals("/test"));
-
- assertTrue(connectionurl.getBrokerCount() == 1);
- BrokerDetails service = connectionurl.getBrokerDetails(0);
- assertTrue(service.getTransport().equals("tcp"));
- assertTrue(service.getHost().equals("under_score"));
- assertTrue(service.getPort() == 6672);
-
- url = "amqp://guest:guest@clientid/test?brokerlist='tcp://under_score'";
-
- connectionurl = new AMQConnectionURL(url);
-
- assertTrue(connectionurl.getUsername().equals("guest"));
- assertTrue(connectionurl.getPassword().equals("guest"));
- assertTrue(connectionurl.getVirtualHost().equals("/test"));
-
- assertTrue(connectionurl.getBrokerCount() == 1);
- service = connectionurl.getBrokerDetails(0);
- assertTrue(service.getTransport().equals("tcp"));
- assertTrue(service.getHost().equals("under_score"));
- assertTrue(service.getPort() == 5672);
- }
-
public static junit.framework.Test suite()
{
return new junit.framework.TestSuite(ConnectionURLTest.class);
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java
index 4637c6e505..47c0359b94 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java
@@ -195,10 +195,4 @@ public class TestAMQSession extends AMQSession<BasicMessageConsumer_0_8, BasicMe
{
return false;
}
-
- @Override
- public AMQException getLastException()
- {
- return null;
- }
}
diff --git a/qpid/java/common.xml b/qpid/java/common.xml
index f503a5c7da..066859b29f 100644
--- a/qpid/java/common.xml
+++ b/qpid/java/common.xml
@@ -23,9 +23,7 @@
<dirname property="project.root" file="${ant.file.common}"/>
<property name="project.name" value="qpid"/>
- <property name="project.version" value="0.13"/>
- <property name="project.url" value="http://qpid.apache.org"/>
- <property name="project.groupid" value="org.apache.qpid"/>
+ <property name="project.version" value="0.9"/>
<property name="project.namever" value="${project.name}-${project.version}"/>
<property name="resources" location="${project.root}/resources"/>
@@ -65,11 +63,6 @@
<property name="mllib.dir" value="${project.root}/../python" />
<property name="findbugs.dir" value="${project.root}/lib/findbugs" />
- <!-- properties used to control Ant Eclipse for Eclipse classpath/project files etc -->
- <property name="eclipse.updatealways" value="false"/>
- <property name="eclipse.compilercompliance" value="5.0"/>
- <property name="eclipse.container" value="JVM 1.5"/>
-
<path id="cobertura.classpath">
<fileset dir="${cobertura.dir}">
<include name="cobertura.jar" />
@@ -78,7 +71,6 @@
</path>
<property name="maven.local.repo" value="${build.scratch}/maven-local-repo"/>
- <property name="maven.settings.xml" value="${project.root}/maven-settings.xml"/>
<property name="maven.unique.version" value="false"/>
<property name="maven.snapshot" value="true"/>
<condition property="maven.version.suffix" value="" else="-SNAPSHOT">
@@ -116,10 +108,9 @@
<attribute name="dir"/>
<attribute name="name"/>
<attribute name="excludes" default=""/>
- <attribute name="erroronmissingdir" default="true"/>
<sequential>
- <dirset id="@{dir}.refid" dir="@{dir}" excludes="@{excludes}" erroronmissingdir="@{erroronmissingdir}">
+ <dirset id="@{dir}.refid" dir="@{dir}" excludes="@{excludes}">
<present targetdir="@{dir}">
<mapper type="glob" from="*" to="*/build.xml" />
</present>
@@ -133,6 +124,8 @@
</sequential>
</macrodef>
+
+
<macrodef name="jython">
<attribute name="path"/>
<element name="args"/>
@@ -329,20 +322,6 @@
results directory:
${build.results}
-
- ant eclipse
-
- Generates project and classpath files for the Eclispe IDE. Requires that
- the Ant Eclipse task (http://ant-eclipse.sourceforge.net/) has been installed
- in $ANT_HOME/lib.
-
- The following system properties will be passed to the task. These can be usefully
- overridden from the command line.
-
- eclipse.updatealways - forces Eclipse files to be regenerated even if they are newer then the build.xml (default ${eclipse.updatealways}).
- eclipse.container - controls the Eclipse container (default ${eclipse.container}).
- eclipse.compilercompliance" - controls the Eclipse compiler compliance (default ${eclipse.compilercompliance}).
-
</echo>
</target>
diff --git a/qpid/java/common/src/main/java/common.bnd b/qpid/java/common/src/main/java/common.bnd
index f12fbf9273..ef56ecec9e 100755
--- a/qpid/java/common/src/main/java/common.bnd
+++ b/qpid/java/common/src/main/java/common.bnd
@@ -17,7 +17,7 @@
# under the License.
#
-ver: 0.13.0
+ver: 0.9.0
Bundle-SymbolicName: qpid-common
Bundle-Version: ${ver}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/common/FixedSizeByteBufferAllocator.java b/qpid/java/common/src/main/java/org/apache/mina/common/FixedSizeByteBufferAllocator.java
new file mode 100644
index 0000000000..0c311b6645
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/common/FixedSizeByteBufferAllocator.java
@@ -0,0 +1,467 @@
+package org.apache.mina.common;
+
+import org.apache.mina.common.ByteBuffer;
+
+import java.nio.*;
+
+/*
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*
+*/
+public class FixedSizeByteBufferAllocator implements ByteBufferAllocator
+{
+
+
+ private static final int MINIMUM_CAPACITY = 1;
+
+ public FixedSizeByteBufferAllocator ()
+ {
+ }
+
+ public ByteBuffer allocate( int capacity, boolean direct )
+ {
+ java.nio.ByteBuffer nioBuffer;
+ if( direct )
+ {
+ nioBuffer = java.nio.ByteBuffer.allocateDirect( capacity );
+ }
+ else
+ {
+ nioBuffer = java.nio.ByteBuffer.allocate( capacity );
+ }
+ return new FixedSizeByteBuffer( nioBuffer );
+ }
+
+ public ByteBuffer wrap( java.nio.ByteBuffer nioBuffer )
+ {
+ return new FixedSizeByteBuffer( nioBuffer );
+ }
+
+ public void dispose()
+ {
+ }
+
+
+
+ private static final class FixedSizeByteBuffer extends ByteBuffer
+ {
+ private java.nio.ByteBuffer buf;
+ private int mark = -1;
+
+
+ protected FixedSizeByteBuffer( java.nio.ByteBuffer buf )
+ {
+ this.buf = buf;
+ buf.order( ByteOrder.BIG_ENDIAN );
+ }
+
+ public synchronized void acquire()
+ {
+ }
+
+ public void release()
+ {
+ }
+
+ public java.nio.ByteBuffer buf()
+ {
+ return buf;
+ }
+
+ public boolean isPooled()
+ {
+ return false;
+ }
+
+ public void setPooled( boolean pooled )
+ {
+ }
+
+ public ByteBuffer duplicate() {
+ return new FixedSizeByteBuffer( this.buf.duplicate() );
+ }
+
+ public ByteBuffer slice() {
+ return new FixedSizeByteBuffer( this.buf.slice() );
+ }
+
+ public ByteBuffer asReadOnlyBuffer() {
+ return new FixedSizeByteBuffer( this.buf.asReadOnlyBuffer() );
+ }
+
+ public byte[] array()
+ {
+ return buf.array();
+ }
+
+ public int arrayOffset()
+ {
+ return buf.arrayOffset();
+ }
+
+ public boolean isDirect()
+ {
+ return buf.isDirect();
+ }
+
+ public boolean isReadOnly()
+ {
+ return buf.isReadOnly();
+ }
+
+ public int capacity()
+ {
+ return buf.capacity();
+ }
+
+ public ByteBuffer capacity( int newCapacity )
+ {
+ if( newCapacity > capacity() )
+ {
+ throw new IllegalArgumentException();
+ }
+
+ return this;
+ }
+
+
+
+ public boolean isAutoExpand()
+ {
+ return false;
+ }
+
+ public ByteBuffer setAutoExpand( boolean autoExpand )
+ {
+ if(autoExpand) throw new IllegalArgumentException();
+ else return this;
+ }
+
+ public ByteBuffer expand( int pos, int expectedRemaining )
+ {
+ int end = pos + expectedRemaining;
+ if( end > capacity() )
+ {
+ // The buffer needs expansion.
+ capacity( end );
+ }
+
+ if( end > limit() )
+ {
+ // We call limit() directly to prevent StackOverflowError
+ buf.limit( end );
+ }
+ return this;
+ }
+
+ public int position()
+ {
+ return buf.position();
+ }
+
+ public ByteBuffer position( int newPosition )
+ {
+
+ buf.position( newPosition );
+ if( mark > newPosition )
+ {
+ mark = -1;
+ }
+ return this;
+ }
+
+ public int limit()
+ {
+ return buf.limit();
+ }
+
+ public ByteBuffer limit( int newLimit )
+ {
+ buf.limit( newLimit );
+ if( mark > newLimit )
+ {
+ mark = -1;
+ }
+ return this;
+ }
+
+ public ByteBuffer mark()
+ {
+ buf.mark();
+ mark = position();
+ return this;
+ }
+
+ public int markValue()
+ {
+ return mark;
+ }
+
+ public ByteBuffer reset()
+ {
+ buf.reset();
+ return this;
+ }
+
+ public ByteBuffer clear()
+ {
+ buf.clear();
+ mark = -1;
+ return this;
+ }
+
+ public ByteBuffer flip()
+ {
+ buf.flip();
+ mark = -1;
+ return this;
+ }
+
+ public ByteBuffer rewind()
+ {
+ buf.rewind();
+ mark = -1;
+ return this;
+ }
+
+ public byte get()
+ {
+ return buf.get();
+ }
+
+ public ByteBuffer put( byte b )
+ {
+ buf.put( b );
+ return this;
+ }
+
+ public byte get( int index )
+ {
+ return buf.get( index );
+ }
+
+ public ByteBuffer put( int index, byte b )
+ {
+ buf.put( index, b );
+ return this;
+ }
+
+ public ByteBuffer get( byte[] dst, int offset, int length )
+ {
+ buf.get( dst, offset, length );
+ return this;
+ }
+
+ public ByteBuffer put( java.nio.ByteBuffer src )
+ {
+ buf.put( src );
+ return this;
+ }
+
+ public ByteBuffer put( byte[] src, int offset, int length )
+ {
+ buf.put( src, offset, length );
+ return this;
+ }
+
+ public ByteBuffer compact()
+ {
+ buf.compact();
+ mark = -1;
+ return this;
+ }
+
+ public ByteOrder order()
+ {
+ return buf.order();
+ }
+
+ public ByteBuffer order( ByteOrder bo )
+ {
+ buf.order( bo );
+ return this;
+ }
+
+ public char getChar()
+ {
+ return buf.getChar();
+ }
+
+ public ByteBuffer putChar( char value )
+ {
+ buf.putChar( value );
+ return this;
+ }
+
+ public char getChar( int index )
+ {
+ return buf.getChar( index );
+ }
+
+ public ByteBuffer putChar( int index, char value )
+ {
+ buf.putChar( index, value );
+ return this;
+ }
+
+ public CharBuffer asCharBuffer()
+ {
+ return buf.asCharBuffer();
+ }
+
+ public short getShort()
+ {
+ return buf.getShort();
+ }
+
+ public ByteBuffer putShort( short value )
+ {
+ buf.putShort( value );
+ return this;
+ }
+
+ public short getShort( int index )
+ {
+ return buf.getShort( index );
+ }
+
+ public ByteBuffer putShort( int index, short value )
+ {
+ buf.putShort( index, value );
+ return this;
+ }
+
+ public ShortBuffer asShortBuffer()
+ {
+ return buf.asShortBuffer();
+ }
+
+ public int getInt()
+ {
+ return buf.getInt();
+ }
+
+ public ByteBuffer putInt( int value )
+ {
+ buf.putInt( value );
+ return this;
+ }
+
+ public int getInt( int index )
+ {
+ return buf.getInt( index );
+ }
+
+ public ByteBuffer putInt( int index, int value )
+ {
+ buf.putInt( index, value );
+ return this;
+ }
+
+ public IntBuffer asIntBuffer()
+ {
+ return buf.asIntBuffer();
+ }
+
+ public long getLong()
+ {
+ return buf.getLong();
+ }
+
+ public ByteBuffer putLong( long value )
+ {
+ buf.putLong( value );
+ return this;
+ }
+
+ public long getLong( int index )
+ {
+ return buf.getLong( index );
+ }
+
+ public ByteBuffer putLong( int index, long value )
+ {
+ buf.putLong( index, value );
+ return this;
+ }
+
+ public LongBuffer asLongBuffer()
+ {
+ return buf.asLongBuffer();
+ }
+
+ public float getFloat()
+ {
+ return buf.getFloat();
+ }
+
+ public ByteBuffer putFloat( float value )
+ {
+ buf.putFloat( value );
+ return this;
+ }
+
+ public float getFloat( int index )
+ {
+ return buf.getFloat( index );
+ }
+
+ public ByteBuffer putFloat( int index, float value )
+ {
+ buf.putFloat( index, value );
+ return this;
+ }
+
+ public FloatBuffer asFloatBuffer()
+ {
+ return buf.asFloatBuffer();
+ }
+
+ public double getDouble()
+ {
+ return buf.getDouble();
+ }
+
+ public ByteBuffer putDouble( double value )
+ {
+ buf.putDouble( value );
+ return this;
+ }
+
+ public double getDouble( int index )
+ {
+ return buf.getDouble( index );
+ }
+
+ public ByteBuffer putDouble( int index, double value )
+ {
+ buf.putDouble( index, value );
+ return this;
+ }
+
+ public DoubleBuffer asDoubleBuffer()
+ {
+ return buf.asDoubleBuffer();
+ }
+
+
+ }
+
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java b/qpid/java/common/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java
new file mode 100644
index 0000000000..4fd28c4eb5
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java
@@ -0,0 +1,227 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.mina.common.support;
+
+import org.apache.mina.common.IoFuture;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.IoFutureListener;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * A default implementation of {@link org.apache.mina.common.IoFuture}.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ */
+public class DefaultIoFuture implements IoFuture
+{
+ private final IoSession session;
+ private final Object lock;
+ private List listeners;
+ private Object result;
+ private boolean ready;
+
+
+ /**
+ * Creates a new instance.
+ *
+ * @param session an {@link IoSession} which is associated with this future
+ */
+ public DefaultIoFuture( IoSession session )
+ {
+ this.session = session;
+ this.lock = this;
+ }
+
+ /**
+ * Creates a new instance which uses the specified object as a lock.
+ */
+ public DefaultIoFuture( IoSession session, Object lock )
+ {
+ if( lock == null )
+ {
+ throw new NullPointerException( "lock" );
+ }
+ this.session = session;
+ this.lock = lock;
+ }
+
+ public IoSession getSession()
+ {
+ return session;
+ }
+
+ public Object getLock()
+ {
+ return lock;
+ }
+
+ public void join()
+ {
+ synchronized( lock )
+ {
+ while( !ready )
+ {
+ try
+ {
+ lock.wait();
+ }
+ catch( InterruptedException e )
+ {
+ }
+ }
+ }
+ }
+
+ public boolean join( long timeoutInMillis )
+ {
+ long startTime = ( timeoutInMillis <= 0 ) ? 0 : System
+ .currentTimeMillis();
+ long waitTime = timeoutInMillis;
+
+ synchronized( lock )
+ {
+ if( ready )
+ {
+ return ready;
+ }
+ else if( waitTime <= 0 )
+ {
+ return ready;
+ }
+
+ for( ;; )
+ {
+ try
+ {
+ lock.wait( waitTime );
+ }
+ catch( InterruptedException e )
+ {
+ }
+
+ if( ready )
+ return true;
+ else
+ {
+ waitTime = timeoutInMillis - ( System.currentTimeMillis() - startTime );
+ if( waitTime <= 0 )
+ {
+ return ready;
+ }
+ }
+ }
+ }
+ }
+
+ public boolean isReady()
+ {
+ synchronized( lock )
+ {
+ return ready;
+ }
+ }
+
+ /**
+ * Sets the result of the asynchronous operation, and mark it as finished.
+ */
+ protected void setValue( Object newValue )
+ {
+ synchronized( lock )
+ {
+ // Allow only once.
+ if( ready )
+ {
+ return;
+ }
+
+ result = newValue;
+ ready = true;
+ lock.notifyAll();
+
+ notifyListeners();
+ }
+ }
+
+ /**
+ * Returns the result of the asynchronous operation.
+ */
+ protected Object getValue()
+ {
+ synchronized( lock )
+ {
+ return result;
+ }
+ }
+
+ public void addListener( IoFutureListener listener )
+ {
+ if( listener == null )
+ {
+ throw new NullPointerException( "listener" );
+ }
+
+ synchronized( lock )
+ {
+ if(listeners == null)
+ {
+ listeners = new ArrayList();
+ }
+ listeners.add( listener );
+ if( ready )
+ {
+ listener.operationComplete( this );
+ }
+ }
+ }
+
+ public void removeListener( IoFutureListener listener )
+ {
+ if( listener == null )
+ {
+ throw new NullPointerException( "listener" );
+ }
+
+ synchronized( lock )
+ {
+ listeners.remove( listener );
+ }
+ }
+
+ private void notifyListeners()
+ {
+ synchronized( lock )
+ {
+
+ if(listeners != null)
+ {
+
+ for( Iterator i = listeners.iterator(); i.hasNext(); ) {
+ ( ( IoFutureListener ) i.next() ).operationComplete( this );
+ }
+ }
+ }
+ }
+}
+
+
+
diff --git a/qpid/java/common/src/main/java/org/apache/mina/common/support/IoServiceListenerSupport.java b/qpid/java/common/src/main/java/org/apache/mina/common/support/IoServiceListenerSupport.java
new file mode 100644
index 0000000000..5723ffbaa9
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/common/support/IoServiceListenerSupport.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.mina.common.support;
+
+import java.net.SocketAddress;
+import java.util.ArrayList;
+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.concurrent.CountDownLatch;
+
+import org.apache.mina.common.IoAcceptorConfig;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoFuture;
+import org.apache.mina.common.IoFutureListener;
+import org.apache.mina.common.IoHandler;
+import org.apache.mina.common.IoService;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.common.IoServiceListener;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.util.IdentityHashSet;
+
+/**
+ * A helper which provides addition and removal of {@link IoServiceListener}s and firing
+ * events.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 446526 $, $Date: 2006-09-15 01:44:11 -0400 (Fri, 15 Sep 2006) $
+ */
+public class IoServiceListenerSupport
+{
+ /**
+ * A list of {@link IoServiceListener}s.
+ */
+ private final List listeners = new ArrayList();
+
+ /**
+ * Tracks managed <tt>serviceAddress</tt>es.
+ */
+ private final Set managedServiceAddresses = new HashSet();
+
+ /**
+ * Tracks managed sesssions with <tt>serviceAddress</tt> as a key.
+ */
+ private final Map managedSessions = new HashMap();
+
+ /**
+ * Creates a new instance.
+ */
+ public IoServiceListenerSupport()
+ {
+ }
+
+ /**
+ * Adds a new listener.
+ */
+ public void add( IoServiceListener listener )
+ {
+ synchronized( listeners )
+ {
+ listeners.add( listener );
+ }
+ }
+
+ /**
+ * Removes an existing listener.
+ */
+ public void remove( IoServiceListener listener )
+ {
+ synchronized( listeners )
+ {
+ listeners.remove( listener );
+ }
+ }
+
+ public Set getManagedServiceAddresses()
+ {
+ return Collections.unmodifiableSet( managedServiceAddresses );
+ }
+
+ public boolean isManaged( SocketAddress serviceAddress )
+ {
+ synchronized( managedServiceAddresses )
+ {
+ return managedServiceAddresses.contains( serviceAddress );
+ }
+ }
+
+ public Set getManagedSessions( SocketAddress serviceAddress )
+ {
+ Set sessions;
+ synchronized( managedSessions )
+ {
+ sessions = ( Set ) managedSessions.get( serviceAddress );
+ if( sessions == null )
+ {
+ sessions = new IdentityHashSet();
+ }
+ }
+
+ synchronized( sessions )
+ {
+ return new IdentityHashSet( sessions );
+ }
+ }
+
+ /**
+ * Calls {@link IoServiceListener#serviceActivated(IoService, SocketAddress, IoHandler, IoServiceConfig)}
+ * for all registered listeners.
+ */
+ public void fireServiceActivated(
+ IoService service, SocketAddress serviceAddress,
+ IoHandler handler, IoServiceConfig config )
+ {
+ synchronized( managedServiceAddresses )
+ {
+ if( !managedServiceAddresses.add( serviceAddress ) )
+ {
+ return;
+ }
+ }
+
+ synchronized( listeners )
+ {
+ for( Iterator i = listeners.iterator(); i.hasNext(); )
+ {
+ ( ( IoServiceListener ) i.next() ).serviceActivated(
+ service, serviceAddress, handler, config );
+ }
+ }
+ }
+
+ /**
+ * Calls {@link IoServiceListener#serviceDeactivated(IoService, SocketAddress, IoHandler, IoServiceConfig)}
+ * for all registered listeners.
+ */
+ public synchronized void fireServiceDeactivated(
+ IoService service, SocketAddress serviceAddress,
+ IoHandler handler, IoServiceConfig config )
+ {
+ synchronized( managedServiceAddresses )
+ {
+ if( !managedServiceAddresses.remove( serviceAddress ) )
+ {
+ return;
+ }
+ }
+
+ try
+ {
+ synchronized( listeners )
+ {
+ for( Iterator i = listeners.iterator(); i.hasNext(); )
+ {
+ ( ( IoServiceListener ) i.next() ).serviceDeactivated(
+ service, serviceAddress, handler, config );
+ }
+ }
+ }
+ finally
+ {
+ disconnectSessions( serviceAddress, config );
+ }
+ }
+
+
+ /**
+ * Calls {@link IoServiceListener#sessionCreated(IoSession)} for all registered listeners.
+ */
+ public void fireSessionCreated( IoSession session )
+ {
+ SocketAddress serviceAddress = session.getServiceAddress();
+
+ // Get the session set.
+ boolean firstSession = false;
+ Set sessions;
+ synchronized( managedSessions )
+ {
+ sessions = ( Set ) managedSessions.get( serviceAddress );
+ if( sessions == null )
+ {
+ sessions = new IdentityHashSet();
+ managedSessions.put( serviceAddress, sessions );
+ firstSession = true;
+ }
+ }
+
+ // If already registered, ignore.
+ synchronized( sessions )
+ {
+ if ( !sessions.add( session ) )
+ {
+ return;
+ }
+ }
+
+ // If the first connector session, fire a virtual service activation event.
+ if( session.getService() instanceof IoConnector && firstSession )
+ {
+ fireServiceActivated(
+ session.getService(), session.getServiceAddress(),
+ session.getHandler(), session.getServiceConfig() );
+ }
+
+ // Fire session events.
+ session.getFilterChain().fireSessionCreated( session );
+ session.getFilterChain().fireSessionOpened( session);
+
+ // Fire listener events.
+ synchronized( listeners )
+ {
+ for( Iterator i = listeners.iterator(); i.hasNext(); )
+ {
+ ( ( IoServiceListener ) i.next() ).sessionCreated( session );
+ }
+ }
+ }
+
+ /**
+ * Calls {@link IoServiceListener#sessionDestroyed(IoSession)} for all registered listeners.
+ */
+ public void fireSessionDestroyed( IoSession session )
+ {
+ SocketAddress serviceAddress = session.getServiceAddress();
+
+ // Get the session set.
+ Set sessions;
+ boolean lastSession = false;
+ synchronized( managedSessions )
+ {
+ sessions = ( Set ) managedSessions.get( serviceAddress );
+ // Ignore if unknown.
+ if( sessions == null )
+ {
+ return;
+ }
+
+ // Try to remove the remaining empty seession set after removal.
+ synchronized( sessions )
+ {
+ sessions.remove( session );
+ if( sessions.isEmpty() )
+ {
+ managedSessions.remove( serviceAddress );
+ lastSession = true;
+ }
+ }
+ }
+
+ // Fire session events.
+ session.getFilterChain().fireSessionClosed( session );
+
+ // Fire listener events.
+ try
+ {
+ synchronized( listeners )
+ {
+ for( Iterator i = listeners.iterator(); i.hasNext(); )
+ {
+ ( ( IoServiceListener ) i.next() ).sessionDestroyed( session );
+ }
+ }
+ }
+ finally
+ {
+ // Fire a virtual service deactivation event for the last session of the connector.
+ //TODO double-check that this is *STILL* the last session. May not be the case
+ if( session.getService() instanceof IoConnector && lastSession )
+ {
+ fireServiceDeactivated(
+ session.getService(), session.getServiceAddress(),
+ session.getHandler(), session.getServiceConfig() );
+ }
+ }
+ }
+
+ private void disconnectSessions( SocketAddress serviceAddress, IoServiceConfig config )
+ {
+ if( !( config instanceof IoAcceptorConfig ) )
+ {
+ return;
+ }
+
+ if( !( ( IoAcceptorConfig ) config ).isDisconnectOnUnbind() )
+ {
+ return;
+ }
+
+ Set sessions;
+ synchronized( managedSessions )
+ {
+ sessions = ( Set ) managedSessions.get( serviceAddress );
+ }
+
+ if( sessions == null )
+ {
+ return;
+ }
+
+ Set sessionsCopy;
+
+ // Create a copy to avoid ConcurrentModificationException
+ synchronized( sessions )
+ {
+ sessionsCopy = new IdentityHashSet( sessions );
+ }
+
+ final CountDownLatch latch = new CountDownLatch(sessionsCopy.size());
+
+ for( Iterator i = sessionsCopy.iterator(); i.hasNext(); )
+ {
+ ( ( IoSession ) i.next() ).close().addListener( new IoFutureListener()
+ {
+ public void operationComplete( IoFuture future )
+ {
+ latch.countDown();
+ }
+ } );
+ }
+
+ try
+ {
+ latch.await();
+ }
+ catch( InterruptedException ie )
+ {
+ // Ignored
+ }
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferFullExeception.java b/qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferFullExeception.java
new file mode 100644
index 0000000000..47f19aa76d
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferFullExeception.java
@@ -0,0 +1,48 @@
+package org.apache.mina.filter;
+
+import org.apache.mina.common.IoFilter;/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+public class WriteBufferFullExeception extends RuntimeException
+{
+ private IoFilter.WriteRequest _writeRequest;
+
+ public WriteBufferFullExeception()
+ {
+ this(null);
+ }
+
+ public WriteBufferFullExeception(IoFilter.WriteRequest writeRequest)
+ {
+ _writeRequest = writeRequest;
+ }
+
+
+ public void setWriteRequest(IoFilter.WriteRequest writeRequest)
+ {
+ _writeRequest = writeRequest;
+ }
+
+ public IoFilter.WriteRequest getWriteRequest()
+ {
+ return _writeRequest;
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferLimitFilterBuilder.java b/qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferLimitFilterBuilder.java
new file mode 100644
index 0000000000..4e9db9071a
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferLimitFilterBuilder.java
@@ -0,0 +1,272 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.mina.filter;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.DefaultIoFilterChainBuilder;
+import org.apache.mina.common.IoFilterAdapter;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.filter.executor.ExecutorFilter;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * This filter will turn the asynchronous filterWrite method in to a blocking send when there are more than
+ * the prescribed number of messages awaiting filterWrite. It should be used in conjunction with the
+ * {@link ReadThrottleFilterBuilder} on a server as the blocking writes will allow the read thread to
+ * cause an Out of Memory exception due to a back log of unprocessed messages.
+ *
+ * This is should only be viewed as a temporary work around for DIRMINA-302.
+ *
+ * A true solution should not be implemented as a filter as this issue will always occur. On a machine
+ * where the network is slower than the local producer.
+ *
+ * Suggested improvement is to allow implementation of policices on what to do when buffer is full.
+ *
+ * They could be:
+ * Block - As this does
+ * Wait on a given Future - to drain more of the queue.. in essence this filter with high/low watermarks
+ * Throw Exception - through the client filterWrite() method to allow them to get immediate feedback on buffer state
+ *
+ * <p/>
+ * <p>Usage:
+ * <p/>
+ * <pre><code>
+ * DefaultFilterChainBuilder builder = ...
+ * WriteBufferLimitFilterBuilder filter = new WriteBufferLimitFilterBuilder();
+ * filter.attach( builder );
+ * </code></pre>
+ * <p/>
+ * or
+ * <p/>
+ * <pre><code>
+ * IoFilterChain chain = ...
+ * WriteBufferLimitFilterBuilder filter = new WriteBufferLimitFilterBuilder();
+ * filter.attach( chain );
+ * </code></pre>
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $
+ */
+public class WriteBufferLimitFilterBuilder
+{
+ public static final String PENDING_SIZE = WriteBufferLimitFilterBuilder.class.getName() + ".pendingSize";
+
+ private static int DEFAULT_CONNECTION_BUFFER_MESSAGE_COUNT = 5000;
+
+ private volatile boolean throwNotBlock = false;
+
+ private volatile int maximumConnectionBufferCount;
+ private volatile long maximumConnectionBufferSize;
+
+ private final Object _blockLock = new Object();
+
+ private int _blockWaiters = 0;
+
+
+ public WriteBufferLimitFilterBuilder()
+ {
+ this(DEFAULT_CONNECTION_BUFFER_MESSAGE_COUNT);
+ }
+
+ public WriteBufferLimitFilterBuilder(int maxWriteBufferSize)
+ {
+ setMaximumConnectionBufferCount(maxWriteBufferSize);
+ }
+
+
+ /**
+ * Set the maximum amount pending items in the writeQueue for a given session.
+ * Changing the value will only take effect when new data is received for a
+ * connection, including existing connections. Default value is 5000 msgs.
+ *
+ * @param maximumConnectionBufferCount New buffer size. Must be > 0
+ */
+ public void setMaximumConnectionBufferCount(int maximumConnectionBufferCount)
+ {
+ this.maximumConnectionBufferCount = maximumConnectionBufferCount;
+ this.maximumConnectionBufferSize = 0;
+ }
+
+ public void setMaximumConnectionBufferSize(long maximumConnectionBufferSize)
+ {
+ this.maximumConnectionBufferSize = maximumConnectionBufferSize;
+ this.maximumConnectionBufferCount = 0;
+ }
+
+ /**
+ * Attach this filter to the specified filter chain. It will search for the ThreadPoolFilter, and attach itself
+ * before and after that filter.
+ *
+ * @param chain {@link IoFilterChain} to attach self to.
+ */
+ public void attach(IoFilterChain chain)
+ {
+ String name = getThreadPoolFilterEntryName(chain.getAll());
+
+ chain.addBefore(name, getClass().getName() + ".sendlimit", new SendLimit());
+ }
+
+ /**
+ * Attach this filter to the specified builder. It will search for the
+ * {@link ExecutorFilter}, and attach itself before and after that filter.
+ *
+ * @param builder {@link DefaultIoFilterChainBuilder} to attach self to.
+ */
+ public void attach(DefaultIoFilterChainBuilder builder)
+ {
+ String name = getThreadPoolFilterEntryName(builder.getAll());
+
+ builder.addBefore(name, getClass().getName() + ".sendlimit", new SendLimit());
+ }
+
+ private String getThreadPoolFilterEntryName(List entries)
+ {
+ Iterator i = entries.iterator();
+
+ while (i.hasNext())
+ {
+ IoFilterChain.Entry entry = (IoFilterChain.Entry) i.next();
+
+ if (entry.getFilter().getClass().isAssignableFrom(ExecutorFilter.class))
+ {
+ return entry.getName();
+ }
+ }
+
+ throw new IllegalStateException("Chain does not contain a ExecutorFilter");
+ }
+
+
+ public class SendLimit extends IoFilterAdapter
+ {
+ public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception
+ {
+ try
+ {
+ waitTillSendAllowed(session);
+ }
+ catch (WriteBufferFullExeception wbfe)
+ {
+ nextFilter.exceptionCaught(session, wbfe);
+ }
+
+ if (writeRequest.getMessage() instanceof ByteBuffer)
+ {
+ increasePendingWriteSize(session, (ByteBuffer) writeRequest.getMessage());
+ }
+
+ nextFilter.filterWrite(session, writeRequest);
+ }
+
+ private void increasePendingWriteSize(IoSession session, ByteBuffer message)
+ {
+ synchronized (session)
+ {
+ Long pendingSize = getScheduledWriteBytes(session) + message.remaining();
+ session.setAttribute(PENDING_SIZE, pendingSize);
+ }
+ }
+
+ private boolean sendAllowed(IoSession session)
+ {
+ if (session.isClosing())
+ {
+ return true;
+ }
+
+ int lmswm = maximumConnectionBufferCount;
+ long lmswb = maximumConnectionBufferSize;
+
+ return (lmswm == 0 || session.getScheduledWriteRequests() < lmswm)
+ && (lmswb == 0 || getScheduledWriteBytes(session) < lmswb);
+ }
+
+ private long getScheduledWriteBytes(IoSession session)
+ {
+ synchronized (session)
+ {
+ Long i = (Long) session.getAttribute(PENDING_SIZE);
+ return null == i ? 0 : i;
+ }
+ }
+
+ private void waitTillSendAllowed(IoSession session)
+ {
+ synchronized (_blockLock)
+ {
+ if (throwNotBlock)
+ {
+ throw new WriteBufferFullExeception();
+ }
+
+ _blockWaiters++;
+
+ while (!sendAllowed(session))
+ {
+ try
+ {
+ _blockLock.wait();
+ }
+ catch (InterruptedException e)
+ {
+ // Ignore.
+ }
+ }
+ _blockWaiters--;
+ }
+ }
+
+ public void messageSent(NextFilter nextFilter, IoSession session, Object message) throws Exception
+ {
+ if (message instanceof ByteBuffer)
+ {
+ decrementPendingWriteSize(session, (ByteBuffer) message);
+ }
+ notifyWaitingWriters();
+ nextFilter.messageSent(session, message);
+ }
+
+ private void decrementPendingWriteSize(IoSession session, ByteBuffer message)
+ {
+ synchronized (session)
+ {
+ session.setAttribute(PENDING_SIZE, getScheduledWriteBytes(session) - message.remaining());
+ }
+ }
+
+ private void notifyWaitingWriters()
+ {
+ synchronized (_blockLock)
+ {
+ if (_blockWaiters != 0)
+ {
+ _blockLock.notifyAll();
+ }
+ }
+
+ }
+
+ }//SentLimit
+
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/filter/codec/OurCumulativeProtocolDecoder.java b/qpid/java/common/src/main/java/org/apache/mina/filter/codec/OurCumulativeProtocolDecoder.java
new file mode 100644
index 0000000000..3f7e206cb4
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/filter/codec/OurCumulativeProtocolDecoder.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.mina.filter.codec;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoSession;
+
+/**
+ * A {@link ProtocolDecoder} that cumulates the content of received
+ * buffers to a <em>cumulative buffer</em> to help users implement decoders.
+ * <p>
+ * If the received {@link ByteBuffer} is only a part of a message.
+ * decoders should cumulate received buffers to make a message complete or
+ * to postpone decoding until more buffers arrive.
+ * <p>
+ * Here is an example decoder that decodes CRLF terminated lines into
+ * <code>Command</code> objects:
+ * <pre>
+ * public class CRLFTerminatedCommandLineDecoder
+ * extends CumulativeProtocolDecoder {
+ *
+ * private Command parseCommand(ByteBuffer in) {
+ * // Convert the bytes in the specified buffer to a
+ * // Command object.
+ * ...
+ * }
+ *
+ * protected boolean doDecode(IoSession session, ByteBuffer in,
+ * ProtocolDecoderOutput out)
+ * throws Exception {
+ *
+ * // Remember the initial position.
+ * int start = in.position();
+ *
+ * // Now find the first CRLF in the buffer.
+ * byte previous = 0;
+ * while (in.hasRemaining()) {
+ * byte current = in.get();
+ *
+ * if (previous == '\r' && current == '\n') {
+ * // Remember the current position and limit.
+ * int position = in.position();
+ * int limit = in.limit();
+ * try {
+ * in.position(start);
+ * in.limit(position);
+ * // The bytes between in.position() and in.limit()
+ * // now contain a full CRLF terminated line.
+ * out.write(parseCommand(in.slice()));
+ * } finally {
+ * // Set the position to point right after the
+ * // detected line and set the limit to the old
+ * // one.
+ * in.position(position);
+ * in.limit(limit);
+ * }
+ * // Decoded one line; CumulativeProtocolDecoder will
+ * // call me again until I return false. So just
+ * // return true until there are no more lines in the
+ * // buffer.
+ * return true;
+ * }
+ *
+ * previous = current;
+ * }
+ *
+ * // Could not find CRLF in the buffer. Reset the initial
+ * // position to the one we recorded above.
+ * in.position(start);
+ *
+ * return false;
+ * }
+ * }
+ * </pre>
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $
+ */
+public abstract class OurCumulativeProtocolDecoder extends ProtocolDecoderAdapter {
+
+ private static final String BUFFER = OurCumulativeProtocolDecoder.class
+ .getName()
+ + ".Buffer";
+
+ /**
+ * Creates a new instance.
+ */
+ protected OurCumulativeProtocolDecoder() {
+ }
+
+ /**
+ * Cumulates content of <tt>in</tt> into internal buffer and forwards
+ * decoding request to {@link #doDecode(IoSession, ByteBuffer, ProtocolDecoderOutput)}.
+ * <tt>doDecode()</tt> is invoked repeatedly until it returns <tt>false</tt>
+ * and the cumulative buffer is NOT compacted after decoding ends.
+ *
+ * @throws IllegalStateException if your <tt>doDecode()</tt> returned
+ * <tt>true</tt> not consuming the cumulative buffer.
+ */
+ public void decode(IoSession session, ByteBuffer in,
+ ProtocolDecoderOutput out) throws Exception {
+ boolean usingSessionBuffer = true;
+ ByteBuffer buf = (ByteBuffer) session.getAttribute(BUFFER);
+ // If we have a session buffer, append data to that; otherwise
+ // use the buffer read from the network directly.
+ if (buf != null) {
+ buf.put(in);
+ buf.flip();
+ } else {
+ buf = in;
+ usingSessionBuffer = false;
+ }
+
+ for (;;) {
+ int oldPos = buf.position();
+ boolean decoded = doDecode(session, buf, out);
+ if (decoded) {
+ if (buf.position() == oldPos) {
+ throw new IllegalStateException(
+ "doDecode() can't return true when buffer is not consumed.");
+ }
+
+ if (!buf.hasRemaining()) {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+
+ // if there is any data left that cannot be decoded, we store
+ // it in a buffer in the session and next time this decoder is
+ // invoked the session buffer gets appended to
+ if (buf.hasRemaining()) {
+ storeRemainingInSession(buf, session);
+ } else {
+ if (usingSessionBuffer)
+ removeSessionBuffer(session);
+ }
+ }
+
+ /**
+ * Implement this method to consume the specified cumulative buffer and
+ * decode its content into message(s).
+ *
+ * @param in the cumulative buffer
+ * @return <tt>true</tt> if and only if there's more to decode in the buffer
+ * and you want to have <tt>doDecode</tt> method invoked again.
+ * Return <tt>false</tt> if remaining data is not enough to decode,
+ * then this method will be invoked again when more data is cumulated.
+ * @throws Exception if cannot decode <tt>in</tt>.
+ */
+ protected abstract boolean doDecode(IoSession session, ByteBuffer in,
+ ProtocolDecoderOutput out) throws Exception;
+
+ /**
+ * Releases the cumulative buffer used by the specified <tt>session</tt>.
+ * Please don't forget to call <tt>super.dispose( session )</tt> when
+ * you override this method.
+ */
+ public void dispose(IoSession session) throws Exception {
+ removeSessionBuffer(session);
+ }
+
+ private void removeSessionBuffer(IoSession session) {
+ ByteBuffer buf = (ByteBuffer) session.removeAttribute(BUFFER);
+ if (buf != null) {
+ buf.release();
+ }
+ }
+
+ private void storeRemainingInSession(ByteBuffer buf, IoSession session) {
+ ByteBuffer remainingBuf = ByteBuffer.allocate(buf.capacity());
+ remainingBuf.setAutoExpand(true);
+ remainingBuf.order(buf.order());
+ remainingBuf.put(buf);
+ session.setAttribute(BUFFER, remainingBuf);
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/filter/codec/QpidProtocolCodecFilter.java b/qpid/java/common/src/main/java/org/apache/mina/filter/codec/QpidProtocolCodecFilter.java
new file mode 100644
index 0000000000..b8c6f29720
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/filter/codec/QpidProtocolCodecFilter.java
@@ -0,0 +1,440 @@
+package org.apache.mina.filter.codec;
+
+
+/*
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*
+*/
+
+import org.apache.mina.common.*;
+import org.apache.mina.common.support.DefaultWriteFuture;
+import org.apache.mina.filter.codec.support.SimpleProtocolDecoderOutput;
+import org.apache.mina.util.SessionLog;
+import org.apache.mina.util.Queue;
+
+
+public class QpidProtocolCodecFilter extends IoFilterAdapter
+{
+ public static final String ENCODER = QpidProtocolCodecFilter.class.getName() + ".encoder";
+ public static final String DECODER = QpidProtocolCodecFilter.class.getName() + ".decoder";
+
+ private static final Class[] EMPTY_PARAMS = new Class[0];
+ private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.wrap( new byte[0] );
+
+ private final ProtocolCodecFactory factory;
+
+ public QpidProtocolCodecFilter( ProtocolCodecFactory factory )
+ {
+ if( factory == null )
+ {
+ throw new NullPointerException( "factory" );
+ }
+ this.factory = factory;
+ }
+
+ public QpidProtocolCodecFilter( final ProtocolEncoder encoder, final ProtocolDecoder decoder )
+ {
+ if( encoder == null )
+ {
+ throw new NullPointerException( "encoder" );
+ }
+ if( decoder == null )
+ {
+ throw new NullPointerException( "decoder" );
+ }
+
+ this.factory = new ProtocolCodecFactory()
+ {
+ public ProtocolEncoder getEncoder()
+ {
+ return encoder;
+ }
+
+ public ProtocolDecoder getDecoder()
+ {
+ return decoder;
+ }
+ };
+ }
+
+ public QpidProtocolCodecFilter( final Class encoderClass, final Class decoderClass )
+ {
+ if( encoderClass == null )
+ {
+ throw new NullPointerException( "encoderClass" );
+ }
+ if( decoderClass == null )
+ {
+ throw new NullPointerException( "decoderClass" );
+ }
+ if( !ProtocolEncoder.class.isAssignableFrom( encoderClass ) )
+ {
+ throw new IllegalArgumentException( "encoderClass: " + encoderClass.getName() );
+ }
+ if( !ProtocolDecoder.class.isAssignableFrom( decoderClass ) )
+ {
+ throw new IllegalArgumentException( "decoderClass: " + decoderClass.getName() );
+ }
+ try
+ {
+ encoderClass.getConstructor( EMPTY_PARAMS );
+ }
+ catch( NoSuchMethodException e )
+ {
+ throw new IllegalArgumentException( "encoderClass doesn't have a public default constructor." );
+ }
+ try
+ {
+ decoderClass.getConstructor( EMPTY_PARAMS );
+ }
+ catch( NoSuchMethodException e )
+ {
+ throw new IllegalArgumentException( "decoderClass doesn't have a public default constructor." );
+ }
+
+ this.factory = new ProtocolCodecFactory()
+ {
+ public ProtocolEncoder getEncoder() throws Exception
+ {
+ return ( ProtocolEncoder ) encoderClass.newInstance();
+ }
+
+ public ProtocolDecoder getDecoder() throws Exception
+ {
+ return ( ProtocolDecoder ) decoderClass.newInstance();
+ }
+ };
+ }
+
+ public void onPreAdd( IoFilterChain parent, String name, IoFilter.NextFilter nextFilter ) throws Exception
+ {
+ if( parent.contains( ProtocolCodecFilter.class ) )
+ {
+ throw new IllegalStateException( "A filter chain cannot contain more than one QpidProtocolCodecFilter." );
+ }
+ }
+
+ public void messageReceived( IoFilter.NextFilter nextFilter, IoSession session, Object message ) throws Exception
+ {
+ if( !( message instanceof ByteBuffer ) )
+ {
+ nextFilter.messageReceived( session, message );
+ return;
+ }
+
+ ByteBuffer in = ( ByteBuffer ) message;
+ ProtocolDecoder decoder = getDecoder( session );
+ ProtocolDecoderOutput decoderOut = getDecoderOut( session, nextFilter );
+
+ try
+ {
+ decoder.decode( session, in, decoderOut );
+ }
+ catch( Throwable t )
+ {
+ ProtocolDecoderException pde;
+ if( t instanceof ProtocolDecoderException )
+ {
+ pde = ( ProtocolDecoderException ) t;
+ }
+ else
+ {
+ pde = new ProtocolDecoderException( t );
+ }
+ pde.setHexdump( in.getHexDump() );
+ throw pde;
+ }
+ finally
+ {
+ // Dispose the decoder if this session is connectionless.
+ if( session.getTransportType().isConnectionless() )
+ {
+ disposeDecoder( session );
+ }
+
+ // Release the read buffer.
+ in.release();
+
+ decoderOut.flush();
+ }
+ }
+
+ public void messageSent( IoFilter.NextFilter nextFilter, IoSession session, Object message ) throws Exception
+ {
+ if( message instanceof HiddenByteBuffer )
+ {
+ return;
+ }
+
+ if( !( message instanceof MessageByteBuffer ) )
+ {
+ nextFilter.messageSent( session, message );
+ return;
+ }
+
+ nextFilter.messageSent( session, ( ( MessageByteBuffer ) message ).message );
+ }
+
+ public void filterWrite( IoFilter.NextFilter nextFilter, IoSession session, IoFilter.WriteRequest writeRequest ) throws Exception
+ {
+ Object message = writeRequest.getMessage();
+ if( message instanceof ByteBuffer )
+ {
+ nextFilter.filterWrite( session, writeRequest );
+ return;
+ }
+
+ ProtocolEncoder encoder = getEncoder( session );
+ ProtocolEncoderOutputImpl encoderOut = getEncoderOut( session, nextFilter, writeRequest );
+
+ try
+ {
+ encoder.encode( session, message, encoderOut );
+ encoderOut.flush();
+ nextFilter.filterWrite(
+ session,
+ new IoFilter.WriteRequest(
+ new MessageByteBuffer( writeRequest.getMessage() ),
+ writeRequest.getFuture(), writeRequest.getDestination() ) );
+ }
+ catch( Throwable t )
+ {
+ ProtocolEncoderException pee;
+ if( t instanceof ProtocolEncoderException )
+ {
+ pee = ( ProtocolEncoderException ) t;
+ }
+ else
+ {
+ pee = new ProtocolEncoderException( t );
+ }
+ throw pee;
+ }
+ finally
+ {
+ // Dispose the encoder if this session is connectionless.
+ if( session.getTransportType().isConnectionless() )
+ {
+ disposeEncoder( session );
+ }
+ }
+ }
+
+ public void sessionClosed( IoFilter.NextFilter nextFilter, IoSession session ) throws Exception
+ {
+ // Call finishDecode() first when a connection is closed.
+ ProtocolDecoder decoder = getDecoder( session );
+ ProtocolDecoderOutput decoderOut = getDecoderOut( session, nextFilter );
+ try
+ {
+ decoder.finishDecode( session, decoderOut );
+ }
+ catch( Throwable t )
+ {
+ ProtocolDecoderException pde;
+ if( t instanceof ProtocolDecoderException )
+ {
+ pde = ( ProtocolDecoderException ) t;
+ }
+ else
+ {
+ pde = new ProtocolDecoderException( t );
+ }
+ throw pde;
+ }
+ finally
+ {
+ // Dispose all.
+ disposeEncoder( session );
+ disposeDecoder( session );
+
+ decoderOut.flush();
+ }
+
+ nextFilter.sessionClosed( session );
+ }
+
+ private ProtocolEncoder getEncoder( IoSession session ) throws Exception
+ {
+ ProtocolEncoder encoder = ( ProtocolEncoder ) session.getAttribute( ENCODER );
+ if( encoder == null )
+ {
+ encoder = factory.getEncoder();
+ session.setAttribute( ENCODER, encoder );
+ }
+ return encoder;
+ }
+
+ private ProtocolEncoderOutputImpl getEncoderOut( IoSession session, IoFilter.NextFilter nextFilter, IoFilter.WriteRequest writeRequest )
+ {
+ return new ProtocolEncoderOutputImpl( session, nextFilter, writeRequest );
+ }
+
+ private ProtocolDecoder getDecoder( IoSession session ) throws Exception
+ {
+ ProtocolDecoder decoder = ( ProtocolDecoder ) session.getAttribute( DECODER );
+ if( decoder == null )
+ {
+ decoder = factory.getDecoder();
+ session.setAttribute( DECODER, decoder );
+ }
+ return decoder;
+ }
+
+ private ProtocolDecoderOutput getDecoderOut( IoSession session, IoFilter.NextFilter nextFilter )
+ {
+ return new SimpleProtocolDecoderOutput( session, nextFilter );
+ }
+
+ private void disposeEncoder( IoSession session )
+ {
+ ProtocolEncoder encoder = ( ProtocolEncoder ) session.removeAttribute( ENCODER );
+ if( encoder == null )
+ {
+ return;
+ }
+
+ try
+ {
+ encoder.dispose( session );
+ }
+ catch( Throwable t )
+ {
+ SessionLog.warn(
+ session,
+ "Failed to dispose: " + encoder.getClass().getName() +
+ " (" + encoder + ')' );
+ }
+ }
+
+ private void disposeDecoder( IoSession session )
+ {
+ ProtocolDecoder decoder = ( ProtocolDecoder ) session.removeAttribute( DECODER );
+ if( decoder == null )
+ {
+ return;
+ }
+
+ try
+ {
+ decoder.dispose( session );
+ }
+ catch( Throwable t )
+ {
+ SessionLog.warn(
+ session,
+ "Falied to dispose: " + decoder.getClass().getName() +
+ " (" + decoder + ')' );
+ }
+ }
+
+ private static class HiddenByteBuffer extends ByteBufferProxy
+ {
+ private HiddenByteBuffer( ByteBuffer buf )
+ {
+ super( buf );
+ }
+ }
+
+ private static class MessageByteBuffer extends ByteBufferProxy
+ {
+ private final Object message;
+
+ private MessageByteBuffer( Object message )
+ {
+ super( EMPTY_BUFFER );
+ this.message = message;
+ }
+
+ public void acquire()
+ {
+ // no-op since we are wraping a zero-byte buffer, this instance is to just curry the message
+ }
+
+ public void release()
+ {
+ // no-op since we are wraping a zero-byte buffer, this instance is to just curry the message
+ }
+ }
+
+ private static class ProtocolEncoderOutputImpl implements ProtocolEncoderOutput
+ {
+ private ByteBuffer buffer;
+
+ private final IoSession session;
+ private final IoFilter.NextFilter nextFilter;
+ private final IoFilter.WriteRequest writeRequest;
+
+ public ProtocolEncoderOutputImpl( IoSession session, IoFilter.NextFilter nextFilter, IoFilter.WriteRequest writeRequest )
+ {
+ this.session = session;
+ this.nextFilter = nextFilter;
+ this.writeRequest = writeRequest;
+ }
+
+
+
+ public void write( ByteBuffer buf )
+ {
+ if(buffer != null)
+ {
+ flush();
+ }
+ buffer = buf;
+ }
+
+ public void mergeAll()
+ {
+ }
+
+ public WriteFuture flush()
+ {
+ WriteFuture future = null;
+ if( buffer == null )
+ {
+ return null;
+ }
+ else
+ {
+ ByteBuffer buf = buffer;
+ // Flush only when the buffer has remaining.
+ if( buf.hasRemaining() )
+ {
+ future = doFlush( buf );
+ }
+
+ }
+
+ return future;
+ }
+
+
+ protected WriteFuture doFlush( ByteBuffer buf )
+ {
+ WriteFuture future = new DefaultWriteFuture( session );
+ nextFilter.filterWrite(
+ session,
+ new IoFilter.WriteRequest(
+ buf,
+ future, writeRequest.getDestination() ) );
+ return future;
+ }
+ }
+}
+
diff --git a/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketAcceptor.java b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketAcceptor.java
new file mode 100644
index 0000000000..e5360d32e0
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketAcceptor.java
@@ -0,0 +1,547 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.mina.transport.socket.nio;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IoAcceptor;
+import org.apache.mina.common.IoHandler;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.common.support.BaseIoAcceptor;
+import org.apache.mina.util.Queue;
+import org.apache.mina.util.NewThreadExecutor;
+import org.apache.mina.util.NamePreservingRunnable;
+import edu.emory.mathcs.backport.java.util.concurrent.Executor;
+
+/**
+ * {@link IoAcceptor} for socket transport (TCP/IP).
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $
+ */
+public class MultiThreadSocketAcceptor extends SocketAcceptor
+{
+ /**
+ * @noinspection StaticNonFinalField
+ */
+ private static volatile int nextId = 0;
+
+ private final Executor executor;
+ private final Object lock = new Object();
+ private final int id = nextId ++;
+ private final String threadName = "SocketAcceptor-" + id;
+ private final Map channels = new HashMap();
+
+ private final Queue registerQueue = new Queue();
+ private final Queue cancelQueue = new Queue();
+
+ private final MultiThreadSocketIoProcessor[] ioProcessors;
+ private final int processorCount;
+
+ /**
+ * @noinspection FieldAccessedSynchronizedAndUnsynchronized
+ */
+ private Selector selector;
+ private Worker worker;
+ private int processorDistributor = 0;
+
+ /**
+ * Create an acceptor with a single processing thread using a NewThreadExecutor
+ */
+ public MultiThreadSocketAcceptor()
+ {
+ this( 1, new NewThreadExecutor() );
+ }
+
+ /**
+ * Create an acceptor with the desired number of processing threads
+ *
+ * @param processorCount Number of processing threads
+ * @param executor Executor to use for launching threads
+ */
+ public MultiThreadSocketAcceptor( int processorCount, Executor executor )
+ {
+ if( processorCount < 1 )
+ {
+ throw new IllegalArgumentException( "Must have at least one processor" );
+ }
+
+ this.executor = executor;
+ this.processorCount = processorCount;
+ ioProcessors = new MultiThreadSocketIoProcessor[processorCount];
+
+ for( int i = 0; i < processorCount; i++ )
+ {
+ ioProcessors[i] = new MultiThreadSocketIoProcessor( "SocketAcceptorIoProcessor-" + id + "." + i, executor );
+ }
+ }
+
+
+ /**
+ * Binds to the specified <code>address</code> and handles incoming connections with the specified
+ * <code>handler</code>. Backlog value is configured to the value of <code>backlog</code> property.
+ *
+ * @throws IOException if failed to bind
+ */
+ public void bind( SocketAddress address, IoHandler handler, IoServiceConfig config ) throws IOException
+ {
+ if( handler == null )
+ {
+ throw new NullPointerException( "handler" );
+ }
+
+ if( address != null && !( address instanceof InetSocketAddress ) )
+ {
+ throw new IllegalArgumentException( "Unexpected address type: " + address.getClass() );
+ }
+
+ if( config == null )
+ {
+ config = getDefaultConfig();
+ }
+
+ RegistrationRequest request = new RegistrationRequest( address, handler, config );
+
+ synchronized( registerQueue )
+ {
+ registerQueue.push( request );
+ }
+
+ startupWorker();
+
+ selector.wakeup();
+
+ synchronized( request )
+ {
+ while( !request.done )
+ {
+ try
+ {
+ request.wait();
+ }
+ catch( InterruptedException e )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( e );
+ }
+ }
+ }
+
+ if( request.exception != null )
+ {
+ throw request.exception;
+ }
+ }
+
+
+ private synchronized void startupWorker() throws IOException
+ {
+ synchronized( lock )
+ {
+ if( worker == null )
+ {
+ selector = Selector.open();
+ worker = new Worker();
+
+ executor.execute( new NamePreservingRunnable( worker ) );
+ }
+ }
+ }
+
+ public void unbind( SocketAddress address )
+ {
+ if( address == null )
+ {
+ throw new NullPointerException( "address" );
+ }
+
+ CancellationRequest request = new CancellationRequest( address );
+
+ try
+ {
+ startupWorker();
+ }
+ catch( IOException e )
+ {
+ // IOException is thrown only when Worker thread is not
+ // running and failed to open a selector. We simply throw
+ // IllegalArgumentException here because we can simply
+ // conclude that nothing is bound to the selector.
+ throw new IllegalArgumentException( "Address not bound: " + address );
+ }
+
+ synchronized( cancelQueue )
+ {
+ cancelQueue.push( request );
+ }
+
+ selector.wakeup();
+
+ synchronized( request )
+ {
+ while( !request.done )
+ {
+ try
+ {
+ request.wait();
+ }
+ catch( InterruptedException e )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( e );
+ }
+ }
+ }
+
+ if( request.exception != null )
+ {
+ request.exception.fillInStackTrace();
+
+ throw request.exception;
+ }
+ }
+
+
+ private class Worker implements Runnable
+ {
+ public void run()
+ {
+ Thread.currentThread().setName(MultiThreadSocketAcceptor.this.threadName );
+
+ for( ; ; )
+ {
+ try
+ {
+ int nKeys = selector.select();
+
+ registerNew();
+
+ if( nKeys > 0 )
+ {
+ processSessions( selector.selectedKeys() );
+ }
+
+ cancelKeys();
+
+ if( selector.keys().isEmpty() )
+ {
+ synchronized( lock )
+ {
+ if( selector.keys().isEmpty() &&
+ registerQueue.isEmpty() &&
+ cancelQueue.isEmpty() )
+ {
+ worker = null;
+ try
+ {
+ selector.close();
+ }
+ catch( IOException e )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( e );
+ }
+ finally
+ {
+ selector = null;
+ }
+ break;
+ }
+ }
+ }
+ }
+ catch( IOException e )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( e );
+
+ try
+ {
+ Thread.sleep( 1000 );
+ }
+ catch( InterruptedException e1 )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( e1 );
+ }
+ }
+ }
+ }
+
+ private void processSessions( Set keys ) throws IOException
+ {
+ Iterator it = keys.iterator();
+ while( it.hasNext() )
+ {
+ SelectionKey key = ( SelectionKey ) it.next();
+
+ it.remove();
+
+ if( !key.isAcceptable() )
+ {
+ continue;
+ }
+
+ ServerSocketChannel ssc = ( ServerSocketChannel ) key.channel();
+
+ SocketChannel ch = ssc.accept();
+
+ if( ch == null )
+ {
+ continue;
+ }
+
+ boolean success = false;
+ try
+ {
+
+ RegistrationRequest req = ( RegistrationRequest ) key.attachment();
+
+ MultiThreadSocketSessionImpl session = new MultiThreadSocketSessionImpl(
+ MultiThreadSocketAcceptor.this, nextProcessor(), getListeners(),
+ req.config, ch, req.handler, req.address );
+
+ // New Interface
+// SocketSessionImpl session = new SocketSessionImpl(
+// SocketAcceptor.this, nextProcessor(), getListeners(),
+// req.config, ch, req.handler, req.address );
+
+
+ getFilterChainBuilder().buildFilterChain( session.getFilterChain() );
+ req.config.getFilterChainBuilder().buildFilterChain( session.getFilterChain() );
+ req.config.getThreadModel().buildFilterChain( session.getFilterChain() );
+ session.getIoProcessor().addNew( session );
+ success = true;
+ }
+ catch( Throwable t )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( t );
+ }
+ finally
+ {
+ if( !success )
+ {
+ ch.close();
+ }
+ }
+ }
+ }
+ }
+
+ private MultiThreadSocketIoProcessor nextProcessor()
+ {
+ return ioProcessors[processorDistributor++ % processorCount];
+ }
+
+
+ private void registerNew()
+ {
+ if( registerQueue.isEmpty() )
+ {
+ return;
+ }
+
+ for( ; ; )
+ {
+ RegistrationRequest req;
+
+ synchronized( registerQueue )
+ {
+ req = ( RegistrationRequest ) registerQueue.pop();
+ }
+
+ if( req == null )
+ {
+ break;
+ }
+
+ ServerSocketChannel ssc = null;
+
+ try
+ {
+ ssc = ServerSocketChannel.open();
+ ssc.configureBlocking( false );
+
+ // Configure the server socket,
+ SocketAcceptorConfig cfg;
+ if( req.config instanceof SocketAcceptorConfig )
+ {
+ cfg = ( SocketAcceptorConfig ) req.config;
+ }
+ else
+ {
+ cfg = ( SocketAcceptorConfig ) getDefaultConfig();
+ }
+
+ ssc.socket().setReuseAddress( cfg.isReuseAddress() );
+ ssc.socket().setReceiveBufferSize(
+ ( ( SocketSessionConfig ) cfg.getSessionConfig() ).getReceiveBufferSize() );
+
+ // and bind.
+ ssc.socket().bind( req.address, cfg.getBacklog() );
+ if( req.address == null || req.address.getPort() == 0 )
+ {
+ req.address = ( InetSocketAddress ) ssc.socket().getLocalSocketAddress();
+ }
+ ssc.register( selector, SelectionKey.OP_ACCEPT, req );
+
+ synchronized( channels )
+ {
+ channels.put( req.address, ssc );
+ }
+
+ getListeners().fireServiceActivated(
+ this, req.address, req.handler, req.config );
+ }
+ catch( IOException e )
+ {
+ req.exception = e;
+ }
+ finally
+ {
+ synchronized( req )
+ {
+ req.done = true;
+
+ req.notifyAll();
+ }
+
+ if( ssc != null && req.exception != null )
+ {
+ try
+ {
+ ssc.close();
+ }
+ catch( IOException e )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( e );
+ }
+ }
+ }
+ }
+ }
+
+
+ private void cancelKeys()
+ {
+ if( cancelQueue.isEmpty() )
+ {
+ return;
+ }
+
+ for( ; ; )
+ {
+ CancellationRequest request;
+
+ synchronized( cancelQueue )
+ {
+ request = ( CancellationRequest ) cancelQueue.pop();
+ }
+
+ if( request == null )
+ {
+ break;
+ }
+
+ ServerSocketChannel ssc;
+ synchronized( channels )
+ {
+ ssc = ( ServerSocketChannel ) channels.remove( request.address );
+ }
+
+ // close the channel
+ try
+ {
+ if( ssc == null )
+ {
+ request.exception = new IllegalArgumentException( "Address not bound: " + request.address );
+ }
+ else
+ {
+ SelectionKey key = ssc.keyFor( selector );
+ request.registrationRequest = ( RegistrationRequest ) key.attachment();
+ key.cancel();
+
+ selector.wakeup(); // wake up again to trigger thread death
+
+ ssc.close();
+ }
+ }
+ catch( IOException e )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( e );
+ }
+ finally
+ {
+ synchronized( request )
+ {
+ request.done = true;
+ request.notifyAll();
+ }
+
+ if( request.exception == null )
+ {
+ getListeners().fireServiceDeactivated(
+ this, request.address,
+ request.registrationRequest.handler,
+ request.registrationRequest.config );
+ }
+ }
+ }
+ }
+
+ private static class RegistrationRequest
+ {
+ private InetSocketAddress address;
+ private final IoHandler handler;
+ private final IoServiceConfig config;
+ private IOException exception;
+ private boolean done;
+
+ private RegistrationRequest( SocketAddress address, IoHandler handler, IoServiceConfig config )
+ {
+ this.address = ( InetSocketAddress ) address;
+ this.handler = handler;
+ this.config = config;
+ }
+ }
+
+
+ private static class CancellationRequest
+ {
+ private final SocketAddress address;
+ private boolean done;
+ private RegistrationRequest registrationRequest;
+ private RuntimeException exception;
+
+ private CancellationRequest( SocketAddress address )
+ {
+ this.address = address;
+ }
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketConnector.java b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketConnector.java
new file mode 100644
index 0000000000..7344f70078
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketConnector.java
@@ -0,0 +1,486 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.mina.transport.socket.nio;
+
+import edu.emory.mathcs.backport.java.util.concurrent.Executor;
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoConnectorConfig;
+import org.apache.mina.common.IoHandler;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.common.support.AbstractIoFilterChain;
+import org.apache.mina.common.support.DefaultConnectFuture;
+import org.apache.mina.util.NamePreservingRunnable;
+import org.apache.mina.util.NewThreadExecutor;
+import org.apache.mina.util.Queue;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * {@link IoConnector} for socket transport (TCP/IP).
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $
+ */
+public class MultiThreadSocketConnector extends SocketConnector
+{
+ /** @noinspection StaticNonFinalField */
+ private static volatile int nextId = 0;
+
+ private final Object lock = new Object();
+ private final int id = nextId++;
+ private final String threadName = "SocketConnector-" + id;
+
+ private final Queue connectQueue = new Queue();
+ private final MultiThreadSocketIoProcessor[] ioProcessors;
+ private final int processorCount;
+ private final Executor executor;
+
+ /** @noinspection FieldAccessedSynchronizedAndUnsynchronized */
+ private Selector selector;
+ private Worker worker;
+ private int processorDistributor = 0;
+ private int workerTimeout = 60; // 1 min.
+
+ /** Create a connector with a single processing thread using a NewThreadExecutor */
+ public MultiThreadSocketConnector()
+ {
+ this(1, new NewThreadExecutor());
+ }
+
+ /**
+ * Create a connector with the desired number of processing threads
+ *
+ * @param processorCount Number of processing threads
+ * @param executor Executor to use for launching threads
+ */
+ public MultiThreadSocketConnector(int processorCount, Executor executor)
+ {
+ if (processorCount < 1)
+ {
+ throw new IllegalArgumentException("Must have at least one processor");
+ }
+
+ this.executor = executor;
+ this.processorCount = processorCount;
+ ioProcessors = new MultiThreadSocketIoProcessor[processorCount];
+
+ for (int i = 0; i < processorCount; i++)
+ {
+ ioProcessors[i] = new MultiThreadSocketIoProcessor("SocketConnectorIoProcessor-" + id + "." + i, executor);
+ }
+ }
+
+ /**
+ * How many seconds to keep the connection thread alive between connection requests
+ *
+ * @return Number of seconds to keep connection thread alive
+ */
+ public int getWorkerTimeout()
+ {
+ return workerTimeout;
+ }
+
+ /**
+ * Set how many seconds the connection worker thread should remain alive once idle before terminating itself.
+ *
+ * @param workerTimeout Number of seconds to keep thread alive. Must be >=0
+ */
+ public void setWorkerTimeout(int workerTimeout)
+ {
+ if (workerTimeout < 0)
+ {
+ throw new IllegalArgumentException("Must be >= 0");
+ }
+ this.workerTimeout = workerTimeout;
+ }
+
+ public ConnectFuture connect(SocketAddress address, IoHandler handler, IoServiceConfig config)
+ {
+ return connect(address, null, handler, config);
+ }
+
+ public ConnectFuture connect(SocketAddress address, SocketAddress localAddress,
+ IoHandler handler, IoServiceConfig config)
+ {
+ if (address == null)
+ {
+ throw new NullPointerException("address");
+ }
+ if (handler == null)
+ {
+ throw new NullPointerException("handler");
+ }
+
+ if (!(address instanceof InetSocketAddress))
+ {
+ throw new IllegalArgumentException("Unexpected address type: "
+ + address.getClass());
+ }
+
+ if (localAddress != null && !(localAddress instanceof InetSocketAddress))
+ {
+ throw new IllegalArgumentException("Unexpected local address type: "
+ + localAddress.getClass());
+ }
+
+ if (config == null)
+ {
+ config = getDefaultConfig();
+ }
+
+ SocketChannel ch = null;
+ boolean success = false;
+ try
+ {
+ ch = SocketChannel.open();
+ ch.socket().setReuseAddress(true);
+ if (localAddress != null)
+ {
+ ch.socket().bind(localAddress);
+ }
+
+ ch.configureBlocking(false);
+
+ if (ch.connect(address))
+ {
+ DefaultConnectFuture future = new DefaultConnectFuture();
+ newSession(ch, handler, config, future);
+ success = true;
+ return future;
+ }
+
+ success = true;
+ }
+ catch (IOException e)
+ {
+ return DefaultConnectFuture.newFailedFuture(e);
+ }
+ finally
+ {
+ if (!success && ch != null)
+ {
+ try
+ {
+ ch.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ }
+ }
+
+ ConnectionRequest request = new ConnectionRequest(ch, handler, config);
+ synchronized (lock)
+ {
+ try
+ {
+ startupWorker();
+ }
+ catch (IOException e)
+ {
+ try
+ {
+ ch.close();
+ }
+ catch (IOException e2)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e2);
+ }
+
+ return DefaultConnectFuture.newFailedFuture(e);
+ }
+ }
+
+ synchronized (connectQueue)
+ {
+ connectQueue.push(request);
+ }
+ selector.wakeup();
+
+ return request;
+ }
+
+ private synchronized void startupWorker() throws IOException
+ {
+ if (worker == null)
+ {
+ selector = Selector.open();
+ worker = new Worker();
+ executor.execute(new NamePreservingRunnable(worker));
+ }
+ }
+
+ private void registerNew()
+ {
+ if (connectQueue.isEmpty())
+ {
+ return;
+ }
+
+ for (; ;)
+ {
+ ConnectionRequest req;
+ synchronized (connectQueue)
+ {
+ req = (ConnectionRequest) connectQueue.pop();
+ }
+
+ if (req == null)
+ {
+ break;
+ }
+
+ SocketChannel ch = req.channel;
+ try
+ {
+ ch.register(selector, SelectionKey.OP_CONNECT, req);
+ }
+ catch (IOException e)
+ {
+ req.setException(e);
+ }
+ }
+ }
+
+ private void processSessions(Set keys)
+ {
+ Iterator it = keys.iterator();
+
+ while (it.hasNext())
+ {
+ SelectionKey key = (SelectionKey) it.next();
+
+ if (!key.isConnectable())
+ {
+ continue;
+ }
+
+ SocketChannel ch = (SocketChannel) key.channel();
+ ConnectionRequest entry = (ConnectionRequest) key.attachment();
+
+ boolean success = false;
+ try
+ {
+ ch.finishConnect();
+ newSession(ch, entry.handler, entry.config, entry);
+ success = true;
+ }
+ catch (Throwable e)
+ {
+ entry.setException(e);
+ }
+ finally
+ {
+ key.cancel();
+ if (!success)
+ {
+ try
+ {
+ ch.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ }
+ }
+ }
+
+ keys.clear();
+ }
+
+ private void processTimedOutSessions(Set keys)
+ {
+ long currentTime = System.currentTimeMillis();
+ Iterator it = keys.iterator();
+
+ while (it.hasNext())
+ {
+ SelectionKey key = (SelectionKey) it.next();
+
+ if (!key.isValid())
+ {
+ continue;
+ }
+
+ ConnectionRequest entry = (ConnectionRequest) key.attachment();
+
+ if (currentTime >= entry.deadline)
+ {
+ entry.setException(new ConnectException());
+ try
+ {
+ key.channel().close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ finally
+ {
+ key.cancel();
+ }
+ }
+ }
+ }
+
+ private void newSession(SocketChannel ch, IoHandler handler, IoServiceConfig config, ConnectFuture connectFuture)
+ throws IOException
+ {
+ MultiThreadSocketSessionImpl session =
+ new MultiThreadSocketSessionImpl(this, nextProcessor(), getListeners(),
+ config, ch, handler, ch.socket().getRemoteSocketAddress());
+
+ //new interface
+// SocketSessionImpl session = new SocketSessionImpl(
+// this, nextProcessor(), getListeners(),
+// config, ch, handler, ch.socket().getRemoteSocketAddress() );
+ try
+ {
+ getFilterChainBuilder().buildFilterChain(session.getFilterChain());
+ config.getFilterChainBuilder().buildFilterChain(session.getFilterChain());
+ config.getThreadModel().buildFilterChain(session.getFilterChain());
+ }
+ catch (Throwable e)
+ {
+ throw (IOException) new IOException("Failed to create a session.").initCause(e);
+ }
+
+ // Set the ConnectFuture of the specified session, which will be
+ // removed and notified by AbstractIoFilterChain eventually.
+ session.setAttribute( AbstractIoFilterChain.CONNECT_FUTURE, connectFuture );
+
+ // Forward the remaining process to the SocketIoProcessor.
+ session.getIoProcessor().addNew(session);
+ }
+
+ private MultiThreadSocketIoProcessor nextProcessor()
+ {
+ return ioProcessors[processorDistributor++ % processorCount];
+ }
+
+ private class Worker implements Runnable
+ {
+ private long lastActive = System.currentTimeMillis();
+
+ public void run()
+ {
+ Thread.currentThread().setName(MultiThreadSocketConnector.this.threadName);
+
+ for (; ;)
+ {
+ try
+ {
+ int nKeys = selector.select(1000);
+
+ registerNew();
+
+ if (nKeys > 0)
+ {
+ processSessions(selector.selectedKeys());
+ }
+
+ processTimedOutSessions(selector.keys());
+
+ if (selector.keys().isEmpty())
+ {
+ if (System.currentTimeMillis() - lastActive > workerTimeout * 1000L)
+ {
+ synchronized (lock)
+ {
+ if (selector.keys().isEmpty() &&
+ connectQueue.isEmpty())
+ {
+ worker = null;
+ try
+ {
+ selector.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ finally
+ {
+ selector = null;
+ }
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ lastActive = System.currentTimeMillis();
+ }
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e1)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e1);
+ }
+ }
+ }
+ }
+ }
+
+ private class ConnectionRequest extends DefaultConnectFuture
+ {
+ private final SocketChannel channel;
+ private final long deadline;
+ private final IoHandler handler;
+ private final IoServiceConfig config;
+
+ private ConnectionRequest(SocketChannel channel, IoHandler handler, IoServiceConfig config)
+ {
+ this.channel = channel;
+ long timeout;
+ if (config instanceof IoConnectorConfig)
+ {
+ timeout = ((IoConnectorConfig) config).getConnectTimeoutMillis();
+ }
+ else
+ {
+ timeout = ((IoConnectorConfig) getDefaultConfig()).getConnectTimeoutMillis();
+ }
+ this.deadline = System.currentTimeMillis() + timeout;
+ this.handler = handler;
+ this.config = config;
+ }
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketFilterChain.java b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketFilterChain.java
new file mode 100644
index 0000000000..67b8c8d820
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketFilterChain.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.mina.transport.socket.nio;
+
+import java.io.IOException;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.IoFilter.WriteRequest;
+import org.apache.mina.common.support.AbstractIoFilterChain;
+import org.apache.mina.util.Queue;
+
+/**
+ * An {@link IoFilterChain} for socket transport (TCP/IP).
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ */
+class MultiThreadSocketFilterChain extends AbstractIoFilterChain {
+
+ MultiThreadSocketFilterChain( IoSession parent )
+ {
+ super( parent );
+ }
+
+ protected void doWrite( IoSession session, WriteRequest writeRequest )
+ {
+ MultiThreadSocketSessionImpl s = (MultiThreadSocketSessionImpl) session;
+ Queue writeRequestQueue = s.getWriteRequestQueue();
+
+ // SocketIoProcessor.doFlush() will reset it after write is finished
+ // because the buffer will be passed with messageSent event.
+ ( ( ByteBuffer ) writeRequest.getMessage() ).mark();
+ synchronized( writeRequestQueue )
+ {
+ writeRequestQueue.push( writeRequest );
+ if( writeRequestQueue.size() == 1 && session.getTrafficMask().isWritable() )
+ {
+ // Notify SocketIoProcessor only when writeRequestQueue was empty.
+ s.getIoProcessor().flush( s );
+ }
+ }
+ }
+
+ protected void doClose( IoSession session ) throws IOException
+ {
+ MultiThreadSocketSessionImpl s = (MultiThreadSocketSessionImpl) session;
+ s.getIoProcessor().remove( s );
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketIoProcessor.java b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketIoProcessor.java
new file mode 100644
index 0000000000..c23ad8686f
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketIoProcessor.java
@@ -0,0 +1,1026 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.mina.transport.socket.nio;
+
+import edu.emory.mathcs.backport.java.util.concurrent.Executor;
+import edu.emory.mathcs.backport.java.util.concurrent.locks.ReentrantLock;
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IdleStatus;
+import org.apache.mina.common.IoFilter.WriteRequest;
+import org.apache.mina.common.WriteTimeoutException;
+import org.apache.mina.util.IdentityHashSet;
+import org.apache.mina.util.NamePreservingRunnable;
+import org.apache.mina.util.Queue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * Performs all I/O operations for sockets which is connected or bound. This class is used by MINA internally.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $,
+ */
+class MultiThreadSocketIoProcessor extends SocketIoProcessor
+{
+ Logger _logger = LoggerFactory.getLogger(MultiThreadSocketIoProcessor.class);
+ Logger _loggerRead = LoggerFactory.getLogger(MultiThreadSocketIoProcessor.class + ".Reader");
+ Logger _loggerWrite = LoggerFactory.getLogger(MultiThreadSocketIoProcessor.class + ".Writer");
+
+ private static final long SELECTOR_TIMEOUT = 1000L;
+
+ private int MAX_READ_BYTES_PER_SESSION = 524288; //512K
+ private int MAX_FLUSH_BYTES_PER_SESSION = 524288; //512K
+
+ private final Object readLock = new Object();
+ private final Object writeLock = new Object();
+
+ private final String threadName;
+ private final Executor executor;
+
+ private ReentrantLock trafficMaskUpdateLock = new ReentrantLock();
+
+ /** @noinspection FieldAccessedSynchronizedAndUnsynchronized */
+ private volatile Selector selector, writeSelector;
+
+ private final Queue newSessions = new Queue();
+ private final Queue removingSessions = new Queue();
+ private final BlockingQueue flushingSessions = new LinkedBlockingQueue();
+ private final IdentityHashSet flushingSessionsSet = new IdentityHashSet();
+
+ private final Queue trafficControllingSessions = new Queue();
+
+ private ReadWorker readWorker;
+ private WriteWorker writeWorker;
+ private long lastIdleReadCheckTime = System.currentTimeMillis();
+ private long lastIdleWriteCheckTime = System.currentTimeMillis();
+
+ MultiThreadSocketIoProcessor(String threadName, Executor executor)
+ {
+ super(threadName, executor);
+ this.threadName = threadName;
+ this.executor = executor;
+ }
+
+ void addNew(SocketSessionImpl session) throws IOException
+ {
+ synchronized (newSessions)
+ {
+ newSessions.push(session);
+ }
+
+ startupWorker();
+
+ selector.wakeup();
+ writeSelector.wakeup();
+ }
+
+ void remove(SocketSessionImpl session) throws IOException
+ {
+ scheduleRemove(session);
+ startupWorker();
+ selector.wakeup();
+ }
+
+ private void startupWorker() throws IOException
+ {
+ synchronized (readLock)
+ {
+ if (readWorker == null)
+ {
+ selector = Selector.open();
+ readWorker = new ReadWorker();
+ executor.execute(new NamePreservingRunnable(readWorker));
+ }
+ }
+
+ synchronized (writeLock)
+ {
+ if (writeWorker == null)
+ {
+ writeSelector = Selector.open();
+ writeWorker = new WriteWorker();
+ executor.execute(new NamePreservingRunnable(writeWorker));
+ }
+ }
+
+ }
+
+ void flush(SocketSessionImpl session)
+ {
+ scheduleFlush(session);
+ Selector selector = this.writeSelector;
+
+ if (selector != null)
+ {
+ selector.wakeup();
+ }
+ }
+
+ void updateTrafficMask(SocketSessionImpl session)
+ {
+ scheduleTrafficControl(session);
+ Selector selector = this.selector;
+ if (selector != null)
+ {
+ selector.wakeup();
+ }
+ }
+
+ private void scheduleRemove(SocketSessionImpl session)
+ {
+ synchronized (removingSessions)
+ {
+ removingSessions.push(session);
+ }
+ }
+
+ private void scheduleFlush(SocketSessionImpl session)
+ {
+ synchronized (flushingSessionsSet)
+ {
+ //if flushingSessions grows to contain Integer.MAX_VALUE sessions
+ // then this will fail.
+ if (flushingSessionsSet.add(session))
+ {
+ flushingSessions.offer(session);
+ }
+ }
+ }
+
+ private void scheduleTrafficControl(SocketSessionImpl session)
+ {
+ synchronized (trafficControllingSessions)
+ {
+ trafficControllingSessions.push(session);
+ }
+ }
+
+ private void doAddNewReader() throws InterruptedException
+ {
+ if (newSessions.isEmpty())
+ {
+ return;
+ }
+
+ for (; ;)
+ {
+ MultiThreadSocketSessionImpl session;
+
+ synchronized (newSessions)
+ {
+ session = (MultiThreadSocketSessionImpl) newSessions.peek();
+ }
+
+ if (session == null)
+ {
+ break;
+ }
+
+ SocketChannel ch = session.getChannel();
+
+
+ try
+ {
+
+ ch.configureBlocking(false);
+ session.setSelectionKey(ch.register(selector,
+ SelectionKey.OP_READ,
+ session));
+
+ //System.out.println("ReadDebug:"+"Awaiting Registration");
+ session.awaitRegistration();
+ sessionCreated(session);
+ }
+ catch (IOException e)
+ {
+ // Clear the AbstractIoFilterChain.CONNECT_FUTURE attribute
+ // and call ConnectFuture.setException().
+ session.getFilterChain().fireExceptionCaught(session, e);
+ }
+ }
+ }
+
+
+ private void doAddNewWrite() throws InterruptedException
+ {
+ if (newSessions.isEmpty())
+ {
+ return;
+ }
+
+ for (; ;)
+ {
+ MultiThreadSocketSessionImpl session;
+
+ synchronized (newSessions)
+ {
+ session = (MultiThreadSocketSessionImpl) newSessions.peek();
+ }
+
+ if (session == null)
+ {
+ break;
+ }
+
+ SocketChannel ch = session.getChannel();
+
+ try
+ {
+ ch.configureBlocking(false);
+ synchronized (flushingSessionsSet)
+ {
+ flushingSessionsSet.add(session);
+ }
+
+ session.setWriteSelectionKey(ch.register(writeSelector,
+ SelectionKey.OP_WRITE,
+ session));
+
+ //System.out.println("WriteDebug:"+"Awaiting Registration");
+ session.awaitRegistration();
+ sessionCreated(session);
+ }
+ catch (IOException e)
+ {
+
+ // Clear the AbstractIoFilterChain.CONNECT_FUTURE attribute
+ // and call ConnectFuture.setException().
+ session.getFilterChain().fireExceptionCaught(session, e);
+ }
+ }
+ }
+
+
+ private void sessionCreated(SocketSessionImpl sessionParam) throws InterruptedException
+ {
+ MultiThreadSocketSessionImpl session = (MultiThreadSocketSessionImpl) sessionParam;
+ synchronized (newSessions)
+ {
+ if (!session.created())
+ {
+ _logger.debug("Popping new session");
+ newSessions.pop();
+
+ // AbstractIoFilterChain.CONNECT_FUTURE is cleared inside here
+ // in AbstractIoFilterChain.fireSessionOpened().
+ session.getServiceListeners().fireSessionCreated(session);
+
+ session.doneCreation();
+ }
+ }
+ }
+
+ private void doRemove()
+ {
+ if (removingSessions.isEmpty())
+ {
+ return;
+ }
+
+ for (; ;)
+ {
+ MultiThreadSocketSessionImpl session;
+
+ synchronized (removingSessions)
+ {
+ session = (MultiThreadSocketSessionImpl) removingSessions.pop();
+ }
+
+ if (session == null)
+ {
+ break;
+ }
+
+ SocketChannel ch = session.getChannel();
+ SelectionKey key = session.getReadSelectionKey();
+ SelectionKey writeKey = session.getWriteSelectionKey();
+
+ // Retry later if session is not yet fully initialized.
+ // (In case that Session.close() is called before addSession() is processed)
+ if (key == null || writeKey == null)
+ {
+ scheduleRemove(session);
+ break;
+ }
+ // skip if channel is already closed
+ if (!key.isValid() || !writeKey.isValid())
+ {
+ continue;
+ }
+
+ try
+ {
+ //System.out.println("ReadDebug:"+"Removing Session: " + System.identityHashCode(session));
+ synchronized (readLock)
+ {
+ key.cancel();
+ }
+ synchronized (writeLock)
+ {
+ writeKey.cancel();
+ }
+ ch.close();
+ }
+ catch (IOException e)
+ {
+ session.getFilterChain().fireExceptionCaught(session, e);
+ }
+ finally
+ {
+ releaseWriteBuffers(session);
+ session.getServiceListeners().fireSessionDestroyed(session);
+ }
+ }
+ }
+
+ private void processRead(Set selectedKeys)
+ {
+ Iterator it = selectedKeys.iterator();
+
+ while (it.hasNext())
+ {
+ SelectionKey key = (SelectionKey) it.next();
+ MultiThreadSocketSessionImpl session = (MultiThreadSocketSessionImpl) key.attachment();
+
+ synchronized (readLock)
+ {
+ if (key.isValid() && key.isReadable() && session.getTrafficMask().isReadable())
+ {
+ read(session);
+ }
+ }
+
+ }
+
+ selectedKeys.clear();
+ }
+
+ private void processWrite(Set selectedKeys)
+ {
+ Iterator it = selectedKeys.iterator();
+
+ while (it.hasNext())
+ {
+ SelectionKey key = (SelectionKey) it.next();
+ SocketSessionImpl session = (SocketSessionImpl) key.attachment();
+
+ synchronized (writeLock)
+ {
+ if (key.isValid() && key.isWritable() && session.getTrafficMask().isWritable())
+ {
+
+ // Clear OP_WRITE
+ key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE));
+
+ synchronized (flushingSessionsSet)
+ {
+ flushingSessions.offer(session);
+ }
+ }
+ }
+ }
+
+ selectedKeys.clear();
+ }
+
+ private void read(SocketSessionImpl session)
+ {
+
+ //if (_loggerWrite.isDebugEnabled())
+ {
+ //System.out.println("WriteDebug:"+"Starting read for Session:" + System.identityHashCode(session));
+ }
+
+ int totalReadBytes = 0;
+
+ while (totalReadBytes <= MAX_READ_BYTES_PER_SESSION)
+ {
+ ByteBuffer buf = ByteBuffer.allocate(session.getReadBufferSize());
+ SocketChannel ch = session.getChannel();
+
+ try
+ {
+ buf.clear();
+
+ int readBytes = 0;
+ int ret;
+
+ try
+ {
+ while ((ret = ch.read(buf.buf())) > 0)
+ {
+ readBytes += ret;
+ totalReadBytes += ret;
+ }
+ }
+ finally
+ {
+ buf.flip();
+ }
+
+
+ if (readBytes > 0)
+ {
+ session.increaseReadBytes(readBytes);
+
+ session.getFilterChain().fireMessageReceived(session, buf);
+ buf = null;
+ }
+
+ if (ret <= 0)
+ {
+ if (ret == 0)
+ {
+ if (readBytes == session.getReadBufferSize())
+ {
+ continue;
+ }
+ }
+ else
+ {
+ scheduleRemove(session);
+ }
+
+ break;
+ }
+ }
+ catch (Throwable e)
+ {
+ if (e instanceof IOException)
+ {
+ scheduleRemove(session);
+ }
+ session.getFilterChain().fireExceptionCaught(session, e);
+
+ //Stop Reading this session.
+ return;
+ }
+ finally
+ {
+ if (buf != null)
+ {
+ buf.release();
+ }
+ }
+ }//for
+
+ // if (_loggerWrite.isDebugEnabled())
+ {
+ //System.out.println("WriteDebug:"+"Read for Session:" + System.identityHashCode(session) + " got: " + totalReadBytes);
+ }
+ }
+
+
+ private void notifyReadIdleness()
+ {
+ // process idle sessions
+ long currentTime = System.currentTimeMillis();
+ if ((currentTime - lastIdleReadCheckTime) >= 1000)
+ {
+ lastIdleReadCheckTime = currentTime;
+ Set keys = selector.keys();
+ if (keys != null)
+ {
+ for (Iterator it = keys.iterator(); it.hasNext();)
+ {
+ SelectionKey key = (SelectionKey) it.next();
+ SocketSessionImpl session = (SocketSessionImpl) key.attachment();
+ notifyReadIdleness(session, currentTime);
+ }
+ }
+ }
+ }
+
+ private void notifyWriteIdleness()
+ {
+ // process idle sessions
+ long currentTime = System.currentTimeMillis();
+ if ((currentTime - lastIdleWriteCheckTime) >= 1000)
+ {
+ lastIdleWriteCheckTime = currentTime;
+ Set keys = writeSelector.keys();
+ if (keys != null)
+ {
+ for (Iterator it = keys.iterator(); it.hasNext();)
+ {
+ SelectionKey key = (SelectionKey) it.next();
+ SocketSessionImpl session = (SocketSessionImpl) key.attachment();
+ notifyWriteIdleness(session, currentTime);
+ }
+ }
+ }
+ }
+
+ private void notifyReadIdleness(SocketSessionImpl session, long currentTime)
+ {
+ notifyIdleness0(
+ session, currentTime,
+ session.getIdleTimeInMillis(IdleStatus.BOTH_IDLE),
+ IdleStatus.BOTH_IDLE,
+ Math.max(session.getLastIoTime(), session.getLastIdleTime(IdleStatus.BOTH_IDLE)));
+ notifyIdleness0(
+ session, currentTime,
+ session.getIdleTimeInMillis(IdleStatus.READER_IDLE),
+ IdleStatus.READER_IDLE,
+ Math.max(session.getLastReadTime(), session.getLastIdleTime(IdleStatus.READER_IDLE)));
+
+ notifyWriteTimeout(session, currentTime, session
+ .getWriteTimeoutInMillis(), session.getLastWriteTime());
+ }
+
+ private void notifyWriteIdleness(SocketSessionImpl session, long currentTime)
+ {
+ notifyIdleness0(
+ session, currentTime,
+ session.getIdleTimeInMillis(IdleStatus.BOTH_IDLE),
+ IdleStatus.BOTH_IDLE,
+ Math.max(session.getLastIoTime(), session.getLastIdleTime(IdleStatus.BOTH_IDLE)));
+ notifyIdleness0(
+ session, currentTime,
+ session.getIdleTimeInMillis(IdleStatus.WRITER_IDLE),
+ IdleStatus.WRITER_IDLE,
+ Math.max(session.getLastWriteTime(), session.getLastIdleTime(IdleStatus.WRITER_IDLE)));
+
+ notifyWriteTimeout(session, currentTime, session
+ .getWriteTimeoutInMillis(), session.getLastWriteTime());
+ }
+
+ private void notifyIdleness0(SocketSessionImpl session, long currentTime,
+ long idleTime, IdleStatus status,
+ long lastIoTime)
+ {
+ if (idleTime > 0 && lastIoTime != 0
+ && (currentTime - lastIoTime) >= idleTime)
+ {
+ session.increaseIdleCount(status);
+ session.getFilterChain().fireSessionIdle(session, status);
+ }
+ }
+
+ private void notifyWriteTimeout(SocketSessionImpl session,
+ long currentTime,
+ long writeTimeout, long lastIoTime)
+ {
+
+ MultiThreadSocketSessionImpl sesh = (MultiThreadSocketSessionImpl) session;
+ SelectionKey key = sesh.getWriteSelectionKey();
+
+ synchronized (writeLock)
+ {
+ if (writeTimeout > 0
+ && (currentTime - lastIoTime) >= writeTimeout
+ && key != null && key.isValid()
+ && (key.interestOps() & SelectionKey.OP_WRITE) != 0)
+ {
+ session.getFilterChain().fireExceptionCaught(session, new WriteTimeoutException());
+ }
+ }
+ }
+
+ private SocketSessionImpl getNextFlushingSession()
+ {
+ return (SocketSessionImpl) flushingSessions.poll();
+ }
+
+ private void releaseSession(SocketSessionImpl session)
+ {
+ synchronized (session.getWriteRequestQueue())
+ {
+ synchronized (flushingSessionsSet)
+ {
+ if (session.getScheduledWriteRequests() > 0)
+ {
+ if (_loggerWrite.isDebugEnabled())
+ {
+ //System.out.println("WriteDebug:"+"Reflush" + System.identityHashCode(session));
+ }
+ flushingSessions.offer(session);
+ }
+ else
+ {
+ if (_loggerWrite.isDebugEnabled())
+ {
+ //System.out.println("WriteDebug:"+"Releasing session " + System.identityHashCode(session));
+ }
+ flushingSessionsSet.remove(session);
+ }
+ }
+ }
+ }
+
+ private void releaseWriteBuffers(SocketSessionImpl session)
+ {
+ Queue writeRequestQueue = session.getWriteRequestQueue();
+ WriteRequest req;
+
+ //Should this be synchronized?
+ synchronized (writeRequestQueue)
+ {
+ while ((req = (WriteRequest) writeRequestQueue.pop()) != null)
+ {
+ try
+ {
+ ((ByteBuffer) req.getMessage()).release();
+ }
+ catch (IllegalStateException e)
+ {
+ session.getFilterChain().fireExceptionCaught(session, e);
+ }
+ finally
+ {
+ req.getFuture().setWritten(false);
+ }
+ }
+ }
+ }
+
+ private void doFlush()
+ {
+ MultiThreadSocketSessionImpl session;
+
+ while ((session = (MultiThreadSocketSessionImpl) getNextFlushingSession()) != null)
+ {
+ if (!session.isConnected())
+ {
+ releaseWriteBuffers(session);
+ releaseSession(session);
+ continue;
+ }
+
+ SelectionKey key = session.getWriteSelectionKey();
+ // Retry later if session is not yet fully initialized.
+ // (In case that Session.write() is called before addSession() is processed)
+ if (key == null)
+ {
+ scheduleFlush(session);
+ releaseSession(session);
+ continue;
+ }
+ // skip if channel is already closed
+ if (!key.isValid())
+ {
+ releaseSession(session);
+ continue;
+ }
+
+ try
+ {
+ if (doFlush(session))
+ {
+ releaseSession(session);
+ }
+ }
+ catch (IOException e)
+ {
+ releaseSession(session);
+ scheduleRemove(session);
+ session.getFilterChain().fireExceptionCaught(session, e);
+ }
+
+ }
+
+ }
+
+ private boolean doFlush(SocketSessionImpl sessionParam) throws IOException
+ {
+ MultiThreadSocketSessionImpl session = (MultiThreadSocketSessionImpl) sessionParam;
+ // Clear OP_WRITE
+ SelectionKey key = session.getWriteSelectionKey();
+ synchronized (writeLock)
+ {
+ key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE));
+ }
+ SocketChannel ch = session.getChannel();
+ Queue writeRequestQueue = session.getWriteRequestQueue();
+
+ long totalFlushedBytes = 0;
+ while (true)
+ {
+ WriteRequest req;
+
+ synchronized (writeRequestQueue)
+ {
+ req = (WriteRequest) writeRequestQueue.first();
+ }
+
+ if (req == null)
+ {
+ break;
+ }
+
+ ByteBuffer buf = (ByteBuffer) req.getMessage();
+ if (buf.remaining() == 0)
+ {
+ synchronized (writeRequestQueue)
+ {
+ writeRequestQueue.pop();
+ }
+
+ session.increaseWrittenMessages();
+
+ buf.reset();
+ session.getFilterChain().fireMessageSent(session, req);
+ continue;
+ }
+
+
+ int writtenBytes = 0;
+
+ // Reported as DIRMINA-362
+ //note: todo: fixme: Not sure it is important but if we see NoyYetConnected exceptions or 100% CPU in the kernel then this is it.
+ if (key.isWritable())
+ {
+ writtenBytes = ch.write(buf.buf());
+ totalFlushedBytes += writtenBytes;
+ }
+
+ if (writtenBytes > 0)
+ {
+ session.increaseWrittenBytes(writtenBytes);
+ }
+
+ if (buf.hasRemaining() || (totalFlushedBytes <= MAX_FLUSH_BYTES_PER_SESSION))
+ {
+ // Kernel buffer is full
+ synchronized (writeLock)
+ {
+ key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
+ }
+ if (_loggerWrite.isDebugEnabled())
+ {
+ //System.out.println("WriteDebug:"+"Written BF: " + (session.getWrittenBytes() - totalFlushedBytes) + " bytes");
+ }
+ return false;
+ }
+ }
+
+ if (_loggerWrite.isDebugEnabled())
+ {
+ //System.out.println("WriteDebug:"+"Written : " + (session.getWrittenBytes() - totalFlushedBytes) + " bytes");
+ }
+ return true;
+ }
+
+ private void doUpdateTrafficMask()
+ {
+ if (trafficControllingSessions.isEmpty() || trafficMaskUpdateLock.isLocked())
+ {
+ return;
+ }
+
+ // Synchronize over entire operation as this method should be called
+ // from both read and write thread and we don't want the order of the
+ // updates to get changed.
+ trafficMaskUpdateLock.lock();
+ try
+ {
+ for (; ;)
+ {
+ MultiThreadSocketSessionImpl session;
+
+ session = (MultiThreadSocketSessionImpl) trafficControllingSessions.pop();
+
+ if (session == null)
+ {
+ break;
+ }
+
+ SelectionKey key = session.getReadSelectionKey();
+ // Retry later if session is not yet fully initialized.
+ // (In case that Session.suspend??() or session.resume??() is
+ // called before addSession() is processed)
+ if (key == null)
+ {
+ scheduleTrafficControl(session);
+ break;
+ }
+ // skip if channel is already closed
+ if (!key.isValid())
+ {
+ continue;
+ }
+
+ // The normal is OP_READ and, if there are write requests in the
+ // session's write queue, set OP_WRITE to trigger flushing.
+
+ //Sset to Read and Write if there is nothing then the cost
+ // is one loop through the flusher.
+ int ops = SelectionKey.OP_READ;
+
+ // Now mask the preferred ops with the mask of the current session
+ int mask = session.getTrafficMask().getInterestOps();
+ synchronized (readLock)
+ {
+ key.interestOps(ops & mask);
+ }
+ //Change key to the WriteSelection Key
+ key = session.getWriteSelectionKey();
+ if (key != null && key.isValid())
+ {
+ Queue writeRequestQueue = session.getWriteRequestQueue();
+ synchronized (writeRequestQueue)
+ {
+ if (!writeRequestQueue.isEmpty())
+ {
+ ops = SelectionKey.OP_WRITE;
+ synchronized (writeLock)
+ {
+ key.interestOps(ops & mask);
+ }
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ trafficMaskUpdateLock.unlock();
+ }
+
+ }
+
+ private class WriteWorker implements Runnable
+ {
+
+ public void run()
+ {
+ Thread.currentThread().setName(MultiThreadSocketIoProcessor.this.threadName + "Writer");
+
+ //System.out.println("WriteDebug:"+"Startup");
+ for (; ;)
+ {
+ try
+ {
+ int nKeys = writeSelector.select(SELECTOR_TIMEOUT);
+
+ doAddNewWrite();
+ doUpdateTrafficMask();
+
+ if (nKeys > 0)
+ {
+ //System.out.println("WriteDebug:"+nKeys + " keys from writeselector");
+ processWrite(writeSelector.selectedKeys());
+ }
+ else
+ {
+ //System.out.println("WriteDebug:"+"No keys from writeselector");
+ }
+
+ doRemove();
+ notifyWriteIdleness();
+
+ if (flushingSessionsSet.size() > 0)
+ {
+ doFlush();
+ }
+
+ if (writeSelector.keys().isEmpty())
+ {
+ synchronized (writeLock)
+ {
+
+ if (writeSelector.keys().isEmpty() && newSessions.isEmpty())
+ {
+ writeWorker = null;
+ try
+ {
+ writeSelector.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ finally
+ {
+ writeSelector = null;
+ }
+
+ break;
+ }
+ }
+ }
+
+ }
+ catch (Throwable t)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(t);
+
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e1)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e1);
+ }
+ }
+ }
+ //System.out.println("WriteDebug:"+"Shutdown");
+ }
+
+ }
+
+ private class ReadWorker implements Runnable
+ {
+
+ public void run()
+ {
+ Thread.currentThread().setName(MultiThreadSocketIoProcessor.this.threadName + "Reader");
+
+ //System.out.println("ReadDebug:"+"Startup");
+ for (; ;)
+ {
+ try
+ {
+ int nKeys = selector.select(SELECTOR_TIMEOUT);
+
+ doAddNewReader();
+ doUpdateTrafficMask();
+
+ if (nKeys > 0)
+ {
+ //System.out.println("ReadDebug:"+nKeys + " keys from selector");
+
+ processRead(selector.selectedKeys());
+ }
+ else
+ {
+ //System.out.println("ReadDebug:"+"No keys from selector");
+ }
+
+
+ doRemove();
+ notifyReadIdleness();
+
+ if (selector.keys().isEmpty())
+ {
+
+ synchronized (readLock)
+ {
+ if (selector.keys().isEmpty() && newSessions.isEmpty())
+ {
+ readWorker = null;
+ try
+ {
+ selector.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ finally
+ {
+ selector = null;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ catch (Throwable t)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(t);
+
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e1)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e1);
+ }
+ }
+ }
+ //System.out.println("ReadDebug:"+"Shutdown");
+ }
+
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionConfigImpl.java b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionConfigImpl.java
new file mode 100644
index 0000000000..043d4800b6
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionConfigImpl.java
@@ -0,0 +1,240 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.mina.transport.socket.nio;
+
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IoConnectorConfig;
+import org.apache.mina.common.support.BaseIoSessionConfig;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.net.SocketException;
+
+/**
+ * An {@link IoConnectorConfig} for {@link SocketConnector}.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $
+ */
+public class MultiThreadSocketSessionConfigImpl extends org.apache.mina.transport.socket.nio.SocketSessionConfigImpl
+{
+ private static boolean SET_RECEIVE_BUFFER_SIZE_AVAILABLE = false;
+ private static boolean SET_SEND_BUFFER_SIZE_AVAILABLE = false;
+ private static boolean GET_TRAFFIC_CLASS_AVAILABLE = false;
+ private static boolean SET_TRAFFIC_CLASS_AVAILABLE = false;
+
+ private static boolean DEFAULT_REUSE_ADDRESS;
+ private static int DEFAULT_RECEIVE_BUFFER_SIZE;
+ private static int DEFAULT_SEND_BUFFER_SIZE;
+ private static int DEFAULT_TRAFFIC_CLASS;
+ private static boolean DEFAULT_KEEP_ALIVE;
+ private static boolean DEFAULT_OOB_INLINE;
+ private static int DEFAULT_SO_LINGER;
+ private static boolean DEFAULT_TCP_NO_DELAY;
+
+ static
+ {
+ initialize();
+ }
+
+ private static void initialize()
+ {
+ Socket socket = null;
+
+ socket = new Socket();
+
+ try
+ {
+ DEFAULT_REUSE_ADDRESS = socket.getReuseAddress();
+ DEFAULT_RECEIVE_BUFFER_SIZE = socket.getReceiveBufferSize();
+ DEFAULT_SEND_BUFFER_SIZE = socket.getSendBufferSize();
+ DEFAULT_KEEP_ALIVE = socket.getKeepAlive();
+ DEFAULT_OOB_INLINE = socket.getOOBInline();
+ DEFAULT_SO_LINGER = socket.getSoLinger();
+ DEFAULT_TCP_NO_DELAY = socket.getTcpNoDelay();
+
+ // Check if setReceiveBufferSize is supported.
+ try
+ {
+ socket.setReceiveBufferSize(DEFAULT_RECEIVE_BUFFER_SIZE);
+ SET_RECEIVE_BUFFER_SIZE_AVAILABLE = true;
+ }
+ catch( SocketException e )
+ {
+ SET_RECEIVE_BUFFER_SIZE_AVAILABLE = false;
+ }
+
+ // Check if setSendBufferSize is supported.
+ try
+ {
+ socket.setSendBufferSize(DEFAULT_SEND_BUFFER_SIZE);
+ SET_SEND_BUFFER_SIZE_AVAILABLE = true;
+ }
+ catch( SocketException e )
+ {
+ SET_SEND_BUFFER_SIZE_AVAILABLE = false;
+ }
+
+ // Check if getTrafficClass is supported.
+ try
+ {
+ DEFAULT_TRAFFIC_CLASS = socket.getTrafficClass();
+ GET_TRAFFIC_CLASS_AVAILABLE = true;
+ }
+ catch( SocketException e )
+ {
+ GET_TRAFFIC_CLASS_AVAILABLE = false;
+ DEFAULT_TRAFFIC_CLASS = 0;
+ }
+ }
+ catch( SocketException e )
+ {
+ throw new ExceptionInInitializerError(e);
+ }
+ finally
+ {
+ if( socket != null )
+ {
+ try
+ {
+ socket.close();
+ }
+ catch( IOException e )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ }
+ }
+ }
+
+ public static boolean isSetReceiveBufferSizeAvailable() {
+ return SET_RECEIVE_BUFFER_SIZE_AVAILABLE;
+ }
+
+ public static boolean isSetSendBufferSizeAvailable() {
+ return SET_SEND_BUFFER_SIZE_AVAILABLE;
+ }
+
+ public static boolean isGetTrafficClassAvailable() {
+ return GET_TRAFFIC_CLASS_AVAILABLE;
+ }
+
+ public static boolean isSetTrafficClassAvailable() {
+ return SET_TRAFFIC_CLASS_AVAILABLE;
+ }
+
+ private boolean reuseAddress = DEFAULT_REUSE_ADDRESS;
+ private int receiveBufferSize = DEFAULT_RECEIVE_BUFFER_SIZE;
+ private int sendBufferSize = DEFAULT_SEND_BUFFER_SIZE;
+ private int trafficClass = DEFAULT_TRAFFIC_CLASS;
+ private boolean keepAlive = DEFAULT_KEEP_ALIVE;
+ private boolean oobInline = DEFAULT_OOB_INLINE;
+ private int soLinger = DEFAULT_SO_LINGER;
+ private boolean tcpNoDelay = DEFAULT_TCP_NO_DELAY;
+
+ /**
+ * Creates a new instance.
+ */
+ MultiThreadSocketSessionConfigImpl()
+ {
+ }
+
+ public boolean isReuseAddress()
+ {
+ return reuseAddress;
+ }
+
+ public void setReuseAddress( boolean reuseAddress )
+ {
+ this.reuseAddress = reuseAddress;
+ }
+
+ public int getReceiveBufferSize()
+ {
+ return receiveBufferSize;
+ }
+
+ public void setReceiveBufferSize( int receiveBufferSize )
+ {
+ this.receiveBufferSize = receiveBufferSize;
+ }
+
+ public int getSendBufferSize()
+ {
+ return sendBufferSize;
+ }
+
+ public void setSendBufferSize( int sendBufferSize )
+ {
+ this.sendBufferSize = sendBufferSize;
+ }
+
+ public int getTrafficClass()
+ {
+ return trafficClass;
+ }
+
+ public void setTrafficClass( int trafficClass )
+ {
+ this.trafficClass = trafficClass;
+ }
+
+ public boolean isKeepAlive()
+ {
+ return keepAlive;
+ }
+
+ public void setKeepAlive( boolean keepAlive )
+ {
+ this.keepAlive = keepAlive;
+ }
+
+ public boolean isOobInline()
+ {
+ return oobInline;
+ }
+
+ public void setOobInline( boolean oobInline )
+ {
+ this.oobInline = oobInline;
+ }
+
+ public int getSoLinger()
+ {
+ return soLinger;
+ }
+
+ public void setSoLinger( int soLinger )
+ {
+ this.soLinger = soLinger;
+ }
+
+ public boolean isTcpNoDelay()
+ {
+ return tcpNoDelay;
+ }
+
+ public void setTcpNoDelay( boolean tcpNoDelay )
+ {
+ this.tcpNoDelay = tcpNoDelay;
+ }
+
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionImpl.java b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionImpl.java
new file mode 100644
index 0000000000..be4a2d289d
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionImpl.java
@@ -0,0 +1,488 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.mina.transport.socket.nio;
+
+import org.apache.mina.common.IoFilter.WriteRequest;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoHandler;
+import org.apache.mina.common.IoService;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.IoSessionConfig;
+import org.apache.mina.common.RuntimeIOException;
+import org.apache.mina.common.TransportType;
+import org.apache.mina.common.support.BaseIoSessionConfig;
+import org.apache.mina.common.support.IoServiceListenerSupport;
+import org.apache.mina.util.Queue;
+
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * An {@link IoSession} for socket transport (TCP/IP).
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $
+ */
+class MultiThreadSocketSessionImpl extends SocketSessionImpl
+{
+ private final IoService manager;
+ private final IoServiceConfig serviceConfig;
+ private final SocketSessionConfig config = new SessionConfigImpl();
+ private final MultiThreadSocketIoProcessor ioProcessor;
+ private final MultiThreadSocketFilterChain filterChain;
+ private final SocketChannel ch;
+ private final Queue writeRequestQueue;
+ private final IoHandler handler;
+ private final SocketAddress remoteAddress;
+ private final SocketAddress localAddress;
+ private final SocketAddress serviceAddress;
+ private final IoServiceListenerSupport serviceListeners;
+ private SelectionKey readKey, writeKey;
+ private int readBufferSize;
+ private CountDownLatch registeredReadyLatch = new CountDownLatch(2);
+ private AtomicBoolean created = new AtomicBoolean(false);
+
+ /**
+ * Creates a new instance.
+ */
+ MultiThreadSocketSessionImpl( IoService manager,
+ SocketIoProcessor ioProcessor,
+ IoServiceListenerSupport listeners,
+ IoServiceConfig serviceConfig,
+ SocketChannel ch,
+ IoHandler defaultHandler,
+ SocketAddress serviceAddress )
+ {
+ super(manager, ioProcessor, listeners, serviceConfig, ch,defaultHandler,serviceAddress);
+ this.manager = manager;
+ this.serviceListeners = listeners;
+ this.ioProcessor = (MultiThreadSocketIoProcessor) ioProcessor;
+ this.filterChain = new MultiThreadSocketFilterChain(this);
+ this.ch = ch;
+ this.writeRequestQueue = new Queue();
+ this.handler = defaultHandler;
+ this.remoteAddress = ch.socket().getRemoteSocketAddress();
+ this.localAddress = ch.socket().getLocalSocketAddress();
+ this.serviceAddress = serviceAddress;
+ this.serviceConfig = serviceConfig;
+
+ // Apply the initial session settings
+ IoSessionConfig sessionConfig = serviceConfig.getSessionConfig();
+ if( sessionConfig instanceof SocketSessionConfig )
+ {
+ SocketSessionConfig cfg = ( SocketSessionConfig ) sessionConfig;
+ this.config.setKeepAlive( cfg.isKeepAlive() );
+ this.config.setOobInline( cfg.isOobInline() );
+ this.config.setReceiveBufferSize( cfg.getReceiveBufferSize() );
+ this.readBufferSize = cfg.getReceiveBufferSize();
+ this.config.setReuseAddress( cfg.isReuseAddress() );
+ this.config.setSendBufferSize( cfg.getSendBufferSize() );
+ this.config.setSoLinger( cfg.getSoLinger() );
+ this.config.setTcpNoDelay( cfg.isTcpNoDelay() );
+
+ if( this.config.getTrafficClass() != cfg.getTrafficClass() )
+ {
+ this.config.setTrafficClass( cfg.getTrafficClass() );
+ }
+ }
+ }
+
+ void awaitRegistration() throws InterruptedException
+ {
+ registeredReadyLatch.countDown();
+
+ registeredReadyLatch.await();
+ }
+
+ boolean created() throws InterruptedException
+ {
+ return created.get();
+ }
+
+ void doneCreation()
+ {
+ created.getAndSet(true);
+ }
+
+ public IoService getService()
+ {
+ return manager;
+ }
+
+ public IoServiceConfig getServiceConfig()
+ {
+ return serviceConfig;
+ }
+
+ public IoSessionConfig getConfig()
+ {
+ return config;
+ }
+
+ SocketIoProcessor getIoProcessor()
+ {
+ return ioProcessor;
+ }
+
+ public IoFilterChain getFilterChain()
+ {
+ return filterChain;
+ }
+
+ SocketChannel getChannel()
+ {
+ return ch;
+ }
+
+ IoServiceListenerSupport getServiceListeners()
+ {
+ return serviceListeners;
+ }
+
+ SelectionKey getSelectionKey()
+ {
+ return readKey;
+ }
+
+ SelectionKey getReadSelectionKey()
+ {
+ return readKey;
+ }
+
+ SelectionKey getWriteSelectionKey()
+ {
+ return writeKey;
+ }
+
+ void setSelectionKey(SelectionKey key)
+ {
+ this.readKey = key;
+ }
+
+ void setWriteSelectionKey(SelectionKey key)
+ {
+ this.writeKey = key;
+ }
+
+ public IoHandler getHandler()
+ {
+ return handler;
+ }
+
+ protected void close0()
+ {
+ filterChain.fireFilterClose( this );
+ }
+
+ Queue getWriteRequestQueue()
+ {
+ return writeRequestQueue;
+ }
+
+ /**
+ @return int Number of write scheduled write requests
+ @deprecated
+ */
+ public int getScheduledWriteMessages()
+ {
+ return getScheduledWriteRequests();
+ }
+
+ public int getScheduledWriteRequests()
+ {
+ synchronized( writeRequestQueue )
+ {
+ return writeRequestQueue.size();
+ }
+ }
+
+ public int getScheduledWriteBytes()
+ {
+ synchronized( writeRequestQueue )
+ {
+ return writeRequestQueue.byteSize();
+ }
+ }
+
+ protected void write0( WriteRequest writeRequest )
+ {
+ filterChain.fireFilterWrite( this, writeRequest );
+ }
+
+ public TransportType getTransportType()
+ {
+ return TransportType.SOCKET;
+ }
+
+ public SocketAddress getRemoteAddress()
+ {
+ //This is what I had previously
+// return ch.socket().getRemoteSocketAddress();
+ return remoteAddress;
+ }
+
+ public SocketAddress getLocalAddress()
+ {
+ //This is what I had previously
+// return ch.socket().getLocalSocketAddress();
+ return localAddress;
+ }
+
+ public SocketAddress getServiceAddress()
+ {
+ return serviceAddress;
+ }
+
+ protected void updateTrafficMask()
+ {
+ this.ioProcessor.updateTrafficMask( this );
+ }
+
+ int getReadBufferSize()
+ {
+ return readBufferSize;
+ }
+
+ private class SessionConfigImpl extends BaseIoSessionConfig implements SocketSessionConfig
+ {
+ public boolean isKeepAlive()
+ {
+ try
+ {
+ return ch.socket().getKeepAlive();
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public void setKeepAlive( boolean on )
+ {
+ try
+ {
+ ch.socket().setKeepAlive( on );
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public boolean isOobInline()
+ {
+ try
+ {
+ return ch.socket().getOOBInline();
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public void setOobInline( boolean on )
+ {
+ try
+ {
+ ch.socket().setOOBInline( on );
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public boolean isReuseAddress()
+ {
+ try
+ {
+ return ch.socket().getReuseAddress();
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public void setReuseAddress( boolean on )
+ {
+ try
+ {
+ ch.socket().setReuseAddress( on );
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public int getSoLinger()
+ {
+ try
+ {
+ return ch.socket().getSoLinger();
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public void setSoLinger( int linger )
+ {
+ try
+ {
+ if( linger < 0 )
+ {
+ ch.socket().setSoLinger( false, 0 );
+ }
+ else
+ {
+ ch.socket().setSoLinger( true, linger );
+ }
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public boolean isTcpNoDelay()
+ {
+ try
+ {
+ return ch.socket().getTcpNoDelay();
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public void setTcpNoDelay( boolean on )
+ {
+ try
+ {
+ ch.socket().setTcpNoDelay( on );
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public int getTrafficClass()
+ {
+ if( SocketSessionConfigImpl.isGetTrafficClassAvailable() )
+ {
+ try
+ {
+ return ch.socket().getTrafficClass();
+ }
+ catch( SocketException e )
+ {
+ // Throw an exception only when setTrafficClass is also available.
+ if( SocketSessionConfigImpl.isSetTrafficClassAvailable() )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ public void setTrafficClass( int tc )
+ {
+ if( SocketSessionConfigImpl.isSetTrafficClassAvailable() )
+ {
+ try
+ {
+ ch.socket().setTrafficClass( tc );
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+ }
+
+ public int getSendBufferSize()
+ {
+ try
+ {
+ return ch.socket().getSendBufferSize();
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public void setSendBufferSize( int size )
+ {
+ if( SocketSessionConfigImpl.isSetSendBufferSizeAvailable() )
+ {
+ try
+ {
+ ch.socket().setSendBufferSize( size );
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+ }
+
+ public int getReceiveBufferSize()
+ {
+ try
+ {
+ return ch.socket().getReceiveBufferSize();
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public void setReceiveBufferSize( int size )
+ {
+ if( SocketSessionConfigImpl.isSetReceiveBufferSizeAvailable() )
+ {
+ try
+ {
+ ch.socket().setReceiveBufferSize( size );
+ MultiThreadSocketSessionImpl.this.readBufferSize = size;
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/transport/vmpipe/QpidVmPipeConnector.java b/qpid/java/common/src/main/java/org/apache/mina/transport/vmpipe/QpidVmPipeConnector.java
new file mode 100644
index 0000000000..a23e546af5
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/transport/vmpipe/QpidVmPipeConnector.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.mina.transport.vmpipe;
+
+import java.io.IOException;
+import java.net.SocketAddress;
+
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoHandler;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.common.IoSessionConfig;
+import org.apache.mina.common.support.AbstractIoFilterChain;
+import org.apache.mina.common.support.BaseIoConnector;
+import org.apache.mina.common.support.BaseIoConnectorConfig;
+import org.apache.mina.common.support.BaseIoSessionConfig;
+import org.apache.mina.common.support.DefaultConnectFuture;
+import org.apache.mina.transport.vmpipe.support.VmPipe;
+import org.apache.mina.transport.vmpipe.support.VmPipeIdleStatusChecker;
+import org.apache.mina.transport.vmpipe.support.VmPipeSessionImpl;
+import org.apache.mina.util.AnonymousSocketAddress;
+
+/**
+ * Connects to {@link IoHandler}s which is bound on the specified
+ * {@link VmPipeAddress}.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $
+ */
+public class QpidVmPipeConnector extends VmPipeConnector
+{
+ private static final IoSessionConfig CONFIG = new BaseIoSessionConfig() {};
+ private final IoServiceConfig defaultConfig = new BaseIoConnectorConfig()
+ {
+ public IoSessionConfig getSessionConfig()
+ {
+ return CONFIG;
+ }
+ };
+
+ /**
+ * Creates a new instance.
+ */
+ public QpidVmPipeConnector()
+ {
+ }
+
+ public ConnectFuture connect( SocketAddress address, IoHandler handler, IoServiceConfig config )
+ {
+ return connect( address, null, handler, config );
+ }
+
+ public ConnectFuture connect( SocketAddress address, SocketAddress localAddress, IoHandler handler, IoServiceConfig config )
+ {
+ if( address == null )
+ throw new NullPointerException( "address" );
+ if( handler == null )
+ throw new NullPointerException( "handler" );
+ if( ! ( address instanceof VmPipeAddress ) )
+ throw new IllegalArgumentException(
+ "address must be VmPipeAddress." );
+
+ if( config == null )
+ {
+ config = getDefaultConfig();
+ }
+
+ VmPipe entry = ( VmPipe ) VmPipeAcceptor.boundHandlers.get( address );
+ if( entry == null )
+ {
+ return DefaultConnectFuture.newFailedFuture(
+ new IOException( "Endpoint unavailable: " + address ) );
+ }
+
+ DefaultConnectFuture future = new DefaultConnectFuture();
+ VmPipeSessionImpl localSession =
+ new VmPipeSessionImpl(
+ this,
+ config,
+ getListeners(),
+ new Object(), // lock
+ new AnonymousSocketAddress(),
+ handler,
+ entry );
+
+ // initialize acceptor session
+ VmPipeSessionImpl remoteSession = localSession.getRemoteSession();
+ try
+ {
+ IoFilterChain filterChain = remoteSession.getFilterChain();
+ entry.getAcceptor().getFilterChainBuilder().buildFilterChain( filterChain );
+ entry.getConfig().getFilterChainBuilder().buildFilterChain( filterChain );
+ entry.getConfig().getThreadModel().buildFilterChain( filterChain );
+
+ // The following sentences don't throw any exceptions.
+ entry.getListeners().fireSessionCreated( remoteSession );
+ VmPipeIdleStatusChecker.getInstance().addSession( remoteSession );
+ }
+ catch( Throwable t )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( t );
+ remoteSession.close();
+ }
+
+
+ // initialize connector session
+ try
+ {
+ IoFilterChain filterChain = localSession.getFilterChain();
+ this.getFilterChainBuilder().buildFilterChain( filterChain );
+ config.getFilterChainBuilder().buildFilterChain( filterChain );
+ config.getThreadModel().buildFilterChain( filterChain );
+
+ // The following sentences don't throw any exceptions.
+ localSession.setAttribute( AbstractIoFilterChain.CONNECT_FUTURE, future );
+ getListeners().fireSessionCreated( localSession );
+ VmPipeIdleStatusChecker.getInstance().addSession( localSession);
+ }
+ catch( Throwable t )
+ {
+ future.setException( t );
+ }
+
+
+
+ return future;
+ }
+
+ public IoServiceConfig getDefaultConfig()
+ {
+ return defaultConfig;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java b/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java
index 2f6290b55a..ef9420ba87 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java
@@ -54,7 +54,6 @@ public class AMQChannelException extends AMQException
public AMQFrame getCloseFrame(int channel)
{
MethodRegistry reg = MethodRegistry.getMethodRegistry(new ProtocolVersion(major,minor));
- return new AMQFrame(channel, reg.createChannelCloseBody(getErrorCode() == null ? AMQConstant.INTERNAL_ERROR.getCode() : getErrorCode().getCode(), getMessageAsShortString(),_classId,_methodId));
+ return new AMQFrame(channel, reg.createChannelCloseBody(getErrorCode() == null ? AMQConstant.INTERNAL_ERROR.getCode() : getErrorCode().getCode(), new AMQShortString(getMessage()),_classId,_methodId));
}
-
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java b/qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java
index ca9c9f9dc4..8ef6facef1 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java
@@ -62,10 +62,9 @@ public class AMQConnectionException extends AMQException
MethodRegistry reg = MethodRegistry.getMethodRegistry(new ProtocolVersion(major,minor));
return new AMQFrame(0,
reg.createConnectionCloseBody(getErrorCode().getCode(),
- getMessageAsShortString(),
+ new AMQShortString(getMessage()),
_classId,
_methodId));
}
-
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java b/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java
index 86d439d269..b0c6fccc9e 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.protocol.AMQConstant;
/**
@@ -122,19 +121,4 @@ public class AMQException extends Exception
return newAMQE;
}
-
- /**
- * Truncates the exception message to 255 characters if its length exceeds 255.
- *
- * @return exception message
- */
- public AMQShortString getMessageAsShortString()
- {
- String message = getMessage();
- if (message != null && message.length() > AMQShortString.MAX_LENGTH)
- {
- message = message.substring(0, AMQShortString.MAX_LENGTH - 3) + "...";
- }
- return new AMQShortString(message);
- }
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/ToyBroker.java b/qpid/java/common/src/main/java/org/apache/qpid/ToyBroker.java
new file mode 100644
index 0000000000..5423bbb68f
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/ToyBroker.java
@@ -0,0 +1,208 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid;
+
+import org.apache.qpid.transport.*;
+import org.apache.qpid.transport.network.mina.MinaHandler;
+
+import static org.apache.qpid.transport.util.Functions.str;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.LinkedBlockingQueue;
+
+
+/**
+ * ToyBroker
+ *
+ * @author Rafael H. Schloming
+ */
+
+class ToyBroker extends SessionDelegate
+{
+
+ private ToyExchange exchange;
+ private Map<String,Consumer> consumers = new ConcurrentHashMap<String,Consumer>();
+
+ public ToyBroker(ToyExchange exchange)
+ {
+ this.exchange = exchange;
+ }
+
+ public void messageAcquire(Session context, MessageAcquire struct)
+ {
+ System.out.println("\n==================> messageAcquire " );
+ context.executionResult((int) struct.getId(), new Acquired(struct.getTransfers()));
+ }
+
+ @Override public void queueDeclare(Session ssn, QueueDeclare qd)
+ {
+ exchange.createQueue(qd.getQueue());
+ System.out.println("\n==================> declared queue: " + qd.getQueue() + "\n");
+ }
+
+ @Override public void exchangeBind(Session ssn, ExchangeBind qb)
+ {
+ exchange.bindQueue(qb.getExchange(), qb.getBindingKey(),qb.getQueue());
+ System.out.println("\n==================> bound queue: " + qb.getQueue() + " with binding key " + qb.getBindingKey() + "\n");
+ }
+
+ @Override public void queueQuery(Session ssn, QueueQuery qq)
+ {
+ QueueQueryResult result = new QueueQueryResult().queue(qq.getQueue());
+ ssn.executionResult((int) qq.getId(), result);
+ }
+
+ @Override public void messageSubscribe(Session ssn, MessageSubscribe ms)
+ {
+ Consumer c = new Consumer();
+ c._queueName = ms.getQueue();
+ consumers.put(ms.getDestination(),c);
+ System.out.println("\n==================> message subscribe : " + ms.getDestination() + " queue: " + ms.getQueue() + "\n");
+ }
+
+ @Override public void messageFlow(Session ssn,MessageFlow struct)
+ {
+ Consumer c = consumers.get(struct.getDestination());
+ c._credit = struct.getValue();
+ System.out.println("\n==================> message flow : " + struct.getDestination() + " credit: " + struct.getValue() + "\n");
+ }
+
+ @Override public void messageFlush(Session ssn,MessageFlush struct)
+ {
+ System.out.println("\n==================> message flush for consumer : " + struct.getDestination() + "\n");
+ checkAndSendMessagesToConsumer(ssn,struct.getDestination());
+ }
+
+ @Override public void messageTransfer(Session ssn, MessageTransfer xfr)
+ {
+ String dest = xfr.getDestination();
+ System.out.println("received transfer " + dest);
+ Header header = xfr.getHeader();
+ DeliveryProperties props = header.get(DeliveryProperties.class);
+ if (props != null)
+ {
+ System.out.println("received headers routing_key " + props.getRoutingKey());
+ }
+
+ MessageProperties mp = header.get(MessageProperties.class);
+ System.out.println("MP: " + mp);
+ if (mp != null)
+ {
+ System.out.println(mp.getApplicationHeaders());
+ }
+
+ if (exchange.route(dest,props == null ? null : props.getRoutingKey(),xfr))
+ {
+ System.out.println("queued " + xfr);
+ dispatchMessages(ssn);
+ }
+ else
+ {
+
+ if (props == null || !props.getDiscardUnroutable())
+ {
+ RangeSet ranges = new RangeSet();
+ ranges.add(xfr.getId());
+ ssn.messageReject(ranges, MessageRejectCode.UNROUTABLE,
+ "no such destination");
+ }
+ }
+ ssn.processed(xfr);
+ }
+
+ private void transferMessageToPeer(Session ssn,String dest, MessageTransfer m)
+ {
+ System.out.println("\n==================> Transfering message to: " +dest + "\n");
+ ssn.messageTransfer(m.getDestination(), MessageAcceptMode.EXPLICIT,
+ MessageAcquireMode.PRE_ACQUIRED,
+ m.getHeader(), m.getBody());
+ }
+
+ private void dispatchMessages(Session ssn)
+ {
+ for (String dest: consumers.keySet())
+ {
+ checkAndSendMessagesToConsumer(ssn,dest);
+ }
+ }
+
+ private void checkAndSendMessagesToConsumer(Session ssn,String dest)
+ {
+ Consumer c = consumers.get(dest);
+ LinkedBlockingQueue<MessageTransfer> queue = exchange.getQueue(c._queueName);
+ MessageTransfer m = queue.poll();
+ while (m != null && c._credit>0)
+ {
+ transferMessageToPeer(ssn,dest,m);
+ c._credit--;
+ m = queue.poll();
+ }
+ }
+
+ // ugly, but who cares :)
+ // assumes unit is always no of messages, not bytes
+ // assumes it's credit mode and not window
+ private static class Consumer
+ {
+ long _credit;
+ String _queueName;
+ }
+
+ private static final class ToyBrokerSession extends Session
+ {
+
+ public ToyBrokerSession(Connection connection, Binary name, long expiry, ToyExchange exchange)
+ {
+ super(connection, new ToyBroker(exchange), name, expiry);
+ }
+ }
+
+ public static final void main(String[] args) throws IOException
+ {
+ final ToyExchange exchange = new ToyExchange();
+ ConnectionDelegate delegate = new ServerDelegate()
+ {
+ @Override
+ public void init(Connection conn, ProtocolHeader hdr)
+ {
+ conn.setSessionFactory(new Connection.SessionFactory()
+ {
+ public Session newSession(Connection conn, Binary name, long expiry)
+ {
+ return new ToyBrokerSession(conn, name, expiry, exchange);
+ }
+ });
+
+ super.init(conn, hdr); //To change body of overridden methods use File | Settings | File Templates.
+ }
+
+ };
+
+ MinaHandler.accept("0.0.0.0", 5672, delegate);
+ }
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/ToyClient.java b/qpid/java/common/src/main/java/org/apache/qpid/ToyClient.java
new file mode 100644
index 0000000000..5b2db10613
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/ToyClient.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;
+
+import java.nio.*;
+import java.util.*;
+
+import org.apache.qpid.transport.*;
+import org.apache.qpid.transport.network.mina.MinaHandler;
+
+
+/**
+ * ToyClient
+ *
+ * @author Rafael H. Schloming
+ */
+
+class ToyClient implements SessionListener
+{
+ public void opened(Session ssn) {}
+
+ public void resumed(Session ssn) {}
+
+ public void exception(Session ssn, SessionException exc)
+ {
+ exc.printStackTrace();
+ }
+
+ public void message(Session ssn, MessageTransfer xfr)
+ {
+ System.out.println("msg: " + xfr);
+ }
+
+ public void closed(Session ssn) {}
+
+ public static final void main(String[] args)
+ {
+ Connection conn = new Connection();
+ conn.connect("0.0.0.0", 5672, null, "guest", "guest", false);
+ Session ssn = conn.createSession();
+ ssn.setSessionListener(new ToyClient());
+
+ ssn.queueDeclare("asdf", null, null);
+ ssn.sync();
+
+ Map<String,Object> nested = new LinkedHashMap<String,Object>();
+ nested.put("list", Arrays.asList("one", "two", "three"));
+ Map<String,Object> map = new LinkedHashMap<String,Object>();
+
+ map.put("str", "this is a string");
+
+ map.put("+int", 3);
+ map.put("-int", -3);
+ map.put("maxint", Integer.MAX_VALUE);
+ map.put("minint", Integer.MIN_VALUE);
+
+ map.put("+short", (short) 1);
+ map.put("-short", (short) -1);
+ map.put("maxshort", (short) Short.MAX_VALUE);
+ map.put("minshort", (short) Short.MIN_VALUE);
+
+ map.put("float", (float) 3.3);
+ map.put("double", 4.9);
+ map.put("char", 'c');
+
+ map.put("table", nested);
+ map.put("list", Arrays.asList(1, 2, 3));
+ map.put("binary", new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
+
+ ssn.messageTransfer("asdf", MessageAcceptMode.EXPLICIT,
+ MessageAcquireMode.PRE_ACQUIRED,
+ new Header(new DeliveryProperties(),
+ new MessageProperties()
+ .setApplicationHeaders(map)),
+ "this is the data");
+
+ ssn.messageTransfer("fdsa", MessageAcceptMode.EXPLICIT,
+ MessageAcquireMode.PRE_ACQUIRED,
+ null,
+ "this should be rejected");
+ ssn.sync();
+
+ Future<QueueQueryResult> future = ssn.queueQuery("asdf");
+ System.out.println(future.get().getQueue());
+ ssn.sync();
+ ssn.close();
+ conn.close();
+ }
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/ToyExchange.java b/qpid/java/common/src/main/java/org/apache/qpid/ToyExchange.java
new file mode 100644
index 0000000000..da6aed9629
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/ToyExchange.java
@@ -0,0 +1,154 @@
+package org.apache.qpid;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.qpid.transport.MessageTransfer;
+
+
+public class ToyExchange
+{
+ final static String DIRECT = "amq.direct";
+ final static String TOPIC = "amq.topic";
+
+ private Map<String,List<LinkedBlockingQueue<MessageTransfer>>> directEx = new HashMap<String,List<LinkedBlockingQueue<MessageTransfer>>>();
+ private Map<String,List<LinkedBlockingQueue<MessageTransfer>>> topicEx = new HashMap<String,List<LinkedBlockingQueue<MessageTransfer>>>();
+ private Map<String,LinkedBlockingQueue<MessageTransfer>> queues = new HashMap<String,LinkedBlockingQueue<MessageTransfer>>();
+
+ public void createQueue(String name)
+ {
+ queues.put(name, new LinkedBlockingQueue<MessageTransfer>());
+ }
+
+ public LinkedBlockingQueue<MessageTransfer> getQueue(String name)
+ {
+ return queues.get(name);
+ }
+
+ public void bindQueue(String type,String binding,String queueName)
+ {
+ LinkedBlockingQueue<MessageTransfer> queue = queues.get(queueName);
+ binding = normalizeKey(binding);
+ if(DIRECT.equals(type))
+ {
+
+ if (directEx.containsKey(binding))
+ {
+ List<LinkedBlockingQueue<MessageTransfer>> list = directEx.get(binding);
+ list.add(queue);
+ }
+ else
+ {
+ List<LinkedBlockingQueue<MessageTransfer>> list = new LinkedList<LinkedBlockingQueue<MessageTransfer>>();
+ list.add(queue);
+ directEx.put(binding,list);
+ }
+ }
+ else
+ {
+ if (topicEx.containsKey(binding))
+ {
+ List<LinkedBlockingQueue<MessageTransfer>> list = topicEx.get(binding);
+ list.add(queue);
+ }
+ else
+ {
+ List<LinkedBlockingQueue<MessageTransfer>> list = new LinkedList<LinkedBlockingQueue<MessageTransfer>>();
+ list.add(queue);
+ topicEx.put(binding,list);
+ }
+ }
+ }
+
+ public boolean route(String dest, String routingKey, MessageTransfer msg)
+ {
+ List<LinkedBlockingQueue<MessageTransfer>> queues;
+ if(DIRECT.equals(dest))
+ {
+ queues = directEx.get(routingKey);
+ }
+ else
+ {
+ queues = matchWildCard(routingKey);
+ }
+ if(queues != null && queues.size()>0)
+ {
+ System.out.println("Message stored in " + queues.size() + " queues");
+ storeMessage(msg,queues);
+ return true;
+ }
+ else
+ {
+ System.out.println("Message unroutable " + msg);
+ return false;
+ }
+ }
+
+ private String normalizeKey(String routingKey)
+ {
+ if(routingKey.indexOf(".*")>1)
+ {
+ return routingKey.substring(0,routingKey.indexOf(".*"));
+ }
+ else
+ {
+ return routingKey;
+ }
+ }
+
+ private List<LinkedBlockingQueue<MessageTransfer>> matchWildCard(String routingKey)
+ {
+ List<LinkedBlockingQueue<MessageTransfer>> selected = new ArrayList<LinkedBlockingQueue<MessageTransfer>>();
+
+ for(String key: topicEx.keySet())
+ {
+ Pattern p = Pattern.compile(key);
+ Matcher m = p.matcher(routingKey);
+ if (m.find())
+ {
+ for(LinkedBlockingQueue<MessageTransfer> queue : topicEx.get(key))
+ {
+ selected.add(queue);
+ }
+ }
+ }
+
+ return selected;
+ }
+
+ private void storeMessage(MessageTransfer msg,List<LinkedBlockingQueue<MessageTransfer>> selected)
+ {
+ for(LinkedBlockingQueue<MessageTransfer> queue : selected)
+ {
+ queue.offer(msg);
+ }
+ }
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java b/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
index 36f9a1ae2d..0dd21238a7 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
@@ -23,7 +23,7 @@ package org.apache.qpid.configuration;
*/
public class ClientProperties
{
-
+
/**
* Currently with Qpid it is not possible to change the client ID.
* If one is not specified upon connection construction, an id is generated automatically.
@@ -68,40 +68,67 @@ public class ClientProperties
* by the broker in TuneOK it will be used as the heartbeat interval.
* If not a warning will be printed and the max value specified for
* heartbeat in TuneOK will be used
- *
+ *
* The default idle timeout is set to 120 secs
*/
public static final String IDLE_TIMEOUT_PROP_NAME = "idle_timeout";
public static final long DEFAULT_IDLE_TIMEOUT = 120000;
-
+
public static final String HEARTBEAT = "qpid.heartbeat";
public static final int HEARTBEAT_DEFAULT = 120;
-
+
/**
* This value will be used to determine the default destination syntax type.
* Currently the two types are Binding URL (java only) and the Addressing format (used by
- * all clients).
+ * all clients).
*/
public static final String DEST_SYNTAX = "qpid.dest_syntax";
-
+
public static final String USE_LEGACY_MAP_MESSAGE_FORMAT = "qpid.use_legacy_map_message";
- public static final String AMQP_VERSION = "qpid.amqp.version";
+ /**
+ * ==========================================================
+ * Those properties are used when the io size should be bounded
+ * ==========================================================
+ */
- public static final String QPID_VERIFY_CLIENT_ID = "qpid.verify_client_id";
+ /**
+ * When set to true the io layer throttle down producers and consumers
+ * when written or read messages are accumulating and exceeding a certain size.
+ * This is especially useful when a the producer rate is greater than the network
+ * speed.
+ * type: boolean
+ */
+ public static final String PROTECTIO_PROP_NAME = "protectio";
- private static ClientProperties _instance = new ClientProperties();
+ //=== The following properties are only used when the previous one is true.
+ /**
+ * Max size of read messages that can be stored within the MINA layer
+ * type: int
+ */
+ public static final String READ_BUFFER_LIMIT_PROP_NAME = "qpid.read.buffer.limit";
+ public static final String READ_BUFFER_LIMIT_DEFAULT = "262144";
+ /**
+ * Max size of written messages that can be stored within the MINA layer
+ * type: int
+ */
+ public static final String WRITE_BUFFER_LIMIT_PROP_NAME = "qpid.read.buffer.limit";
+ public static final String WRITE_BUFFER_LIMIT_DEFAULT = "262144";
+ public static final String AMQP_VERSION = "qpid.amqp.version";
+
+ private static ClientProperties _instance = new ClientProperties();
+
/*
- public static final QpidProperty<Boolean> IGNORE_SET_CLIENTID_PROP_NAME =
+ public static final QpidProperty<Boolean> IGNORE_SET_CLIENTID_PROP_NAME =
QpidProperty.booleanProperty(false,"qpid.ignore_set_client_id","ignore_setclientID");
-
+
public static final QpidProperty<Boolean> SYNC_PERSISTENT_PROP_NAME =
QpidProperty.booleanProperty(false,"qpid.sync_persistence","sync_persistence");
-
-
+
+
public static final QpidProperty<Integer> MAX_PREFETCH_PROP_NAME =
QpidProperty.intProperty(500,"qpid.max_prefetch","max_prefetch"); */
-
-
+
+
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
index 2b9e2ffaba..39a9beb9e8 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
@@ -37,10 +37,6 @@ import java.lang.ref.WeakReference;
*/
public final class AMQShortString implements CharSequence, Comparable<AMQShortString>
{
- /**
- * The maximum number of octets in AMQ short string as defined in AMQP specification
- */
- public static final int MAX_LENGTH = 255;
private static final byte MINUS = (byte)'-';
private static final byte ZERO = (byte) '0';
@@ -122,19 +118,22 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
public AMQShortString(byte[] data)
{
- if (data == null)
- {
- throw new NullPointerException("Cannot create AMQShortString with null data[]");
- }
- if (data.length > MAX_LENGTH)
- {
- throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
- }
+
_data = data.clone();
_length = data.length;
_offset = 0;
}
+ public AMQShortString(byte[] data, int pos)
+ {
+ final int size = data[pos++];
+ final byte[] dataCopy = new byte[size];
+ System.arraycopy(data,pos,dataCopy,0,size);
+ _length = size;
+ _data = dataCopy;
+ _offset = 0;
+ }
+
public AMQShortString(String data)
{
this((data == null) ? EMPTY_CHAR_ARRAY : data.toCharArray());
@@ -147,12 +146,7 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
{
throw new NullPointerException("Cannot create AMQShortString with null char[]");
}
- // the current implementation of 0.8/0.9.x short string encoding
- // supports only ASCII characters
- if (data.length> MAX_LENGTH)
- {
- throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
- }
+
final int length = data.length;
final byte[] stringBytes = new byte[length];
int hash = 0;
@@ -171,17 +165,6 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
public AMQShortString(CharSequence charSequence)
{
- if (charSequence == null)
- {
- // it should be possible to create short string for null data
- charSequence = "";
- }
- // the current implementation of 0.8/0.9.x short string encoding
- // supports only ASCII characters
- if (charSequence.length() > MAX_LENGTH)
- {
- throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
- }
final int length = charSequence.length();
final byte[] stringBytes = new byte[length];
int hash = 0;
@@ -201,10 +184,6 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
private AMQShortString(ByteBuffer data, final int length)
{
- if (length > MAX_LENGTH)
- {
- throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
- }
if(data.isDirect() || data.isReadOnly())
{
byte[] dataBytes = new byte[length];
@@ -226,17 +205,8 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
private AMQShortString(final byte[] data, final int from, final int to)
{
- if (data == null)
- {
- throw new NullPointerException("Cannot create AMQShortString with null data[]");
- }
- int length = to - from;
- if (length > MAX_LENGTH)
- {
- throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
- }
_offset = from;
- _length = length;
+ _length = to - from;
_data = data;
}
@@ -275,6 +245,29 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
return new CharSubSequence(start, end);
}
+ public int writeToByteArray(byte[] encoding, int pos)
+ {
+ final int size = length();
+ encoding[pos++] = (byte) size;
+ System.arraycopy(_data,_offset,encoding,pos,size);
+ return pos+size;
+ }
+
+ public static AMQShortString readFromByteArray(byte[] byteEncodedDestination, int pos)
+ {
+
+
+ final AMQShortString shortString = new AMQShortString(byteEncodedDestination, pos);
+ if(shortString.length() == 0)
+ {
+ return null;
+ }
+ else
+ {
+ return shortString;
+ }
+ }
+
public static AMQShortString readFromBuffer(ByteBuffer buffer)
{
final short length = buffer.getUnsigned();
@@ -697,10 +690,6 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
size += term.length();
}
- if (size > MAX_LENGTH)
- {
- throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
- }
byte[] data = new byte[size];
int pos = 0;
final byte[] delimData = delim._data;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java
index 30db3b8be7..83e5a7e341 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java
@@ -36,7 +36,7 @@ public class ContentHeaderBody implements AMQBody
public long bodySize;
/** must never be null */
- private ContentHeaderProperties properties;
+ public ContentHeaderProperties properties;
public ContentHeaderBody()
{
@@ -128,14 +128,4 @@ public class ContentHeaderBody implements AMQBody
{
return new AMQFrame(channelId, body);
}
-
- public ContentHeaderProperties getProperties()
- {
- return properties;
- }
-
- public void setProperties(ContentHeaderProperties props)
- {
- properties = props;
- }
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java b/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java
index 48a3df734a..31953ea6ab 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java
@@ -22,6 +22,8 @@ package org.apache.qpid.protocol;
import java.net.SocketAddress;
+import org.apache.qpid.framing.AMQDataBlock;
+import org.apache.qpid.transport.NetworkDriver;
import org.apache.qpid.transport.Receiver;
/**
@@ -30,6 +32,9 @@ import org.apache.qpid.transport.Receiver;
*/
public interface ProtocolEngine extends Receiver<java.nio.ByteBuffer>
{
+ // Sets the network driver providing data for this ProtocolEngine
+ void setNetworkDriver (NetworkDriver driver);
+
// Returns the remote address of the NetworkDriver
SocketAddress getRemoteAddress();
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngineFactory.java b/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngineFactory.java
index 4e40b78440..9df84eef90 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngineFactory.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngineFactory.java
@@ -20,12 +20,12 @@
*/
package org.apache.qpid.protocol;
-import org.apache.qpid.transport.network.NetworkConnection;
+import org.apache.qpid.transport.NetworkDriver;
public interface ProtocolEngineFactory
{
// Returns a new instance of a ProtocolEngine
- ProtocolEngine newProtocolEngine(NetworkConnection network);
+ ProtocolEngine newProtocolEngine(NetworkDriver networkDriver);
} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/thread/QpidThreadExecutor.java b/qpid/java/common/src/main/java/org/apache/qpid/thread/QpidThreadExecutor.java
index 30010a2d89..38f60c04fe 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/thread/QpidThreadExecutor.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/thread/QpidThreadExecutor.java
@@ -23,7 +23,7 @@ package org.apache.qpid.thread;
import org.apache.qpid.thread.Threading;
-import java.util.concurrent.Executor;
+import edu.emory.mathcs.backport.java.util.concurrent.Executor;
public class QpidThreadExecutor implements Executor
{
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/ClientDelegate.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/ClientDelegate.java
index c8b7ad2a5e..0d9f8c0b28 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/ClientDelegate.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/ClientDelegate.java
@@ -247,7 +247,7 @@ public class ClientDelegate extends ConnectionDelegate
int i = heartbeat;
if (i == 0)
{
- log.info("Idle timeout is 0 sec. Heartbeats are disabled.");
+ log.warn("Idle timeout is zero. Heartbeats are disabled");
return 0; // heartbeats are disabled.
}
else if (i >= min && i <= max)
@@ -256,8 +256,8 @@ public class ClientDelegate extends ConnectionDelegate
}
else
{
- log.info("The broker does not support the configured connection idle timeout of %s sec," +
- " using the brokers max supported value of %s sec instead.", i,max);
+ log.warn("Ignoring the idle timeout %s set by the connection," +
+ " using the brokers max value %s", i,max);
return max;
}
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java
index 7d17397b2d..e5e10c0e07 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java
@@ -25,10 +25,9 @@ import static org.apache.qpid.transport.Connection.State.CLOSING;
import static org.apache.qpid.transport.Connection.State.NEW;
import static org.apache.qpid.transport.Connection.State.OPEN;
import static org.apache.qpid.transport.Connection.State.OPENING;
+import static org.apache.qpid.transport.Connection.State.RESUMING;
-import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -40,13 +39,6 @@ import java.util.concurrent.atomic.AtomicLong;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslServer;
-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.security.SecurityLayer;
import org.apache.qpid.transport.util.Logger;
import org.apache.qpid.transport.util.Waiter;
@@ -120,6 +112,7 @@ public class Connection extends ConnectionInvoker
private SaslServer saslServer;
private SaslClient saslClient;
private int idleTimeout = 0;
+ private String _authorizationID;
private Map<String,Object> _serverProperties;
private String userID;
private ConnectionSettings conSettings;
@@ -241,14 +234,13 @@ public class Connection extends ConnectionInvoker
state = OPENING;
userID = settings.getUsername();
delegate = new ClientDelegate(settings);
-
- securityLayer = new SecurityLayer(this);
-
- OutgoingNetworkTransport transport = Transport.getOutgoingTransportInstance(ProtocolVersion.v0_10);
- Receiver<ByteBuffer> receiver = securityLayer.receiver(new InputHandler(new Assembler(this)));
- NetworkConnection network = transport.connect(settings, receiver, null);
- sender = new Disassembler(securityLayer.sender(network.getSender()), settings.getMaxFrameSize());
-
+
+ TransportBuilder transport = new TransportBuilder();
+ transport.init(this);
+ this.sender = transport.buildSenderPipe();
+ transport.buildReceiverPipe(this);
+ this.securityLayer = transport.getSecurityLayer();
+
send(new ProtocolHeader(1, 0, 10));
Waiter w = new Waiter(lock, timeout);
@@ -474,12 +466,11 @@ public class Connection extends ConnectionInvoker
{
synchronized (lock)
{
- List <Binary> transactedSessions = new ArrayList();
for (Session ssn : sessions.values())
{
if (ssn.isTransacted())
- {
- transactedSessions.add(ssn.getName());
+ {
+ removeSession(ssn);
ssn.setState(Session.State.CLOSED);
}
else
@@ -489,11 +480,6 @@ public class Connection extends ConnectionInvoker
ssn.resume();
}
}
-
- for (Binary ssn_name : transactedSessions)
- {
- sessions.remove(ssn_name);
- }
setState(OPEN);
}
}
@@ -659,6 +645,16 @@ public class Connection extends ConnectionInvoker
return idleTimeout;
}
+ public void setAuthorizationID(String authorizationID)
+ {
+ _authorizationID = authorizationID;
+ }
+
+ public String getAuthorizationID()
+ {
+ return _authorizationID;
+ }
+
public String getUserID()
{
return userID;
@@ -699,8 +695,4 @@ public class Connection extends ConnectionInvoker
return connectionLost.get();
}
- protected Collection<Session> getChannels()
- {
- return channels.values();
- }
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionDelegate.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionDelegate.java
index f183c1e241..88dd2d6afa 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionDelegate.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionDelegate.java
@@ -95,7 +95,6 @@ public abstract class ConnectionDelegate
Session ssn = conn.getSession(dtc.getChannel());
if (ssn != null)
{
- ssn.setDetachCode(dtc.getCode());
conn.unmap(ssn);
ssn.closed();
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionSettings.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionSettings.java
index 2074c77a5b..08678b213b 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionSettings.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionSettings.java
@@ -30,8 +30,6 @@ import java.util.Map;
*/
public class ConnectionSettings
{
- public static final String WILDCARD_ADDRESS = "*";
-
String protocol = "tcp";
String host = "localhost";
String vhost;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriver.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriver.java
new file mode 100644
index 0000000000..86af97bf7e
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriver.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.transport;
+
+import java.net.BindException;
+import java.net.InetAddress;
+import java.net.SocketAddress;
+
+import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.protocol.ProtocolEngineFactory;
+import org.apache.qpid.ssl.SSLContextFactory;
+
+public interface NetworkDriver extends Sender<java.nio.ByteBuffer>
+{
+ // Creates a NetworkDriver which attempts to connect to destination on port and attaches the ProtocolEngine to
+ // it using the SSLContextFactory if provided
+ void open(int port, InetAddress destination, ProtocolEngine engine,
+ NetworkDriverConfiguration config, SSLContextFactory sslFactory)
+ throws OpenException;
+
+ // listens for incoming connections on the specified ports and address and creates a new NetworkDriver which
+ // processes incoming connections with ProtocolEngines and SSLEngines created from the factories
+ // (in the case of an SSLContextFactory, if provided)
+ void bind (int port, InetAddress[] addresses, ProtocolEngineFactory protocolFactory,
+ NetworkDriverConfiguration config, SSLContextFactory sslFactory) throws BindException;
+
+ // Returns the remote address of the underlying socket
+ SocketAddress getRemoteAddress();
+
+ // Returns the local address of the underlying socket
+ SocketAddress getLocalAddress();
+
+ /**
+ * The length of time after which the ProtocolEngines readIdle() method should be called if no data has been
+ * read in seconds
+ */
+ void setMaxReadIdle(int idleTime);
+
+ /**
+ * The length of time after which the ProtocolEngines writeIdle() method should be called if no data has been
+ * written in seconds
+ */
+ void setMaxWriteIdle(int idleTime);
+
+} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriverConfiguration.java
index 8d3f7a779a..c38afe5dd5 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriverConfiguration.java
@@ -25,22 +25,20 @@ package org.apache.qpid.transport;
* buffer sizes and set particular options on the socket. NetworkDrivers should honour the values returned
* from here if the underlying implementation supports them.
*/
-public interface NetworkTransportConfiguration
+public interface NetworkDriverConfiguration
{
// Taken from Socket
+ Boolean getKeepAlive();
+ Boolean getOOBInline();
+ Boolean getReuseAddress();
+ Integer getSoLinger(); // null means off
+ Integer getSoTimeout();
Boolean getTcpNoDelay();
+ Integer getTrafficClass();
// The amount of memory in bytes to allocate to the incoming buffer
Integer getReceiveBufferSize();
// The amount of memory in bytes to allocate to the outgoing buffer
- Integer getSendBufferSize();
-
- Integer getPort();
-
- String getHost();
-
- String getTransport();
-
- Integer getConnectorProcessors();
-}
+ Integer getSendBufferSize();
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java
index 11af86f412..f21df251da 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java
@@ -75,7 +75,10 @@ public class ServerDelegate extends ConnectionDelegate
if (mechanism == null || mechanism.length() == 0)
{
- tuneAuthorizedConnection(conn);
+ conn.connectionTune
+ (getChannelMax(),
+ org.apache.qpid.transport.network.ConnectionBinding.MAX_FRAME_SIZE,
+ 0, getHeartbeatMax());
return;
}
@@ -94,7 +97,8 @@ public class ServerDelegate extends ConnectionDelegate
}
catch (SaslException e)
{
- connectionAuthFailed(conn, e);
+ conn.exception(e);
+ conn.connectionClose(ConnectionCloseCode.CONNECTION_FORCED, e.getMessage());
}
}
@@ -105,52 +109,33 @@ public class ServerDelegate extends ConnectionDelegate
return ss;
}
- protected void secure(final SaslServer ss, final Connection conn, final byte[] response)
+ private void secure(Connection conn, byte[] response)
{
+ SaslServer ss = conn.getSaslServer();
try
{
byte[] challenge = ss.evaluateResponse(response);
if (ss.isComplete())
{
ss.dispose();
- tuneAuthorizedConnection(conn);
+ conn.connectionTune
+ (getChannelMax(),
+ org.apache.qpid.transport.network.ConnectionBinding.MAX_FRAME_SIZE,
+ 0, getHeartbeatMax());
+ conn.setAuthorizationID(ss.getAuthorizationID());
}
else
{
- connectionAuthContinue(conn, challenge);
+ conn.connectionSecure(challenge);
}
}
catch (SaslException e)
{
- connectionAuthFailed(conn, e);
+ conn.exception(e);
+ conn.connectionClose(ConnectionCloseCode.CONNECTION_FORCED, e.getMessage());
}
}
- protected void connectionAuthFailed(final Connection conn, Exception e)
- {
- conn.exception(e);
- conn.connectionClose(ConnectionCloseCode.CONNECTION_FORCED, e.getMessage());
- }
-
- protected void connectionAuthContinue(final Connection conn, byte[] challenge)
- {
- conn.connectionSecure(challenge);
- }
-
- protected void tuneAuthorizedConnection(final Connection conn)
- {
- conn.connectionTune
- (getChannelMax(),
- org.apache.qpid.transport.network.ConnectionBinding.MAX_FRAME_SIZE,
- 0, getHeartbeatMax());
- }
-
- protected void secure(final Connection conn, final byte[] response)
- {
- final SaslServer ss = conn.getSaslServer();
- secure(ss, conn, response);
- }
-
protected int getHeartbeatMax()
{
return 0xFFFF;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java
index e0c6cb29d3..214d4534c1 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java
@@ -42,10 +42,7 @@ import static org.apache.qpid.util.Serial.max;
import static org.apache.qpid.util.Strings.toUTF8;
import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
@@ -120,9 +117,7 @@ public class Session extends SessionInvoker
private Thread resumer = null;
private boolean transacted = false;
- private SessionDetachCode detachCode;
- private final Object stateLock = new Object();
-
+
protected Session(Connection connection, Binary name, long expiry)
{
this(connection, new SessionDelegate(), name, expiry);
@@ -267,32 +262,7 @@ public class Session extends SessionInvoker
}
else if (m instanceof MessageTransfer)
{
- MessageTransfer xfr = (MessageTransfer)m;
-
- if (xfr.getHeader() != null)
- {
- if (xfr.getHeader().get(DeliveryProperties.class) != null)
- {
- xfr.getHeader().get(DeliveryProperties.class).setRedelivered(true);
- }
- else
- {
- Struct[] structs = xfr.getHeader().getStructs();
- DeliveryProperties deliveryProps = new DeliveryProperties();
- deliveryProps.setRedelivered(true);
-
- List<Struct> list = Arrays.asList(structs);
- list.add(deliveryProps);
- xfr.setHeader(new Header(list));
- }
-
- }
- else
- {
- DeliveryProperties deliveryProps = new DeliveryProperties();
- deliveryProps.setRedelivered(true);
- xfr.setHeader(new Header(deliveryProps));
- }
+ ((MessageTransfer)m).getHeader().get(DeliveryProperties.class).setRedelivered(true);
}
sessionCommandPoint(m.getId(), 0);
send(m);
@@ -452,10 +422,7 @@ public class Session extends SessionInvoker
{
return;
}
- if (copy.size() > 0)
- {
- sessionCompleted(copy, options);
- }
+ sessionCompleted(copy, options);
}
}
@@ -694,12 +661,7 @@ public class Session extends SessionInvoker
{
sessionCommandPoint(0, 0);
}
-
- boolean replayTransfer = !closing && !transacted &&
- m instanceof MessageTransfer &&
- ! m.isUnreliable();
-
- if ((replayTransfer) || m.hasCompletionListener())
+ if ((!closing && !transacted && m instanceof MessageTransfer) || m.hasCompletionListener())
{
commands[mod(next, commands.length)] = m;
commandBytes += m.getBodySize();
@@ -1033,8 +995,7 @@ public class Session extends SessionInvoker
if(state == CLOSED)
{
- connection.removeSession(this);
- listener.closed(this);
+ connection.removeSession(this);
}
}
@@ -1047,54 +1008,13 @@ public class Session extends SessionInvoker
{
return String.format("ssn:%s", name);
}
-
+
public void setTransacted(boolean b) {
this.transacted = b;
}
-
+
public boolean isTransacted(){
return transacted;
}
-
- public void setDetachCode(SessionDetachCode dtc)
- {
- this.detachCode = dtc;
- }
-
- public SessionDetachCode getDetachCode()
- {
- return this.detachCode;
- }
-
- public void awaitOpen()
- {
- switch (state)
- {
- case NEW:
- synchronized(stateLock)
- {
- Waiter w = new Waiter(stateLock, timeout);
- while (w.hasTime() && state == NEW)
- {
- w.await();
- }
- }
-
- if (state != OPEN)
- {
- throw new SessionException("Timed out waiting for Session to open");
- }
- case DETACHED:
- case CLOSING:
- case CLOSED:
- throw new SessionException("Session closed");
- default :
- break;
- }
- }
-
- public Object getStateLock()
- {
- return stateLock;
- }
+
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java
index 3341149e5f..5d8e4d5565 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java
@@ -76,10 +76,6 @@ public class SessionDelegate
@Override public void sessionAttached(Session ssn, SessionAttached atc)
{
ssn.setState(Session.State.OPEN);
- synchronized (ssn.getStateLock())
- {
- ssn.getStateLock().notifyAll();
- }
}
@Override public void sessionTimeout(Session ssn, SessionTimeout t)
@@ -206,19 +202,11 @@ public class SessionDelegate
public void closed(Session session)
{
- log.debug("CLOSED: [%s]", session);
- synchronized (session.getStateLock())
- {
- session.getStateLock().notifyAll();
- }
+ log.warn("CLOSED: [%s]", session);
}
public void detached(Session session)
{
- log.debug("DETACHED: [%s]", session);
- synchronized (session.getStateLock())
- {
- session.getStateLock().notifyAll();
- }
+ log.warn("DETACHED: [%s]", session);
}
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/SocketConnectorFactory.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/SocketConnectorFactory.java
deleted file mode 100644
index 2c7652abeb..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/SocketConnectorFactory.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.apache.qpid.transport;
-
-import org.apache.mina.common.IoConnector;
-
-public interface SocketConnectorFactory
-{
- IoConnector newConnector();
-} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/TransportBuilder.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/TransportBuilder.java
new file mode 100644
index 0000000000..c08909c6e4
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/TransportBuilder.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.transport;
+
+import java.nio.ByteBuffer;
+
+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.NetworkTransport;
+import org.apache.qpid.transport.network.Transport;
+import org.apache.qpid.transport.network.security.SecurityLayer;
+
+public class TransportBuilder
+{
+ private Connection con;
+ private ConnectionSettings settings;
+ private NetworkTransport transport;
+ private SecurityLayer securityLayer = new SecurityLayer();
+
+ public void init(Connection con) throws TransportException
+ {
+ this.con = con;
+ this.settings = con.getConnectionSettings();
+ transport = Transport.getTransport();
+ transport.init(settings);
+ securityLayer.init(con);
+ }
+
+ public Sender<ProtocolEvent> buildSenderPipe()
+ {
+ ConnectionSettings settings = con.getConnectionSettings();
+
+ // Io layer
+ Sender<ByteBuffer> sender = transport.sender();
+
+ // Security layer
+ sender = securityLayer.sender(sender);
+
+ Disassembler dis = new Disassembler(sender, settings.getMaxFrameSize());
+ return dis;
+ }
+
+ public void buildReceiverPipe(Receiver<ProtocolEvent> delegate)
+ {
+ Receiver<ByteBuffer> receiver = new InputHandler(new Assembler(delegate));
+
+ // Security layer
+ receiver = securityLayer.receiver(receiver);
+
+ //Io layer
+ transport.receiver(receiver);
+ }
+
+ public SecurityLayer getSecurityLayer()
+ {
+ return securityLayer;
+ }
+
+} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java
index 0ccfcfcb70..908d14a307 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java
@@ -63,7 +63,6 @@ abstract class AbstractEncoder implements Encoder
ENCODINGS.put(Double.class, Type.DOUBLE);
ENCODINGS.put(Character.class, Type.CHAR);
ENCODINGS.put(byte[].class, Type.VBIN32);
- ENCODINGS.put(UUID.class, Type.UUID);
}
private final Map<String,byte[]> str8cache = new LinkedHashMap<String,byte[]>()
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkTransport.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkTransport.java
index 4610c2351e..5e12d7e7c6 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkTransport.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkTransport.java
@@ -20,13 +20,19 @@
*/
package org.apache.qpid.transport.network;
-/**
- * A network transport is responsible for the establishment of network connections.
- * NetworkTransport implementations are pluggable via the {@link Transport} class.
- */
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.transport.Receiver;
+import org.apache.qpid.transport.Sender;
+import org.apache.qpid.transport.ConnectionSettings;
+
public interface NetworkTransport
{
+ public void init(ConnectionSettings settings);
+
+ public Sender<ByteBuffer> sender();
+
+ public void receiver(Receiver<ByteBuffer> delegate);
+
public void close();
-
- public NetworkConnection getConnection();
-}
+} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Transport.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Transport.java
index 2c10a30f10..f0bf04d04f 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Transport.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Transport.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,129 +7,50 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
+package org.apache.qpid.transport.network;
-import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.transport.TransportException;
public class Transport
-{
- public static final String QPID_TRANSPORT_PROPNAME = "qpid.transport";
- public static final String QPID_TRANSPORT_V0_8_PROPNAME = "qpid.transport.v0_8";
- public static final String QPID_TRANSPORT_V0_9_PROPNAME = "qpid.transport.v0_9";
- public static final String QPID_TRANSPORT_V0_9_1_PROPNAME = "qpid.transport.v0_9_1";
- public static final String QPID_TRANSPORT_V0_10_PROPNAME = "qpid.transport.v0_10";
- public static final String QPID_BROKER_TRANSPORT_PROPNAME = "qpid.broker.transport";
-
- // Can't reference the class directly here, as this would preclude the ability to bundle transports separately.
- private static final String MINA_TRANSPORT_CLASSNAME = "org.apache.qpid.transport.network.mina.MinaNetworkTransport";
- private static final String IO_TRANSPORT_CLASSNAME = "org.apache.qpid.transport.network.io.IoNetworkTransport";
-
- public static final String TCP = "tcp";
-
- private final static Map<ProtocolVersion,String> OUTGOING_PROTOCOL_TO_IMPLDEFAULTS_MAP;
-
- static
- {
- final Map<ProtocolVersion,String> map = new HashMap<ProtocolVersion, String>();
- map.put(ProtocolVersion.v8_0, MINA_TRANSPORT_CLASSNAME);
- map.put(ProtocolVersion.v0_9, MINA_TRANSPORT_CLASSNAME);
- map.put(ProtocolVersion.v0_91, MINA_TRANSPORT_CLASSNAME);
- map.put(ProtocolVersion.v0_10, IO_TRANSPORT_CLASSNAME);
-
- OUTGOING_PROTOCOL_TO_IMPLDEFAULTS_MAP = Collections.unmodifiableMap(map);
- }
-
- public static IncomingNetworkTransport getIncomingTransportInstance()
+{
+ private final static Class<?> transportClass;
+
+ static
{
- return (IncomingNetworkTransport) loadTransportClass(
- System.getProperty(QPID_BROKER_TRANSPORT_PROPNAME, MINA_TRANSPORT_CLASSNAME));
- }
-
- public static OutgoingNetworkTransport getOutgoingTransportInstance(
- final ProtocolVersion protocolVersion)
- {
-
- final String overrride = getOverrideClassNameFromSystemProperty(protocolVersion);
- final String networkTransportClassName;
- if (overrride != null)
- {
- networkTransportClassName = overrride;
- }
- else
- {
- networkTransportClassName = OUTGOING_PROTOCOL_TO_IMPLDEFAULTS_MAP.get(protocolVersion);
- }
-
- return (OutgoingNetworkTransport) loadTransportClass(networkTransportClassName);
- }
-
- private static NetworkTransport loadTransportClass(final String networkTransportClassName)
- {
- if (networkTransportClassName == null)
- {
- throw new IllegalArgumentException("transport class name must not be null");
- }
-
try
{
- final Class<?> clazz = Class.forName(networkTransportClassName);
- return (NetworkTransport) clazz.newInstance();
+ transportClass =
+ Class.forName(System.getProperty("qpid.transport",
+ "org.apache.qpid.transport.network.io.IoNetworkTransport"));
+
}
- catch (InstantiationException e)
+ catch(Exception e)
{
- throw new TransportException("Unable to instantiate transport class " + networkTransportClassName, e);
- }
- catch (IllegalAccessException e)
- {
- throw new TransportException("Access exception " + networkTransportClassName, e);
- }
- catch (ClassNotFoundException e)
- {
- throw new TransportException("Unable to load transport class " + networkTransportClassName, e);
+ throw new Error("Error occured while loading Qpid Transport",e);
}
}
-
- private static String getOverrideClassNameFromSystemProperty(final ProtocolVersion protocolVersion)
+
+ public static NetworkTransport getTransport() throws TransportException
{
- final String protocolSpecificSystemProperty;
-
- if (ProtocolVersion.v0_10.equals(protocolVersion))
- {
- protocolSpecificSystemProperty = QPID_TRANSPORT_V0_10_PROPNAME;
- }
- else if (ProtocolVersion.v0_91.equals(protocolVersion))
- {
- protocolSpecificSystemProperty = QPID_TRANSPORT_V0_9_1_PROPNAME;
- }
- else if (ProtocolVersion.v0_9.equals(protocolVersion))
- {
- protocolSpecificSystemProperty = QPID_TRANSPORT_V0_9_PROPNAME;
- }
- else if (ProtocolVersion.v8_0.equals(protocolVersion))
+ try
{
- protocolSpecificSystemProperty = QPID_TRANSPORT_V0_8_PROPNAME;
+ return (NetworkTransport)transportClass.newInstance();
}
- else
+ catch (Exception e)
{
- throw new IllegalArgumentException("Unknown ProtocolVersion " + protocolVersion);
+ throw new TransportException("Error while creating a new transport instance",e);
}
-
- return System.getProperty(protocolSpecificSystemProperty, System.getProperty(QPID_TRANSPORT_PROPNAME));
}
-}
+} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/InputHandler_0_9.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/InputHandler_0_9.java
new file mode 100644
index 0000000000..ecc5f6d07c
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/InputHandler_0_9.java
@@ -0,0 +1,130 @@
+package org.apache.qpid.transport.network.io;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQFrame;
+import org.apache.qpid.framing.AMQFrameDecodingException;
+import org.apache.qpid.framing.AMQMethodBody;
+import org.apache.qpid.framing.AMQMethodBodyFactory;
+import org.apache.qpid.framing.BodyFactory;
+import org.apache.qpid.framing.ContentBody;
+import org.apache.qpid.framing.ContentBodyFactory;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.ContentHeaderBodyFactory;
+import org.apache.qpid.framing.HeartbeatBody;
+import org.apache.qpid.framing.HeartbeatBodyFactory;
+import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
+import org.apache.qpid.transport.Receiver;
+
+public class InputHandler_0_9 implements Receiver<ByteBuffer>
+{
+
+ private AMQVersionAwareProtocolSession _session;
+ private MethodRegistry _registry;
+ private BodyFactory bodyFactory;
+ private static final BodyFactory[] _bodiesSupported = new BodyFactory[Byte.MAX_VALUE];
+
+ static
+ {
+ _bodiesSupported[ContentHeaderBody.TYPE] = ContentHeaderBodyFactory.getInstance();
+ _bodiesSupported[ContentBody.TYPE] = ContentBodyFactory.getInstance();
+ _bodiesSupported[HeartbeatBody.TYPE] = new HeartbeatBodyFactory();
+ }
+
+ public InputHandler_0_9(AMQVersionAwareProtocolSession session)
+ {
+ _session = session;
+ _registry = _session.getMethodRegistry();
+ }
+
+ public void closed()
+ {
+ // AS FIXME: implement
+ }
+
+ public void exception(Throwable t)
+ {
+ // TODO: propogate exception to things
+ t.printStackTrace();
+ }
+
+ public void received(ByteBuffer buf)
+ {
+ org.apache.mina.common.ByteBuffer in = org.apache.mina.common.ByteBuffer.wrap(buf);
+ try
+ {
+ final byte type = in.get();
+ if (type == AMQMethodBody.TYPE)
+ {
+ bodyFactory = new AMQMethodBodyFactory(_session);
+ }
+ else
+ {
+ bodyFactory = _bodiesSupported[type];
+ }
+
+ if (bodyFactory == null)
+ {
+ throw new AMQFrameDecodingException(null, "Unsupported frame type: " + type, null);
+ }
+
+ final int channel = in.getUnsignedShort();
+ final long bodySize = in.getUnsignedInt();
+
+ // bodySize can be zero
+ if ((channel < 0) || (bodySize < 0))
+ {
+ throw new AMQFrameDecodingException(null, "Undecodable frame: type = " + type + " channel = " + channel
+ + " bodySize = " + bodySize, null);
+ }
+
+ AMQFrame frame = new AMQFrame(in, channel, bodySize, bodyFactory);
+
+ byte marker = in.get();
+ if ((marker & 0xFF) != 0xCE)
+ {
+ throw new AMQFrameDecodingException(null, "End of frame marker not found. Read " + marker + " length=" + bodySize
+ + " type=" + type, null);
+ }
+
+ try
+ {
+ frame.getBodyFrame().handle(frame.getChannel(), _session);
+ }
+ catch (AMQException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ catch (AMQFrameDecodingException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IoAcceptor.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoAcceptor.java
index 8530240dcc..8530240dcc 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IoAcceptor.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoAcceptor.java
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/MockSender.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoContext.java
index 4b38b7318a..69b3a0ce45 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/MockSender.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoContext.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,41 +7,29 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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;
+package org.apache.qpid.transport.network.io;
+import java.net.Socket;
import java.nio.ByteBuffer;
-public class MockSender implements Sender<ByteBuffer>
-{
-
- public void setIdleTimeout(int i)
- {
-
- }
-
- public void send(ByteBuffer msg)
- {
+import org.apache.qpid.transport.Sender;
- }
-
- public void flush()
- {
-
- }
-
- public void close()
- {
+public interface IoContext
+{
+ Sender<ByteBuffer> getSender();
+
+ IoReceiver getReceiver();
- }
+ Socket getSocket();
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java
deleted file mode 100644
index cca1fc46c9..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java
+++ /dev/null
@@ -1,93 +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.transport.network.io;
-
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-
-import org.apache.qpid.transport.Receiver;
-import org.apache.qpid.transport.Sender;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class IoNetworkConnection implements NetworkConnection
-{
- private static final Logger LOGGER = LoggerFactory.getLogger(IoNetworkConnection.class);
- private final Socket _socket;
- private final long _timeout;
- private final IoSender _ioSender;
- private final IoReceiver _ioReceiver;
-
- public IoNetworkConnection(Socket socket, Receiver<ByteBuffer> delegate,
- int sendBufferSize, int receiveBufferSize, long timeout)
- {
- _socket = socket;
- _timeout = timeout;
-
- _ioReceiver = new IoReceiver(_socket, delegate, receiveBufferSize,_timeout);
- _ioSender = new IoSender(_socket, 2 * sendBufferSize, _timeout);
- _ioSender.registerCloseListener(_ioReceiver);
-
- _ioReceiver.initiate();
- _ioSender.initiate();
- }
-
- public Sender<ByteBuffer> getSender()
- {
- return _ioSender;
- }
-
- public void close()
- {
- try
- {
- _ioSender.close();
- }
- finally
- {
- _ioReceiver.close(false);
- }
- }
-
- public SocketAddress getRemoteAddress()
- {
- return _socket.getRemoteSocketAddress();
- }
-
- public SocketAddress getLocalAddress()
- {
- return _socket.getLocalSocketAddress();
- }
-
- public void setMaxWriteIdle(int sec)
- {
- // TODO implement support for setting heartbeating config in this way
- // Currently a socket timeout is used in IoSender
- }
-
- public void setMaxReadIdle(int sec)
- {
- // TODO implement support for setting heartbeating config in this way
- // Currently a socket timeout is used in IoSender
- }
-}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java
index d611ab1cf3..dd6a37eca2 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java
@@ -27,15 +27,14 @@ import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
-import org.apache.qpid.ssl.SSLContextFactory;
import org.apache.qpid.transport.ConnectionSettings;
import org.apache.qpid.transport.Receiver;
+import org.apache.qpid.transport.Sender;
import org.apache.qpid.transport.TransportException;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.apache.qpid.transport.network.OutgoingNetworkTransport;
+import org.apache.qpid.transport.network.NetworkTransport;
import org.apache.qpid.transport.util.Logger;
-public class IoNetworkTransport implements OutgoingNetworkTransport
+public class IoNetworkTransport implements NetworkTransport, IoContext
{
static
{
@@ -45,31 +44,34 @@ public class IoNetworkTransport implements OutgoingNetworkTransport
(Boolean.getBoolean("amqj.enableDirectBuffers"));
}
- private static final Logger LOGGER = Logger.get(IoNetworkTransport.class);
+ private static final Logger log = Logger.get(IoNetworkTransport.class);
- private Socket _socket;
- private IoNetworkConnection _connection;
- private long _timeout = 60000;
+ private Socket socket;
+ private Sender<ByteBuffer> sender;
+ private IoReceiver receiver;
+ private long timeout = 60000;
+ private ConnectionSettings settings;
- public NetworkConnection connect(ConnectionSettings settings, Receiver<ByteBuffer> delegate, SSLContextFactory sslFactory)
+ public void init(ConnectionSettings settings)
{
- int sendBufferSize = settings.getWriteBufferSize();
- int receiveBufferSize = settings.getReadBufferSize();
-
try
{
- _socket = new Socket();
- _socket.setReuseAddress(true);
- _socket.setTcpNoDelay(settings.isTcpNodelay());
- _socket.setSendBufferSize(sendBufferSize);
- _socket.setReceiveBufferSize(receiveBufferSize);
+ this.settings = settings;
+ InetAddress address = InetAddress.getByName(settings.getHost());
+ socket = new Socket();
+ socket.setReuseAddress(true);
+ socket.setTcpNoDelay(settings.isTcpNodelay());
- LOGGER.debug("SO_RCVBUF : %s", _socket.getReceiveBufferSize());
- LOGGER.debug("SO_SNDBUF : %s", _socket.getSendBufferSize());
+ log.debug("default-SO_RCVBUF : %s", socket.getReceiveBufferSize());
+ log.debug("default-SO_SNDBUF : %s", socket.getSendBufferSize());
- InetAddress address = InetAddress.getByName(settings.getHost());
+ socket.setSendBufferSize(settings.getWriteBufferSize());
+ socket.setReceiveBufferSize(settings.getReadBufferSize());
- _socket.connect(new InetSocketAddress(address, settings.getPort()));
+ log.debug("new-SO_RCVBUF : %s", socket.getReceiveBufferSize());
+ log.debug("new-SO_SNDBUF : %s", socket.getSendBufferSize());
+
+ socket.connect(new InetSocketAddress(address, settings.getPort()));
}
catch (SocketException e)
{
@@ -79,35 +81,36 @@ public class IoNetworkTransport implements OutgoingNetworkTransport
{
throw new TransportException("Error connecting to broker", e);
}
+ }
- try
- {
- _connection = new IoNetworkConnection(_socket, delegate, sendBufferSize, receiveBufferSize, _timeout);
- }
- catch(Exception e)
- {
- try
- {
- _socket.close();
- }
- catch(IOException ioe)
- {
- //ignored, throw based on original exception
- }
-
- throw new TransportException("Error creating network connection", e);
- }
+ public void receiver(Receiver<ByteBuffer> delegate)
+ {
+ receiver = new IoReceiver(this, delegate,
+ 2*settings.getReadBufferSize() , timeout);
+ }
- return _connection;
+ public Sender<ByteBuffer> sender()
+ {
+ return new IoSender(this, 2*settings.getWriteBufferSize(), timeout);
}
public void close()
{
- _connection.close();
+
+ }
+
+ public Sender<ByteBuffer> getSender()
+ {
+ return sender;
+ }
+
+ public IoReceiver getReceiver()
+ {
+ return receiver;
}
- public NetworkConnection getConnection()
+ public Socket getSocket()
{
- return _connection;
+ return socket;
}
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java
index fea87fc350..19a683d505 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.transport.network.io;
-import org.apache.qpid.common.Closeable;
import org.apache.qpid.thread.Threading;
import org.apache.qpid.transport.Receiver;
import org.apache.qpid.transport.TransportException;
@@ -38,54 +37,43 @@ import java.util.concurrent.atomic.AtomicBoolean;
*
*/
-final class IoReceiver implements Runnable, Closeable
+final class IoReceiver implements Runnable
{
private static final Logger log = Logger.get(IoReceiver.class);
+ private final IoContext ioCtx;
private final Receiver<ByteBuffer> receiver;
private final int bufferSize;
private final Socket socket;
private final long timeout;
private final AtomicBoolean closed = new AtomicBoolean(false);
private final Thread receiverThread;
- private static final boolean shutdownBroken;
- static
- {
- String osName = System.getProperty("os.name");
- shutdownBroken = osName == null ? false : osName.matches("(?i).*windows.*");
- }
+ private final boolean shutdownBroken =
+ ((String) System.getProperties().get("os.name")).matches("(?i).*windows.*");
- public IoReceiver(Socket socket, Receiver<ByteBuffer> receiver, int bufferSize, long timeout)
+ public IoReceiver(IoContext ioCtx, Receiver<ByteBuffer> receiver,
+ int bufferSize, long timeout)
{
+ this.ioCtx = ioCtx;
this.receiver = receiver;
this.bufferSize = bufferSize;
- this.socket = socket;
+ this.socket = ioCtx.getSocket();
this.timeout = timeout;
try
{
- //Create but deliberately don't start the thread.
receiverThread = Threading.getThreadFactory().createThread(this);
}
catch(Exception e)
{
- throw new RuntimeException("Error creating IOReceiver thread",e);
+ throw new Error("Error creating IOReceiver thread",e);
}
receiverThread.setDaemon(true);
receiverThread.setName(String.format("IoReceiver - %s", socket.getRemoteSocketAddress()));
- }
-
- public void initiate()
- {
receiverThread.start();
}
- public void close()
- {
- close(false);
- }
-
void close(boolean block)
{
if (!closed.getAndSet(true))
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java
index 1bb515624c..66b97e8225 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java
@@ -24,11 +24,8 @@ import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
-import org.apache.qpid.common.Closeable;
import org.apache.qpid.thread.Threading;
import org.apache.qpid.transport.Sender;
import org.apache.qpid.transport.SenderException;
@@ -46,6 +43,7 @@ public final class IoSender implements Runnable, Sender<ByteBuffer>
// we can test other cases as well
private final static int START = Integer.MAX_VALUE - 10;
+ private final IoContext ioCtx;
private final long timeout;
private final Socket socket;
private final OutputStream out;
@@ -58,13 +56,14 @@ public final class IoSender implements Runnable, Sender<ByteBuffer>
private final Object notEmpty = new Object();
private final AtomicBoolean closed = new AtomicBoolean(false);
private final Thread senderThread;
- private final List<Closeable> _listeners = new ArrayList<Closeable>();
private volatile Throwable exception = null;
- public IoSender(Socket socket, int bufferSize, long timeout)
+
+ public IoSender(IoContext ioCtx, int bufferSize, long timeout)
{
- this.socket = socket;
+ this.ioCtx = ioCtx;
+ this.socket = ioCtx.getSocket();
this.buffer = new byte[pof2(bufferSize)]; // buffer size must be a power of 2
this.timeout = timeout;
@@ -79,7 +78,6 @@ public final class IoSender implements Runnable, Sender<ByteBuffer>
try
{
- //Create but deliberately don't start the thread.
senderThread = Threading.getThreadFactory().createThread(this);
}
catch(Exception e)
@@ -89,10 +87,6 @@ public final class IoSender implements Runnable, Sender<ByteBuffer>
senderThread.setDaemon(true);
senderThread.setName(String.format("IoSender - %s", socket.getRemoteSocketAddress()));
- }
-
- public void initiate()
- {
senderThread.start();
}
@@ -210,20 +204,16 @@ public final class IoSender implements Runnable, Sender<ByteBuffer>
senderThread.join(timeout);
if (senderThread.isAlive())
{
- log.error("join timed out");
throw new SenderException("join timed out");
}
}
+ ioCtx.getReceiver().close(false);
}
catch (InterruptedException e)
{
- log.error("interrupted whilst waiting for sender thread to stop");
throw new SenderException(e);
}
- finally
- {
- closeListeners();
- }
+
if (reportException && exception != null)
{
throw new SenderException(exception);
@@ -231,28 +221,6 @@ public final class IoSender implements Runnable, Sender<ByteBuffer>
}
}
- private void closeListeners()
- {
- Exception ex = null;
- for(Closeable listener : _listeners)
- {
- try
- {
- listener.close();
- }
- catch(Exception e)
- {
- log.error("Exception closing listener: " + e.getMessage());
- ex = e;
- }
- }
-
- if (ex != null)
- {
- throw new SenderException(ex.getMessage(), ex);
- }
- }
-
public void run()
{
final int size = buffer.length;
@@ -336,9 +304,4 @@ public final class IoSender implements Runnable, Sender<ByteBuffer>
throw new SenderException(e);
}
}
-
- public void registerCloseListener(Closeable listener)
- {
- _listeners.add(listener);
- }
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoTransport.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoTransport.java
new file mode 100644
index 0000000000..bfdbb34978
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoTransport.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+
+import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
+import org.apache.qpid.ssl.SSLContextFactory;
+import org.apache.qpid.transport.Binding;
+import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.ConnectionDelegate;
+import org.apache.qpid.transport.Receiver;
+import org.apache.qpid.transport.Sender;
+import org.apache.qpid.transport.TransportException;
+import org.apache.qpid.transport.network.ConnectionBinding;
+import org.apache.qpid.transport.network.security.ssl.SSLReceiver;
+import org.apache.qpid.transport.network.security.ssl.SSLSender;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * This class provides a socket based transport using the java.io
+ * classes.
+ *
+ * The following params are configurable via JVM arguments
+ * TCP_NO_DELAY - amqj.tcpNoDelay
+ * SO_RCVBUF - amqj.receiveBufferSize
+ * SO_SNDBUF - amqj.sendBufferSize
+ */
+public final class IoTransport<E> implements IoContext
+{
+
+ static
+ {
+ org.apache.mina.common.ByteBuffer.setAllocator
+ (new org.apache.mina.common.SimpleByteBufferAllocator());
+ org.apache.mina.common.ByteBuffer.setUseDirectBuffers
+ (Boolean.getBoolean("amqj.enableDirectBuffers"));
+ }
+
+ private static final Logger log = Logger.get(IoTransport.class);
+
+ private static int DEFAULT_READ_WRITE_BUFFER_SIZE = 64 * 1024;
+ private static int readBufferSize = Integer.getInteger
+ ("amqj.receiveBufferSize", DEFAULT_READ_WRITE_BUFFER_SIZE);
+ private static int writeBufferSize = Integer.getInteger
+ ("amqj.sendBufferSize", DEFAULT_READ_WRITE_BUFFER_SIZE);
+
+ private Socket socket;
+ private Sender<ByteBuffer> sender;
+ private E endpoint;
+ private IoReceiver receiver;
+ private long timeout = 60000;
+
+ IoTransport(Socket socket, Binding<E,ByteBuffer> binding, boolean ssl)
+ {
+ this.socket = socket;
+
+ if (ssl)
+ {
+ SSLEngine engine = null;
+ SSLContext sslCtx;
+ try
+ {
+ sslCtx = createSSLContext();
+ }
+ catch (Exception e)
+ {
+ throw new TransportException("Error creating SSL Context", e);
+ }
+
+ try
+ {
+ engine = sslCtx.createSSLEngine();
+ engine.setUseClientMode(true);
+ }
+ catch(Exception e)
+ {
+ throw new TransportException("Error creating SSL Engine", e);
+ }
+
+ this.sender = new SSLSender(engine,new IoSender(this, 2*writeBufferSize, timeout));
+ this.endpoint = binding.endpoint(sender);
+ this.receiver = new IoReceiver(this, new SSLReceiver(engine,binding.receiver(endpoint),(SSLSender)sender),
+ 2*readBufferSize, timeout);
+
+ log.info("SSL Sender and Receiver initiated");
+ }
+ else
+ {
+ this.sender = new IoSender(this, 2*writeBufferSize, timeout);
+ this.endpoint = binding.endpoint(sender);
+ this.receiver = new IoReceiver(this, binding.receiver(endpoint),
+ 2*readBufferSize, timeout);
+ }
+ }
+
+ public Sender<ByteBuffer> getSender()
+ {
+ return sender;
+ }
+
+ public IoReceiver getReceiver()
+ {
+ return receiver;
+ }
+
+ public Socket getSocket()
+ {
+ return socket;
+ }
+
+ public static final <E> E connect(String host, int port,
+ Binding<E,ByteBuffer> binding,
+ boolean ssl)
+ {
+ Socket socket = createSocket(host, port);
+ IoTransport<E> transport = new IoTransport<E>(socket, binding,ssl);
+ return transport.endpoint;
+ }
+
+ public static final Connection connect(String host, int port,
+ ConnectionDelegate delegate,
+ boolean ssl)
+ {
+ return connect(host, port, ConnectionBinding.get(delegate),ssl);
+ }
+
+ public static void connect_0_9(AMQVersionAwareProtocolSession session, String host, int port, boolean ssl)
+ {
+ connect(host, port, new Binding_0_9(session),ssl);
+ }
+
+ private static class Binding_0_9
+ implements Binding<AMQVersionAwareProtocolSession,ByteBuffer>
+ {
+
+ private AMQVersionAwareProtocolSession session;
+
+ Binding_0_9(AMQVersionAwareProtocolSession session)
+ {
+ this.session = session;
+ }
+
+ public AMQVersionAwareProtocolSession endpoint(Sender<ByteBuffer> sender)
+ {
+ session.setSender(sender);
+ return session;
+ }
+
+ public Receiver<ByteBuffer> receiver(AMQVersionAwareProtocolSession ssn)
+ {
+ return new InputHandler_0_9(ssn);
+ }
+
+ }
+
+ private static Socket createSocket(String host, int port)
+ {
+ try
+ {
+ InetAddress address = InetAddress.getByName(host);
+ Socket socket = new Socket();
+ socket.setReuseAddress(true);
+ socket.setTcpNoDelay(Boolean.getBoolean("amqj.tcpNoDelay"));
+
+ log.debug("default-SO_RCVBUF : %s", socket.getReceiveBufferSize());
+ log.debug("default-SO_SNDBUF : %s", socket.getSendBufferSize());
+
+ socket.setSendBufferSize(writeBufferSize);
+ socket.setReceiveBufferSize(readBufferSize);
+
+ log.debug("new-SO_RCVBUF : %s", socket.getReceiveBufferSize());
+ log.debug("new-SO_SNDBUF : %s", socket.getSendBufferSize());
+
+ socket.connect(new InetSocketAddress(address, port));
+ return socket;
+ }
+ catch (SocketException e)
+ {
+ throw new TransportException("Error connecting to broker", e);
+ }
+ catch (IOException e)
+ {
+ throw new TransportException("Error connecting to broker", e);
+ }
+ }
+
+ private SSLContext createSSLContext() throws Exception
+ {
+ String trustStorePath = System.getProperty("javax.net.ssl.trustStore");
+ String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
+ String trustStoreCertType = System.getProperty("qpid.ssl.trustStoreCertType","SunX509");
+
+ String keyStorePath = System.getProperty("javax.net.ssl.keyStore",trustStorePath);
+ String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword",trustStorePassword);
+ String keyStoreCertType = System.getProperty("qpid.ssl.keyStoreCertType","SunX509");
+
+ SSLContextFactory sslContextFactory = new SSLContextFactory(trustStorePath,trustStorePassword,
+ trustStoreCertType,keyStorePath,
+ keyStorePassword,keyStoreCertType);
+
+ return sslContextFactory.buildServerContext();
+
+ }
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MINANetworkDriver.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MINANetworkDriver.java
new file mode 100644
index 0000000000..0f2c0d0226
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MINANetworkDriver.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.transport.network.mina;
+
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.ExecutorThreadModel;
+import org.apache.mina.common.IdleStatus;
+import org.apache.mina.common.IoAcceptor;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.SimpleByteBufferAllocator;
+import org.apache.mina.common.WriteFuture;
+import org.apache.mina.filter.ReadThrottleFilterBuilder;
+import org.apache.mina.filter.SSLFilter;
+import org.apache.mina.filter.WriteBufferLimitFilterBuilder;
+import org.apache.mina.filter.executor.ExecutorFilter;
+import org.apache.mina.transport.socket.nio.MultiThreadSocketConnector;
+import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
+import org.apache.mina.transport.socket.nio.SocketConnector;
+import org.apache.mina.transport.socket.nio.SocketConnectorConfig;
+import org.apache.mina.transport.socket.nio.SocketSessionConfig;
+import org.apache.mina.util.NewThreadExecutor;
+import org.apache.mina.util.SessionUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.protocol.ProtocolEngineFactory;
+import org.apache.qpid.ssl.SSLContextFactory;
+import org.apache.qpid.thread.QpidThreadExecutor;
+import org.apache.qpid.transport.NetworkDriver;
+import org.apache.qpid.transport.NetworkDriverConfiguration;
+import org.apache.qpid.transport.OpenException;
+
+import java.io.IOException;
+import java.net.BindException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+
+public class MINANetworkDriver extends IoHandlerAdapter implements NetworkDriver
+{
+
+ private static final int DEFAULT_BUFFER_SIZE = 32 * 1024;
+
+ ProtocolEngine _protocolEngine;
+ private boolean _useNIO = false;
+ private int _processors = 4;
+ private boolean _executorPool = false;
+ private SSLContextFactory _sslFactory = null;
+ private IoConnector _socketConnector;
+ private IoAcceptor _acceptor;
+ private IoSession _ioSession;
+ private ProtocolEngineFactory _factory;
+ private boolean _protectIO;
+ private NetworkDriverConfiguration _config;
+ private Throwable _lastException;
+ private boolean _acceptingConnections = false;
+
+ private WriteFuture _lastWriteFuture;
+
+ private static final Logger _logger = LoggerFactory.getLogger(MINANetworkDriver.class);
+
+ static
+ {
+ org.apache.mina.common.ByteBuffer.setUseDirectBuffers(Boolean.getBoolean("amqj.enableDirectBuffers"));
+
+ //override the MINA defaults to prevent use of the PooledByteBufferAllocator
+ org.apache.mina.common.ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
+ }
+
+ public MINANetworkDriver(boolean useNIO, int processors, boolean executorPool, boolean protectIO)
+ {
+ _useNIO = useNIO;
+ _processors = processors;
+ _executorPool = executorPool;
+ _protectIO = protectIO;
+ }
+
+ public MINANetworkDriver(boolean useNIO, int processors, boolean executorPool, boolean protectIO,
+ ProtocolEngine protocolEngine, IoSession session)
+ {
+ _useNIO = useNIO;
+ _processors = processors;
+ _executorPool = executorPool;
+ _protectIO = protectIO;
+ _protocolEngine = protocolEngine;
+ _ioSession = session;
+ _ioSession.setAttachment(_protocolEngine);
+ }
+
+ public MINANetworkDriver()
+ {
+
+ }
+
+ public MINANetworkDriver(IoConnector ioConnector)
+ {
+ _socketConnector = ioConnector;
+ }
+
+ public MINANetworkDriver(IoConnector ioConnector, ProtocolEngine engine)
+ {
+ _socketConnector = ioConnector;
+ _protocolEngine = engine;
+ }
+
+ public void bind(int port, InetAddress[] addresses, ProtocolEngineFactory factory,
+ NetworkDriverConfiguration config, SSLContextFactory sslFactory) throws BindException
+ {
+
+ _factory = factory;
+ _config = config;
+
+ if (_useNIO)
+ {
+ _acceptor = new org.apache.mina.transport.socket.nio.MultiThreadSocketAcceptor(_processors,
+ new NewThreadExecutor());
+ }
+ else
+ {
+ _acceptor = new org.apache.mina.transport.socket.nio.SocketAcceptor(_processors, new NewThreadExecutor());
+ }
+
+ SocketAcceptorConfig sconfig = (SocketAcceptorConfig) _acceptor.getDefaultConfig();
+ sconfig.setThreadModel(ExecutorThreadModel.getInstance("MINANetworkDriver(Acceptor)"));
+ SocketSessionConfig sc = (SocketSessionConfig) sconfig.getSessionConfig();
+
+ if (config != null)
+ {
+ sc.setReceiveBufferSize(config.getReceiveBufferSize());
+ sc.setSendBufferSize(config.getSendBufferSize());
+ sc.setTcpNoDelay(config.getTcpNoDelay());
+ }
+
+ if (sslFactory != null)
+ {
+ _sslFactory = sslFactory;
+ }
+
+ if (addresses != null && addresses.length > 0)
+ {
+ for (InetAddress addr : addresses)
+ {
+ try
+ {
+ _acceptor.bind(new InetSocketAddress(addr, port), this, sconfig);
+ }
+ catch (IOException e)
+ {
+ throw new BindException(String.format("Could not bind to %1s:%2s", addr, port));
+ }
+ }
+ }
+ else
+ {
+ try
+ {
+ _acceptor.bind(new InetSocketAddress(port), this, sconfig);
+ }
+ catch (IOException e)
+ {
+ throw new BindException(String.format("Could not bind to *:%1s", port));
+ }
+ }
+ _acceptingConnections = true;
+ }
+
+ public SocketAddress getRemoteAddress()
+ {
+ return _ioSession.getRemoteAddress();
+ }
+
+ public SocketAddress getLocalAddress()
+ {
+ return _ioSession.getLocalAddress();
+ }
+
+
+ public void open(int port, InetAddress destination, ProtocolEngine engine, NetworkDriverConfiguration config,
+ SSLContextFactory sslFactory) throws OpenException
+ {
+ if (sslFactory != null)
+ {
+ _sslFactory = sslFactory;
+ }
+
+ if (_useNIO)
+ {
+ _socketConnector = new MultiThreadSocketConnector(1, new QpidThreadExecutor());
+ }
+ else
+ {
+ _socketConnector = new SocketConnector(1, new QpidThreadExecutor()); // non-blocking
+ // connector
+ }
+
+ SocketConnectorConfig cfg = (SocketConnectorConfig) _socketConnector.getDefaultConfig();
+ String s = "";
+ StackTraceElement[] trace = Thread.currentThread().getStackTrace();
+ for(StackTraceElement elt : trace)
+ {
+ if(elt.getClassName().contains("Test"))
+ {
+ s = elt.getClassName();
+ break;
+ }
+ }
+ cfg.setThreadModel(ExecutorThreadModel.getInstance("MINANetworkDriver(Client)-"+s));
+
+ SocketSessionConfig scfg = (SocketSessionConfig) cfg.getSessionConfig();
+ scfg.setTcpNoDelay((config != null) ? config.getTcpNoDelay() : true);
+ scfg.setSendBufferSize((config != null) ? config.getSendBufferSize() : DEFAULT_BUFFER_SIZE);
+ scfg.setReceiveBufferSize((config != null) ? config.getReceiveBufferSize() : DEFAULT_BUFFER_SIZE);
+
+ // Don't have the connector's worker thread wait around for other
+ // connections (we only use
+ // one SocketConnector per connection at the moment anyway). This allows
+ // short-running
+ // clients (like unit tests) to complete quickly.
+ if (_socketConnector instanceof SocketConnector)
+ {
+ ((SocketConnector) _socketConnector).setWorkerTimeout(0);
+ }
+
+ ConnectFuture future = _socketConnector.connect(new InetSocketAddress(destination, port), this, cfg);
+ future.join();
+ if (!future.isConnected())
+ {
+ throw new OpenException("Could not open connection", _lastException);
+ }
+ _ioSession = future.getSession();
+ _ioSession.setAttachment(engine);
+ engine.setNetworkDriver(this);
+ _protocolEngine = engine;
+ }
+
+ public void setMaxReadIdle(int idleTime)
+ {
+ _ioSession.setIdleTime(IdleStatus.READER_IDLE, idleTime);
+ }
+
+ public void setMaxWriteIdle(int idleTime)
+ {
+ _ioSession.setIdleTime(IdleStatus.WRITER_IDLE, idleTime);
+ }
+
+ public void close()
+ {
+ if (_lastWriteFuture != null)
+ {
+ _lastWriteFuture.join();
+ }
+ if (_acceptor != null)
+ {
+ _acceptor.unbindAll();
+ }
+ if (_ioSession != null)
+ {
+ _ioSession.close();
+ }
+ }
+
+ public void flush()
+ {
+ if (_lastWriteFuture != null)
+ {
+ _lastWriteFuture.join();
+ }
+ }
+
+ public void send(ByteBuffer msg)
+ {
+ org.apache.mina.common.ByteBuffer minaBuf = org.apache.mina.common.ByteBuffer.allocate(msg.capacity());
+ minaBuf.put(msg);
+ minaBuf.flip();
+ _lastWriteFuture = _ioSession.write(minaBuf);
+ }
+
+ public void setIdleTimeout(int i)
+ {
+ // MINA doesn't support setting SO_TIMEOUT
+ }
+
+ public void exceptionCaught(IoSession protocolSession, Throwable throwable) throws Exception
+ {
+ if (_protocolEngine != null)
+ {
+ _protocolEngine.exception(throwable);
+ }
+ else
+ {
+ _logger.error("Exception thrown and no ProtocolEngine to handle it", throwable);
+ }
+ _lastException = throwable;
+ }
+
+ /**
+ * Invoked when a message is received on a particular protocol session. Note
+ * that a protocol session is directly tied to a particular physical
+ * connection.
+ *
+ * @param protocolSession
+ * the protocol session that received the message
+ * @param message
+ * the message itself (i.e. a decoded frame)
+ *
+ * @throws Exception
+ * if the message cannot be processed
+ */
+ public void messageReceived(IoSession protocolSession, Object message) throws Exception
+ {
+ if (message instanceof org.apache.mina.common.ByteBuffer)
+ {
+ ((ProtocolEngine) protocolSession.getAttachment()).received(((org.apache.mina.common.ByteBuffer) message).buf());
+ }
+ else
+ {
+ throw new IllegalStateException("Handed unhandled message. message.class = " + message.getClass() + " message = " + message);
+ }
+ }
+
+ public void sessionClosed(IoSession protocolSession) throws Exception
+ {
+ ((ProtocolEngine) protocolSession.getAttachment()).closed();
+ }
+
+ public void sessionCreated(IoSession protocolSession) throws Exception
+ {
+ // Configure the session with SSL if necessary
+ SessionUtil.initialize(protocolSession);
+ if (_executorPool)
+ {
+ if (_sslFactory != null)
+ {
+ protocolSession.getFilterChain().addAfter("AsynchronousReadFilter", "sslFilter",
+ new SSLFilter(_sslFactory.buildServerContext()));
+ }
+ }
+ else
+ {
+ if (_sslFactory != null)
+ {
+ protocolSession.getFilterChain().addBefore("protocolFilter", "sslFilter",
+ new SSLFilter(_sslFactory.buildServerContext()));
+ }
+ }
+ // Do we want to have read/write buffer limits?
+ if (_protectIO)
+ {
+ //Add IO Protection Filters
+ IoFilterChain chain = protocolSession.getFilterChain();
+
+ protocolSession.getFilterChain().addLast("tempExecutorFilterForFilterBuilder", new ExecutorFilter());
+
+ ReadThrottleFilterBuilder readfilter = new ReadThrottleFilterBuilder();
+ readfilter.setMaximumConnectionBufferSize(_config.getReceiveBufferSize());
+ readfilter.attach(chain);
+
+ WriteBufferLimitFilterBuilder writefilter = new WriteBufferLimitFilterBuilder();
+ writefilter.setMaximumConnectionBufferSize(_config.getSendBufferSize());
+ writefilter.attach(chain);
+
+ protocolSession.getFilterChain().remove("tempExecutorFilterForFilterBuilder");
+ }
+
+ if (_ioSession == null)
+ {
+ _ioSession = protocolSession;
+ }
+
+ if (_acceptingConnections)
+ {
+ // Set up the protocol engine
+ ProtocolEngine protocolEngine = _factory.newProtocolEngine(this);
+ MINANetworkDriver newDriver = new MINANetworkDriver(_useNIO, _processors, _executorPool, _protectIO, protocolEngine, protocolSession);
+ protocolEngine.setNetworkDriver(newDriver);
+ }
+ }
+
+ public void sessionIdle(IoSession session, IdleStatus status) throws Exception
+ {
+ if (IdleStatus.WRITER_IDLE.equals(status))
+ {
+ ((ProtocolEngine) session.getAttachment()).writerIdle();
+ }
+ else if (IdleStatus.READER_IDLE.equals(status))
+ {
+ ((ProtocolEngine) session.getAttachment()).readerIdle();
+ }
+ }
+
+ private ProtocolEngine getProtocolEngine()
+ {
+ return _protocolEngine;
+ }
+
+ public void setProtocolEngineFactory(ProtocolEngineFactory engineFactory, boolean acceptingConnections)
+ {
+ _factory = engineFactory;
+ _acceptingConnections = acceptingConnections;
+ }
+
+ public void setProtocolEngine(ProtocolEngine protocolEngine)
+ {
+ _protocolEngine = protocolEngine;
+ if (_ioSession != null)
+ {
+ _ioSession.setAttachment(protocolEngine);
+ }
+ }
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaHandler.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaHandler.java
new file mode 100644
index 0000000000..b89eed48b0
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaHandler.java
@@ -0,0 +1,274 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.mina;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+
+import org.apache.mina.common.*;
+
+import org.apache.mina.transport.socket.nio.SocketAcceptor;
+import org.apache.mina.transport.socket.nio.SocketSessionConfig;
+import org.apache.mina.transport.socket.nio.SocketConnector;
+import org.apache.mina.filter.ReadThrottleFilterBuilder;
+import org.apache.mina.filter.WriteBufferLimitFilterBuilder;
+import org.apache.mina.filter.executor.ExecutorFilter;
+
+import org.apache.qpid.transport.Binding;
+import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.ConnectionDelegate;
+import org.apache.qpid.transport.Receiver;
+import org.apache.qpid.transport.Sender;
+import org.apache.qpid.transport.network.ConnectionBinding;
+
+import org.apache.qpid.transport.util.Logger;
+
+import org.apache.qpid.transport.network.Assembler;
+import org.apache.qpid.transport.network.Disassembler;
+import org.apache.qpid.transport.network.InputHandler;
+
+import static org.apache.qpid.transport.util.Functions.*;
+
+/**
+ * MinaHandler
+ *
+ * @author Rafael H. Schloming
+ */
+//RA making this public until we sort out the package issues
+public class MinaHandler<E> implements IoHandler
+{
+ /** Default buffer size for pending messages reads */
+ private static final String DEFAULT_READ_BUFFER_LIMIT = "262144";
+ /** Default buffer size for pending messages writes */
+ private static final String DEFAULT_WRITE_BUFFER_LIMIT = "262144";
+ private static final int MAX_RCVBUF = 64*1024;
+
+ private static final Logger log = Logger.get(MinaHandler.class);
+
+ static
+ {
+ ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
+ ByteBuffer.setUseDirectBuffers(Boolean.getBoolean("amqj.enableDirectBuffers"));
+ }
+
+ private final Binding<E,java.nio.ByteBuffer> binding;
+
+ private MinaHandler(Binding<E,java.nio.ByteBuffer> binding)
+ {
+ this.binding = binding;
+ }
+
+ public void messageReceived(IoSession ssn, Object obj)
+ {
+ Attachment<E> attachment = (Attachment<E>) ssn.getAttachment();
+ ByteBuffer buf = (ByteBuffer) obj;
+ try
+ {
+ attachment.receiver.received(buf.buf());
+ }
+ catch (Throwable t)
+ {
+ log.error(t, "exception handling buffer %s", str(buf.buf()));
+ throw new RuntimeException(t);
+ }
+ }
+
+ public void messageSent(IoSession ssn, Object obj)
+ {
+ // do nothing
+ }
+
+ public void exceptionCaught(IoSession ssn, Throwable e)
+ {
+ Attachment<E> attachment = (Attachment<E>) ssn.getAttachment();
+ attachment.receiver.exception(e);
+ }
+
+ /**
+ * Invoked by MINA when a MINA session for a new connection is created. This method sets up the filter chain on the
+ * session, which filters the events handled by this handler. The filter chain consists of, handing off events
+ * to an optional protectio
+ *
+ * @param session The MINA session.
+ * @throws Exception Any underlying exceptions are allowed to fall through to MINA.
+ */
+ public void sessionCreated(IoSession session) throws Exception
+ {
+ log.debug("Protocol session created for session " + System.identityHashCode(session));
+
+ if (Boolean.getBoolean("protectio"))
+ {
+ try
+ {
+ //Add IO Protection Filters
+ IoFilterChain chain = session.getFilterChain();
+
+ session.getFilterChain().addLast("tempExecutorFilterForFilterBuilder", new ExecutorFilter());
+
+ ReadThrottleFilterBuilder readfilter = new ReadThrottleFilterBuilder();
+ readfilter.setMaximumConnectionBufferSize(
+ Integer.parseInt(System.getProperty("qpid.read.buffer.limit", DEFAULT_READ_BUFFER_LIMIT)));
+ readfilter.attach(chain);
+
+ WriteBufferLimitFilterBuilder writefilter = new WriteBufferLimitFilterBuilder();
+ writefilter.setMaximumConnectionBufferSize(
+ Integer.parseInt(System.getProperty("qpid.write.buffer.limit", DEFAULT_WRITE_BUFFER_LIMIT)));
+ writefilter.attach(chain);
+ session.getFilterChain().remove("tempExecutorFilterForFilterBuilder");
+
+ log.info("Using IO Read/Write Filter Protection");
+ }
+ catch (Exception e)
+ {
+ log.error("Unable to attach IO Read/Write Filter Protection :" + e.getMessage());
+ }
+ }
+ }
+
+ public void sessionOpened(final IoSession ssn)
+ {
+ log.debug("opened: %s", this);
+ E endpoint = binding.endpoint(new MinaSender(ssn));
+ Attachment<E> attachment =
+ new Attachment<E>(endpoint, binding.receiver(endpoint));
+
+ // We need to synchronize and notify here because the MINA
+ // connect future returns the session prior to the attachment
+ // being set. This is arguably a bug in MINA.
+ synchronized (ssn)
+ {
+ ssn.setAttachment(attachment);
+ ssn.notifyAll();
+ }
+ }
+
+ public void sessionClosed(IoSession ssn)
+ {
+ log.debug("closed: %s", ssn);
+ Attachment<E> attachment = (Attachment<E>) ssn.getAttachment();
+ attachment.receiver.closed();
+ ssn.setAttachment(null);
+ }
+
+ public void sessionIdle(IoSession ssn, IdleStatus status)
+ {
+ // do nothing
+ }
+
+ private static class Attachment<E>
+ {
+
+ E endpoint;
+ Receiver<java.nio.ByteBuffer> receiver;
+
+ Attachment(E endpoint, Receiver<java.nio.ByteBuffer> receiver)
+ {
+ this.endpoint = endpoint;
+ this.receiver = receiver;
+ }
+ }
+
+ public static final void accept(String host, int port,
+ Binding<?,java.nio.ByteBuffer> binding)
+ throws IOException
+ {
+ accept(new InetSocketAddress(host, port), binding);
+ }
+
+ public static final <E> void accept(SocketAddress address,
+ Binding<E,java.nio.ByteBuffer> binding)
+ throws IOException
+ {
+ IoAcceptor acceptor = new SocketAcceptor();
+ acceptor.bind(address, new MinaHandler<E>(binding));
+ }
+
+ public static final <E> E connect(String host, int port,
+ Binding<E,java.nio.ByteBuffer> binding)
+ {
+ return connect(new InetSocketAddress(host, port), binding);
+ }
+
+ public static final <E> E connect(SocketAddress address,
+ Binding<E,java.nio.ByteBuffer> binding)
+ {
+ MinaHandler<E> handler = new MinaHandler<E>(binding);
+ SocketConnector connector = new SocketConnector();
+ IoServiceConfig acceptorConfig = connector.getDefaultConfig();
+ acceptorConfig.setThreadModel(ThreadModel.MANUAL);
+ SocketSessionConfig scfg = (SocketSessionConfig) acceptorConfig.getSessionConfig();
+ scfg.setTcpNoDelay(Boolean.getBoolean("amqj.tcpNoDelay"));
+ Integer sendBufferSize = Integer.getInteger("amqj.sendBufferSize");
+ if (sendBufferSize != null && sendBufferSize > 0)
+ {
+ scfg.setSendBufferSize(sendBufferSize);
+ }
+ Integer receiveBufferSize = Integer.getInteger("amqj.receiveBufferSize");
+ if (receiveBufferSize != null && receiveBufferSize > 0)
+ {
+ scfg.setReceiveBufferSize(receiveBufferSize);
+ }
+ else if (scfg.getReceiveBufferSize() > MAX_RCVBUF)
+ {
+ scfg.setReceiveBufferSize(MAX_RCVBUF);
+ }
+ connector.setWorkerTimeout(0);
+ ConnectFuture cf = connector.connect(address, handler);
+ cf.join();
+ IoSession ssn = cf.getSession();
+
+ // We need to synchronize and wait here because the MINA
+ // connect future returns the session prior to the attachment
+ // being set. This is arguably a bug in MINA.
+ synchronized (ssn)
+ {
+ while (ssn.getAttachment() == null)
+ {
+ try
+ {
+ ssn.wait();
+ }
+ catch (InterruptedException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ Attachment<E> attachment = (Attachment<E>) ssn.getAttachment();
+ return attachment.endpoint;
+ }
+
+ public static final void accept(String host, int port,
+ ConnectionDelegate delegate)
+ throws IOException
+ {
+ accept(host, port, ConnectionBinding.get(delegate));
+ }
+
+ public static final Connection connect(String host, int port,
+ ConnectionDelegate delegate)
+ {
+ return connect(host, port, ConnectionBinding.get(delegate));
+ }
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkConnection.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkConnection.java
deleted file mode 100644
index 0f433f6eeb..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkConnection.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.transport.network.mina;
-
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-
-import org.apache.mina.common.IdleStatus;
-import org.apache.mina.common.IoSession;
-import org.apache.qpid.transport.Sender;
-import org.apache.qpid.transport.network.NetworkConnection;
-
-public class MinaNetworkConnection implements NetworkConnection
-{
- private IoSession _session;
- private Sender<ByteBuffer> _sender;
-
- public MinaNetworkConnection(IoSession session)
- {
- _session = session;
- _sender = new MinaSender(_session);
- }
-
- public Sender<ByteBuffer> getSender()
- {
- return _sender;
- }
-
- public void close()
- {
- _session.close();
- }
-
- public SocketAddress getRemoteAddress()
- {
- return _session.getRemoteAddress();
- }
-
- public SocketAddress getLocalAddress()
- {
- return _session.getLocalAddress();
- }
-
- public long getReadBytes()
- {
- return _session.getReadBytes();
- }
-
- public long getWrittenBytes()
- {
- return _session.getWrittenBytes();
- }
-
- public void setMaxWriteIdle(int sec)
- {
- _session.setIdleTime(IdleStatus.WRITER_IDLE, sec);
- }
-
- public void setMaxReadIdle(int sec)
- {
- _session.setIdleTime(IdleStatus.READER_IDLE, sec);
- }
-}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkHandler.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkHandler.java
deleted file mode 100644
index c00187480c..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkHandler.java
+++ /dev/null
@@ -1,149 +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.transport.network.mina;
-
-import org.apache.mina.common.ByteBuffer;
-import org.apache.mina.common.IdleStatus;
-import org.apache.mina.common.IoHandlerAdapter;
-import org.apache.mina.common.IoSession;
-import org.apache.mina.common.SimpleByteBufferAllocator;
-import org.apache.mina.filter.SSLFilter;
-import org.apache.mina.util.SessionUtil;
-import org.apache.qpid.protocol.ProtocolEngine;
-import org.apache.qpid.protocol.ProtocolEngineFactory;
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MinaNetworkHandler extends IoHandlerAdapter
-{
- private static final Logger LOGGER = LoggerFactory.getLogger(MinaNetworkHandler.class);
-
- private ProtocolEngineFactory _factory;
- private SSLContextFactory _sslFactory = null;
-
- static
- {
- boolean directBuffers = Boolean.getBoolean("amqj.enableDirectBuffers");
- LOGGER.debug("Using " + (directBuffers ? "direct" : "heap") + " buffers");
- ByteBuffer.setUseDirectBuffers(directBuffers);
-
- //override the MINA defaults to prevent use of the PooledByteBufferAllocator
- ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
- }
-
- public MinaNetworkHandler(SSLContextFactory sslFactory, ProtocolEngineFactory factory)
- {
- _sslFactory = sslFactory;
- _factory = factory;
- }
-
- public MinaNetworkHandler(SSLContextFactory sslFactory)
- {
- this(sslFactory, null);
- }
-
- public void messageReceived(IoSession session, Object message)
- {
- ProtocolEngine engine = (ProtocolEngine) session.getAttachment();
- ByteBuffer buf = (ByteBuffer) message;
- try
- {
- engine.received(buf.buf());
- }
- catch (RuntimeException re)
- {
- engine.exception(re);
- }
- }
-
- public void exceptionCaught(IoSession ioSession, Throwable throwable) throws Exception
- {
- ProtocolEngine engine = (ProtocolEngine) ioSession.getAttachment();
- if(engine != null)
- {
- LOGGER.error("Exception caught by Mina", throwable);
- engine.exception(throwable);
- }
- else
- {
- LOGGER.error("Exception caught by Mina but without protocol engine to handle it", throwable);
- }
- }
-
- public void sessionCreated(IoSession ioSession) throws Exception
- {
- if(LOGGER.isDebugEnabled())
- {
- LOGGER.debug("Created session: " + ioSession.getRemoteAddress());
- }
-
- SessionUtil.initialize(ioSession);
-
- if (_sslFactory != null)
- {
- ioSession.getFilterChain().addBefore("protocolFilter", "sslFilter",
- new SSLFilter(_sslFactory.buildServerContext()));
- }
-
- if (_factory != null)
- {
- NetworkConnection netConn = new MinaNetworkConnection(ioSession);
-
- ProtocolEngine engine = _factory.newProtocolEngine(netConn);
- ioSession.setAttachment(engine);
- }
- }
-
- public void sessionClosed(IoSession ioSession) throws Exception
- {
- if(LOGGER.isDebugEnabled())
- {
- LOGGER.debug("closed: " + ioSession.getRemoteAddress());
- }
-
- ProtocolEngine engine = (ProtocolEngine) ioSession.getAttachment();
- if(engine != null)
- {
- engine.closed();
- }
- else
- {
- LOGGER.error("Unable to close ProtocolEngine as none was present");
- }
- }
-
-
- public void sessionIdle(IoSession session, IdleStatus status) throws Exception
- {
- if (IdleStatus.WRITER_IDLE.equals(status))
- {
- ((ProtocolEngine) session.getAttachment()).writerIdle();
- }
- else if (IdleStatus.READER_IDLE.equals(status))
- {
- ((ProtocolEngine) session.getAttachment()).readerIdle();
- }
- }
-
-}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkTransport.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkTransport.java
deleted file mode 100644
index d0367b82f4..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkTransport.java
+++ /dev/null
@@ -1,219 +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.transport.network.mina;
-
-import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-
-import org.apache.mina.common.ConnectFuture;
-import org.apache.mina.common.ExecutorThreadModel;
-import org.apache.mina.common.IoConnector;
-import org.apache.mina.common.IoSession;
-import org.apache.mina.transport.socket.nio.SocketAcceptor;
-import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
-import org.apache.mina.transport.socket.nio.SocketConnector;
-import org.apache.mina.transport.socket.nio.SocketConnectorConfig;
-import org.apache.mina.transport.socket.nio.SocketSessionConfig;
-import org.apache.mina.util.NewThreadExecutor;
-
-import org.apache.qpid.protocol.ProtocolEngineFactory;
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.thread.QpidThreadExecutor;
-import org.apache.qpid.transport.ConnectionSettings;
-import org.apache.qpid.transport.NetworkTransportConfiguration;
-import org.apache.qpid.transport.Receiver;
-import org.apache.qpid.transport.SocketConnectorFactory;
-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.Transport;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MinaNetworkTransport implements OutgoingNetworkTransport, IncomingNetworkTransport
-{
- private static final int UNKNOWN = -1;
- private static final int TCP = 0;
-
- public NetworkConnection _connection;
- private SocketAcceptor _acceptor;
- private InetSocketAddress _address;
-
- public NetworkConnection connect(ConnectionSettings settings,
- Receiver<java.nio.ByteBuffer> delegate, SSLContextFactory sslFactory)
- {
- int transport = getTransport(settings.getProtocol());
-
- IoConnectorCreator stc;
- switch(transport)
- {
- case TCP:
- stc = new IoConnectorCreator(new SocketConnectorFactory()
- {
- public IoConnector newConnector()
- {
- return new SocketConnector(1, new QpidThreadExecutor()); // non-blocking connector
- }
- });
- _connection = stc.connect(delegate, settings, sslFactory);
- break;
- case UNKNOWN:
- default:
- throw new TransportException("Unknown protocol: " + settings.getProtocol());
- }
-
- return _connection;
- }
-
- private static int getTransport(String transport)
- {
- if (transport.equals(Transport.TCP))
- {
- return TCP;
- }
-
- return UNKNOWN;
- }
-
- public void close()
- {
- if(_connection != null)
- {
- _connection.close();
- }
- if (_acceptor != null)
- {
- _acceptor.unbindAll();
- }
- }
-
- public NetworkConnection getConnection()
- {
- return _connection;
- }
-
- public void accept(final NetworkTransportConfiguration config, final ProtocolEngineFactory factory,
- final SSLContextFactory sslFactory)
- {
- int processors = config.getConnectorProcessors();
-
- if (Transport.TCP.equalsIgnoreCase(config.getTransport()))
- {
- _acceptor = new SocketAcceptor(processors, new NewThreadExecutor());
-
- SocketAcceptorConfig sconfig = (SocketAcceptorConfig) _acceptor.getDefaultConfig();
- sconfig.setThreadModel(ExecutorThreadModel.getInstance("MinaNetworkTransport(Acceptor)"));
- SocketSessionConfig sc = (SocketSessionConfig) sconfig.getSessionConfig();
- sc.setTcpNoDelay(config.getTcpNoDelay());
- sc.setSendBufferSize(config.getSendBufferSize());
- sc.setReceiveBufferSize(config.getReceiveBufferSize());
-
- if (config.getHost().equals(WILDCARD_ADDRESS))
- {
- _address = new InetSocketAddress(config.getPort());
- }
- else
- {
- _address = new InetSocketAddress(config.getHost(), config.getPort());
- }
- }
- else
- {
- throw new TransportException("Unknown transport: " + config.getTransport());
- }
-
- try
- {
- _acceptor.bind(_address, new MinaNetworkHandler(sslFactory, factory));
- }
- catch (IOException e)
- {
- throw new TransportException("Could not bind to " + _address, e);
- }
- }
-
-
- private static class IoConnectorCreator
- {
- private static final Logger LOGGER = LoggerFactory.getLogger(IoConnectorCreator.class);
-
- private static final int CLIENT_DEFAULT_BUFFER_SIZE = 32 * 1024;
-
- private SocketConnectorFactory _ioConnectorFactory;
-
- public IoConnectorCreator(SocketConnectorFactory socketConnectorFactory)
- {
- _ioConnectorFactory = socketConnectorFactory;
- }
-
- public NetworkConnection connect(Receiver<java.nio.ByteBuffer> receiver, ConnectionSettings settings, SSLContextFactory sslFactory)
- {
- final IoConnector ioConnector = _ioConnectorFactory.newConnector();
- final SocketAddress address;
- final String protocol = settings.getProtocol();
- final int port = settings.getPort();
-
- if (Transport.TCP.equalsIgnoreCase(protocol))
- {
- address = new InetSocketAddress(settings.getHost(), port);
- }
- else
- {
- throw new TransportException("Unknown transport: " + protocol);
- }
-
- LOGGER.info("Attempting connection to " + address);
-
- if (ioConnector instanceof SocketConnector)
- {
- SocketConnectorConfig cfg = (SocketConnectorConfig) ioConnector.getDefaultConfig();
- cfg.setThreadModel(ExecutorThreadModel.getInstance("MinaNetworkTransport(Client)"));
-
- SocketSessionConfig scfg = (SocketSessionConfig) cfg.getSessionConfig();
- scfg.setTcpNoDelay(true);
- scfg.setSendBufferSize(CLIENT_DEFAULT_BUFFER_SIZE);
- scfg.setReceiveBufferSize(CLIENT_DEFAULT_BUFFER_SIZE);
-
- // Don't have the connector's worker thread wait around for other
- // connections (we only use one SocketConnector per connection
- // at the moment anyway). This allows short-running
- // clients (like unit tests) to complete quickly.
- ((SocketConnector) ioConnector).setWorkerTimeout(0);
- }
-
- ConnectFuture future = ioConnector.connect(address, new MinaNetworkHandler(sslFactory), ioConnector.getDefaultConfig());
- future.join();
- if (!future.isConnected())
- {
- throw new TransportException("Could not open connection");
- }
-
- IoSession session = future.getSession();
- session.setAttachment(receiver);
-
- return new MinaNetworkConnection(session);
- }
- }
-}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaSender.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaSender.java
index be114e2fa1..22b9c5e784 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaSender.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaSender.java
@@ -25,55 +25,66 @@ import org.apache.mina.common.CloseFuture;
import org.apache.mina.common.IoSession;
import org.apache.mina.common.WriteFuture;
import org.apache.qpid.transport.Sender;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.qpid.transport.TransportException;
+
/**
* MinaSender
*/
+
public class MinaSender implements Sender<java.nio.ByteBuffer>
{
- private static final Logger _log = LoggerFactory.getLogger(MinaSender.class);
-
- private final IoSession _session;
- private WriteFuture _lastWrite;
+ private static final int TIMEOUT = 2 * 60 * 1000;
+
+ private final IoSession session;
+ private WriteFuture lastWrite = null;
public MinaSender(IoSession session)
{
- _session = session;
+ this.session = session;
}
- public synchronized void send(java.nio.ByteBuffer msg)
+ public void send(java.nio.ByteBuffer buf)
{
- _log.debug("sending data:");
- ByteBuffer mina = ByteBuffer.allocate(msg.limit());
- mina.put(msg);
- mina.flip();
- _lastWrite = _session.write(mina);
- _log.debug("sent data:");
- }
+ if (session.isClosing())
+ {
+ throw new TransportException("attempted to write to a closed socket");
+ }
- public synchronized void flush()
- {
- if (_lastWrite != null)
+ synchronized (this)
{
- _lastWrite.join();
+ lastWrite = session.write(ByteBuffer.wrap(buf));
}
}
- public void close()
+ public void flush()
{
- // MINA will sometimes throw away in-progress writes when you ask it to close
- flush();
- CloseFuture closed = _session.close();
+ // pass
+ }
+
+ public synchronized void close()
+ {
+ // MINA will sometimes throw away in-progress writes when you
+ // ask it to close
+ synchronized (this)
+ {
+ if (lastWrite != null)
+ {
+ lastWrite.join();
+ }
+ }
+ CloseFuture closed = session.close();
closed.join();
}
public void setIdleTimeout(int i)
{
- //TODO:
- //We are instead using the setMax[Read|Write]IdleTime methods in
- //MinaNetworkConnection for this. Should remove this method from
- //sender interface, but currently being used by IoSender for 0-10.
+ //noop
}
+
+ public long getIdleTimeout()
+ {
+ return 0;
+ }
+
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioHandler.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioHandler.java
new file mode 100644
index 0000000000..84e66c25bd
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioHandler.java
@@ -0,0 +1,135 @@
+package org.apache.qpid.transport.network.nio;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.ConnectionDelegate;
+import org.apache.qpid.transport.Receiver;
+import org.apache.qpid.transport.network.Assembler;
+import org.apache.qpid.transport.network.Disassembler;
+import org.apache.qpid.transport.network.InputHandler;
+
+public class NioHandler implements Runnable
+{
+ private Receiver<ByteBuffer> _receiver;
+ private SocketChannel _ch;
+ private ByteBuffer _readBuf;
+ private static Map<Long,NioSender> _handlers = new ConcurrentHashMap<Long,NioSender>();
+
+ private NioHandler(){}
+
+ public static final Connection connect(String host, int port,
+ ConnectionDelegate delegate)
+ {
+ NioHandler handler = new NioHandler();
+ return handler.connectInternal(host,port,delegate);
+ }
+
+ private Connection connectInternal(String host, int port,
+ ConnectionDelegate delegate)
+ {
+ try
+ {
+ SocketAddress address = new InetSocketAddress(host,port);
+ _ch = SocketChannel.open();
+ _ch.socket().setReuseAddress(true);
+ _ch.configureBlocking(true);
+ _ch.socket().setTcpNoDelay(true);
+ if (address != null)
+ {
+ _ch.socket().connect(address);
+ }
+ while (_ch.isConnectionPending())
+ {
+
+ }
+
+ }
+ catch (SocketException e)
+ {
+
+ e.printStackTrace();
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+
+ NioSender sender = new NioSender(_ch);
+ Connection con = new Connection();
+ con.setSender(new Disassembler(sender, 64*1024 - 1));
+ con.setConnectionDelegate(delegate);
+
+ _handlers.put(con.getConnectionId(),sender);
+
+ _receiver = new InputHandler(new Assembler(con), InputHandler.State.FRAME_HDR);
+
+ Thread t = new Thread(this);
+ t.start();
+
+ return con;
+ }
+
+ public void run()
+ {
+ _readBuf = ByteBuffer.allocate(512);
+ long read = 0;
+ while(_ch.isConnected() && _ch.isOpen())
+ {
+ try
+ {
+ read = _ch.read(_readBuf);
+ if (read > 0)
+ {
+ _readBuf.flip();
+ ByteBuffer b = ByteBuffer.allocate(_readBuf.remaining());
+ b.put(_readBuf);
+ b.flip();
+ _readBuf.clear();
+ _receiver.received(b);
+ }
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ //throw new EOFException("The underlying socket/channel has closed");
+ }
+
+ public static void startBatchingFrames(int connectionId)
+ {
+ NioSender sender = _handlers.get(connectionId);
+ sender.setStartBatching();
+ }
+
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioSender.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioSender.java
new file mode 100644
index 0000000000..2fa875f279
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioSender.java
@@ -0,0 +1,126 @@
+package org.apache.qpid.transport.network.nio;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+
+import org.apache.qpid.transport.Sender;
+
+public class NioSender implements Sender<java.nio.ByteBuffer>
+{
+ private final Object lock = new Object();
+ private SocketChannel _ch;
+ private boolean _batch = false;
+ private ByteBuffer _batcher;
+
+ public NioSender(SocketChannel ch)
+ {
+ this._ch = ch;
+ }
+
+ public void send(java.nio.ByteBuffer buf)
+ {
+ if (_batch)
+ {
+ //System.out.println(_batcher.position() + " , " + buf.remaining() + " , " + buf.position() + ","+_batcher.capacity());
+ if (_batcher.position() + buf.remaining() >= _batcher.capacity())
+ {
+ _batcher.flip();
+ write(_batcher);
+ _batcher.clear();
+ if (buf.remaining() > _batcher.capacity())
+ {
+ write(buf);
+ }
+ else
+ {
+ _batcher.put(buf);
+ }
+ }
+ else
+ {
+ _batcher.put(buf);
+ }
+ }
+ else
+ {
+ write(buf);
+ }
+ }
+
+ public void flush()
+ {
+ // pass
+ }
+
+ private void write(java.nio.ByteBuffer buf)
+ {
+ synchronized (lock)
+ {
+ if( _ch.isConnected() && _ch.isOpen())
+ {
+ try
+ {
+ _ch.write(buf);
+ }
+ catch(Exception e)
+ {
+ e.fillInStackTrace();
+ }
+ }
+ else
+ {
+ throw new RuntimeException("Trying to write on a closed socket");
+ }
+
+ }
+ }
+
+ public void setStartBatching()
+ {
+ _batch = true;
+ _batcher = ByteBuffer.allocate(1024);
+ }
+
+ public void close()
+ {
+ // MINA will sometimes throw away in-progress writes when you
+ // ask it to close
+ synchronized (lock)
+ {
+ try
+ {
+ _ch.close();
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void setIdleTimeout(int i)
+ {
+ //noop
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/SecurityLayer.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/SecurityLayer.java
index 69e4b52edb..3f0966903d 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/SecurityLayer.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/SecurityLayer.java
@@ -43,8 +43,8 @@ public class SecurityLayer
Connection con;
SSLSecurityLayer sslLayer;
SASLSecurityLayer saslLayer;
-
- public SecurityLayer(Connection con)
+
+ public void init(Connection con) throws TransportException
{
this.con = con;
this.settings = con.getConnectionSettings();
@@ -55,9 +55,10 @@ public class SecurityLayer
if (settings.isUseSASLEncryption())
{
saslLayer = new SASLSecurityLayer();
- }
+ }
+
}
-
+
public Sender<ByteBuffer> sender(Sender<ByteBuffer> delegate)
{
Sender<ByteBuffer> sender = delegate;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/sasl/SASLSender.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/sasl/SASLSender.java
index 2d9e4e9a7e..27255f79f6 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/sasl/SASLSender.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/sasl/SASLSender.java
@@ -43,7 +43,8 @@ public class SASLSender extends SASLEncryptor implements Sender<ByteBuffer> {
this.delegate = delegate;
log.debug("SASL Sender enabled");
}
-
+
+ @Override
public void close()
{
@@ -64,11 +65,13 @@ public class SASLSender extends SASLEncryptor implements Sender<ByteBuffer> {
}
}
+ @Override
public void flush()
{
delegate.flush();
}
+ @Override
public void send(ByteBuffer buf)
{
if (closed.get())
@@ -105,6 +108,7 @@ public class SASLSender extends SASLEncryptor implements Sender<ByteBuffer> {
}
}
+ @Override
public void setIdleTimeout(int i)
{
delegate.setIdleTimeout(i);
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java
index 0dd86d4560..14f28f8828 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java
@@ -48,45 +48,51 @@ public class QpidClientX509KeyManager extends X509ExtendedKeyManager
kmf.init(ks, keyStorePassword.toCharArray());
this.delegate = (X509ExtendedKeyManager)kmf.getKeyManagers()[0];
}
-
+
+ @Override
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket)
{
log.debug("chooseClientAlias:Returning alias " + alias);
return alias;
}
+ @Override
public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket)
{
return delegate.chooseServerAlias(keyType, issuers, socket);
}
+ @Override
public X509Certificate[] getCertificateChain(String alias)
{
return delegate.getCertificateChain(alias);
}
+ @Override
public String[] getClientAliases(String keyType, Principal[] issuers)
{
log.debug("getClientAliases:Returning alias " + alias);
return new String[]{alias};
}
+ @Override
public PrivateKey getPrivateKey(String alias)
{
return delegate.getPrivateKey(alias);
}
+ @Override
public String[] getServerAliases(String keyType, Principal[] issuers)
{
return delegate.getServerAliases(keyType, issuers);
}
-
+
public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine)
{
log.debug("chooseEngineClientAlias:Returning alias " + alias);
return alias;
}
-
+
public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine)
{
return delegate.chooseEngineServerAlias(keyType, issuers, engine);
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java b/qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java
index e261860bf3..6f21c327e7 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java
@@ -31,6 +31,9 @@ public class URLHelper
public static void parseOptions(Map<String, String> optionMap, String options) throws URLSyntaxException
{
+ // options looks like this
+ // brokerlist='tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value'',failover='method?option='value',option='value''
+
if ((options == null) || (options.indexOf('=') == -1))
{
return;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java b/qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java
index ac8e3da3c2..516204fbd3 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java
@@ -143,9 +143,8 @@ public class FileUtils
}
/**
- * Either opens the specified filename as an input stream or either the filesystem or classpath,
- * or uses the default resource loaded using the specified class loader, if opening the file fails
- * or no file name is specified.
+ * Either opens the specified filename as an input stream, or uses the default resource loaded using the
+ * specified class loader, if opening the file fails or no file name is specified.
*
* @param filename The name of the file to open.
* @param defaultResource The name of the default resource on the classpath if the file cannot be opened.
@@ -157,28 +156,28 @@ public class FileUtils
{
InputStream is = null;
+ // Flag to indicate whether the default resource should be used. By default this is true, so that the default
+ // is used when opening the file fails.
+ boolean useDefault = true;
+
// Try to open the file if one was specified.
if (filename != null)
{
- // try on filesystem
try
{
is = new BufferedInputStream(new FileInputStream(new File(filename)));
+
+ // Clear the default flag because the file was succesfully opened.
+ useDefault = false;
}
catch (FileNotFoundException e)
{
- is = null;
- }
-
- if (is == null)
- {
- // failed on filesystem, so try on classpath
- is = cl.getResourceAsStream(filename);
+ // Ignore this exception, the default will be used instead.
}
}
// Load the default resource if a file was not specified, or if opening the file failed.
- if (is == null)
+ if (useDefault)
{
is = cl.getResourceAsStream(defaultResource);
}
@@ -340,7 +339,7 @@ public class FileUtils
}
//else we have a source directory
- if (!dst.isDirectory() && !dst.mkdirs())
+ if (!dst.isDirectory() && !dst.mkdir())
{
throw new UnableToCopyException("Unable to create destination directory");
}
diff --git a/qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterClient.java b/qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterClient.java
new file mode 100644
index 0000000000..b93dc46741
--- /dev/null
+++ b/qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterClient.java
@@ -0,0 +1,396 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.mina.SocketIOTest;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.CloseFuture;
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.SimpleByteBufferAllocator;
+import org.apache.mina.filter.ReadThrottleFilterBuilder;
+import org.apache.mina.filter.WriteBufferLimitFilterBuilder;
+import org.apache.mina.transport.socket.nio.SocketSessionConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.concurrent.CountDownLatch;
+
+public class IOWriterClient implements Runnable
+{
+ private static final Logger _logger = LoggerFactory.getLogger(IOWriterClient.class);
+
+ public static int DEFAULT_TEST_SIZE = 2;
+
+ private IoSession _session;
+
+ private long _startTime;
+
+ private long[] _chunkTimes;
+
+ public int _chunkCount = 200000;
+
+ private int _chunkSize = 1024;
+
+ private CountDownLatch _notifier;
+
+ private int _maximumWriteQueueLength;
+
+ static public int _PORT = IOWriterServer._PORT;
+
+ public void run()
+ {
+ _logger.info("Starting to send " + _chunkCount + " buffers of " + _chunkSize + "B");
+ _startTime = System.currentTimeMillis();
+ _notifier = new CountDownLatch(1);
+
+ for (int i = 0; i < _chunkCount; i++)
+ {
+ ByteBuffer buf = ByteBuffer.allocate(_chunkSize, false);
+ byte check = (byte) (i % 128);
+ buf.put(check);
+ buf.fill((byte) 88, buf.remaining());
+ buf.flip();
+
+ _session.write(buf);
+ }
+
+ long _sentall = System.currentTimeMillis();
+ long _receivedall = _sentall;
+ try
+ {
+ _logger.info("All buffers sent; waiting for receipt from server");
+ _notifier.await();
+ _receivedall = System.currentTimeMillis();
+ }
+ catch (InterruptedException e)
+ {
+ //Ignore
+ }
+ _logger.info("Completed");
+ _logger.info("Total time waiting for server after last write: " + (_receivedall - _sentall));
+
+ long totalTime = System.currentTimeMillis() - _startTime;
+
+ _logger.info("Total time: " + totalTime);
+ _logger.info("MB per second: " + (int) ((1.0 * _chunkSize * _chunkCount) / totalTime));
+ long lastChunkTime = _startTime;
+ double average = 0;
+ for (int i = 0; i < _chunkTimes.length; i++)
+ {
+ if (i == 0)
+ {
+ average = _chunkTimes[i] - _startTime;
+ }
+ else
+ {
+ long delta = _chunkTimes[i] - lastChunkTime;
+ if (delta != 0)
+ {
+ average = (average + delta) / 2;
+ }
+ }
+ lastChunkTime = _chunkTimes[i];
+ }
+ _logger.info("Average chunk time: " + average + "ms");
+ _logger.info("Maximum WriteRequestQueue size: " + _maximumWriteQueueLength);
+
+ CloseFuture cf = _session.close();
+ _logger.info("Closing session");
+ cf.join();
+ }
+
+ private class WriterHandler extends IoHandlerAdapter
+ {
+ private int _chunksReceived = 0;
+
+ private int _partialBytesRead = 0;
+
+ private byte _partialCheckNumber;
+
+ private int _totalBytesReceived = 0;
+
+ private int _receivedCount = 0;
+ private int _sentCount = 0;
+ private static final String DEFAULT_READ_BUFFER = "262144";
+ private static final String DEFAULT_WRITE_BUFFER = "262144";
+
+ public void sessionCreated(IoSession session) throws Exception
+ {
+ IoFilterChain chain = session.getFilterChain();
+
+ ReadThrottleFilterBuilder readfilter = new ReadThrottleFilterBuilder();
+ readfilter.setMaximumConnectionBufferSize(Integer.parseInt(System.getProperty("qpid.read.buffer.limit", DEFAULT_READ_BUFFER)));
+ readfilter.attach(chain);
+
+ WriteBufferLimitFilterBuilder writefilter = new WriteBufferLimitFilterBuilder();
+
+ writefilter.setMaximumConnectionBufferSize(Integer.parseInt(System.getProperty("qpid.write.buffer.limit", DEFAULT_WRITE_BUFFER)));
+
+ writefilter.attach(chain);
+ }
+
+ public void messageSent(IoSession session, Object message) throws Exception
+ {
+ _maximumWriteQueueLength = Math.max(session.getScheduledWriteRequests(), _maximumWriteQueueLength);
+
+ if (_logger.isDebugEnabled())
+ {
+ ++_sentCount;
+ if (_sentCount % 1000 == 0)
+ {
+ _logger.debug("Sent count " + _sentCount + ":WQueue" + session.getScheduledWriteRequests());
+
+ }
+ }
+ }
+
+ public void messageReceived(IoSession session, Object message) throws Exception
+ {
+ if (_logger.isDebugEnabled())
+ {
+ ++_receivedCount;
+
+ if (_receivedCount % 1000 == 0)
+ {
+ _logger.debug("Receieved count " + _receivedCount);
+ }
+ }
+
+ ByteBuffer result = (ByteBuffer) message;
+ _totalBytesReceived += result.remaining();
+ int size = result.remaining();
+ long now = System.currentTimeMillis();
+ if (_partialBytesRead > 0)
+ {
+ int offset = _chunkSize - _partialBytesRead;
+ if (size >= offset)
+ {
+ _chunkTimes[_chunksReceived++] = now;
+ result.position(offset);
+ }
+ else
+ {
+ // have not read even one chunk, including the previous partial bytes
+ _partialBytesRead += size;
+ return;
+ }
+ }
+
+
+ int chunkCount = result.remaining() / _chunkSize;
+
+ for (int i = 0; i < chunkCount; i++)
+ {
+ _chunkTimes[_chunksReceived++] = now;
+ byte check = result.get();
+ _logger.debug("Check number " + check + " read");
+ if (check != (byte) ((_chunksReceived - 1) % 128))
+ {
+ _logger.error("Check number " + check + " read when expected " + (_chunksReceived % 128));
+ }
+ _logger.debug("Chunk times recorded");
+
+ try
+ {
+ result.skip(_chunkSize - 1);
+ }
+ catch (IllegalArgumentException e)
+ {
+ _logger.error("Position was: " + result.position());
+ _logger.error("Tried to skip to: " + (_chunkSize * i));
+ _logger.error("limit was; " + result.limit());
+ }
+ }
+ _logger.debug("Chunks received now " + _chunksReceived);
+ _logger.debug("Bytes received: " + _totalBytesReceived);
+ _partialBytesRead = result.remaining();
+
+ if (_partialBytesRead > 0)
+ {
+ _partialCheckNumber = result.get();
+ }
+
+
+ if (_chunksReceived >= _chunkCount)
+ {
+ _notifier.countDown();
+ }
+
+ }
+
+ public void exceptionCaught(IoSession session, Throwable cause) throws Exception
+ {
+ _logger.error("Error: " + cause, cause);
+ }
+ }
+
+ public void startWriter() throws IOException, InterruptedException
+ {
+
+ _maximumWriteQueueLength = 0;
+
+ IoConnector ioConnector = null;
+
+ if (Boolean.getBoolean("multinio"))
+ {
+ _logger.warn("Using MultiThread NIO");
+ ioConnector = new org.apache.mina.transport.socket.nio.MultiThreadSocketConnector();
+ }
+ else
+ {
+ _logger.warn("Using MINA NIO");
+ ioConnector = new org.apache.mina.transport.socket.nio.SocketConnector();
+ }
+
+ SocketSessionConfig scfg = (SocketSessionConfig) ioConnector.getDefaultConfig().getSessionConfig();
+ scfg.setTcpNoDelay(true);
+ scfg.setSendBufferSize(32768);
+ scfg.setReceiveBufferSize(32768);
+
+ ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
+
+
+ final InetSocketAddress address = new InetSocketAddress("localhost", _PORT);
+ _logger.info("Attempting connection to " + address);
+
+ //Old mina style
+// ioConnector.setHandler(new WriterHandler());
+// ConnectFuture future = ioConnector.connect(address);
+ ConnectFuture future = ioConnector.connect(address, new WriterHandler());
+ // wait for connection to complete
+ future.join();
+ _logger.info("Connection completed");
+ // we call getSession which throws an IOException if there has been an error connecting
+ _session = future.getSession();
+
+ _chunkTimes = new long[_chunkCount];
+ Thread t = new Thread(this);
+ t.start();
+ t.join();
+ _logger.info("Test Complete");
+ }
+
+
+ public void test1k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 1k test");
+ _chunkSize = 1024;
+ startWriter();
+ }
+
+
+ public void test2k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 2k test");
+ _chunkSize = 2048;
+ startWriter();
+ }
+
+
+ public void test4k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 4k test");
+ _chunkSize = 4096;
+ startWriter();
+ }
+
+
+ public void test8k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 8k test");
+ _chunkSize = 8192;
+ startWriter();
+ }
+
+
+ public void test16k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 16k test");
+ _chunkSize = 16384;
+ startWriter();
+ }
+
+
+ public void test32k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 32k test");
+ _chunkSize = 32768;
+ startWriter();
+ }
+
+
+ public static int getIntArg(String[] args, int index, int defaultValue)
+ {
+ if (args.length > index)
+ {
+ try
+ {
+ return Integer.parseInt(args[index]);
+ }
+ catch (NumberFormatException e)
+ {
+ //Do nothing
+ }
+ }
+ return defaultValue;
+ }
+
+ public static void main(String[] args) throws IOException, InterruptedException
+ {
+ _PORT = getIntArg(args, 0, _PORT);
+
+ int test = getIntArg(args, 1, DEFAULT_TEST_SIZE);
+
+ IOWriterClient w = new IOWriterClient();
+ w._chunkCount = getIntArg(args, 2, w._chunkCount);
+ switch (test)
+ {
+ case 0:
+ w.test1k();
+ w.test2k();
+ w.test4k();
+ w.test8k();
+ w.test16k();
+ w.test32k();
+ break;
+ case 1:
+ w.test1k();
+ break;
+ case 2:
+ w.test2k();
+ break;
+ case 4:
+ w.test4k();
+ break;
+ case 8:
+ w.test8k();
+ break;
+ case 16:
+ w.test16k();
+ break;
+ case 32:
+ w.test32k();
+ break;
+ }
+ }
+}
diff --git a/qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterServer.java b/qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterServer.java
new file mode 100644
index 0000000000..423e98c67b
--- /dev/null
+++ b/qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterServer.java
@@ -0,0 +1,157 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.mina.SocketIOTest;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoAcceptor;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.SimpleByteBufferAllocator;
+import org.apache.mina.filter.ReadThrottleFilterBuilder;
+import org.apache.mina.filter.WriteBufferLimitFilterBuilder;
+import org.apache.mina.transport.socket.nio.SocketSessionConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+
+/** Tests MINA socket performance. This acceptor simply reads data from the network and writes it back again. */
+public class IOWriterServer
+{
+ private static final Logger _logger = LoggerFactory.getLogger(IOWriterServer.class);
+
+ static public int _PORT = 9999;
+
+ private static final String DEFAULT_READ_BUFFER = "262144";
+ private static final String DEFAULT_WRITE_BUFFER = "262144";
+
+
+ private static class TestHandler extends IoHandlerAdapter
+ {
+ private int _sentCount = 0;
+
+ private int _bytesSent = 0;
+
+ private int _receivedCount = 0;
+
+ public void sessionCreated(IoSession ioSession) throws java.lang.Exception
+ {
+ IoFilterChain chain = ioSession.getFilterChain();
+
+ ReadThrottleFilterBuilder readfilter = new ReadThrottleFilterBuilder();
+ readfilter.setMaximumConnectionBufferSize(Integer.parseInt(System.getProperty("qpid.read.buffer.limit", DEFAULT_READ_BUFFER)));
+ readfilter.attach(chain);
+
+ WriteBufferLimitFilterBuilder writefilter = new WriteBufferLimitFilterBuilder();
+
+ writefilter.setMaximumConnectionBufferSize(Integer.parseInt(System.getProperty("qpid.write.buffer.limit", DEFAULT_WRITE_BUFFER)));
+
+ writefilter.attach(chain);
+
+ }
+
+ public void messageReceived(IoSession session, Object message) throws Exception
+ {
+ ((ByteBuffer) message).acquire();
+ session.write(message);
+
+ if (_logger.isDebugEnabled())
+ {
+ _bytesSent += ((ByteBuffer) message).remaining();
+
+ _sentCount++;
+
+ if (_sentCount % 1000 == 0)
+ {
+ _logger.debug("Bytes sent: " + _bytesSent);
+ }
+ }
+ }
+
+ public void messageSent(IoSession session, Object message) throws Exception
+ {
+ if (_logger.isDebugEnabled())
+ {
+ ++_receivedCount;
+
+ if (_receivedCount % 1000 == 0)
+ {
+ _logger.debug("Receieved count " + _receivedCount);
+ }
+ }
+ }
+
+ public void exceptionCaught(IoSession session, Throwable cause) throws Exception
+ {
+ _logger.error("Error: " + cause, cause);
+ }
+ }
+
+ public void startAcceptor() throws IOException
+ {
+ IoAcceptor acceptor;
+ if (Boolean.getBoolean("multinio"))
+ {
+ _logger.warn("Using MultiThread NIO");
+ acceptor = new org.apache.mina.transport.socket.nio.MultiThreadSocketAcceptor();
+ }
+ else
+ {
+ _logger.warn("Using MINA NIO");
+ acceptor = new org.apache.mina.transport.socket.nio.SocketAcceptor();
+ }
+
+
+ SocketSessionConfig sc = (SocketSessionConfig) acceptor.getDefaultConfig().getSessionConfig();
+ sc.setTcpNoDelay(true);
+ sc.setSendBufferSize(32768);
+ sc.setReceiveBufferSize(32768);
+
+ ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
+
+ //The old mina style
+// acceptor.setLocalAddress(new InetSocketAddress(_PORT));
+// acceptor.setHandler(new TestHandler());
+// acceptor.bind();
+ acceptor.bind(new InetSocketAddress(_PORT), new TestHandler());
+
+ _logger.info("Bound on port " + _PORT + ":" + _logger.isDebugEnabled());
+ _logger.debug("debug on");
+ }
+
+ public static void main(String[] args) throws IOException
+ {
+
+ if (args.length > 0)
+ {
+ try
+ {
+ _PORT = Integer.parseInt(args[0]);
+ }
+ catch (NumberFormatException e)
+ {
+ //IGNORE so use default port 9999;
+ }
+ }
+
+ IOWriterServer a = new IOWriterServer();
+ a.startAcceptor();
+ }
+}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java b/qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java
index f65427e583..ef6cd41492 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java
@@ -23,7 +23,6 @@ package org.apache.qpid;
import junit.framework.TestCase;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.framing.AMQFrameDecodingException;
-import org.apache.qpid.framing.AMQShortString;
/**
* This test is to ensure that when an AMQException is rethrown that the specified exception is correctly wrapped up.
@@ -92,18 +91,6 @@ public class AMQExceptionTest extends TestCase
return amqe;
}
- public void testGetMessageAsString()
- {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < 25; i++)
- {
- sb.append("message [" + i + "]");
- }
- AMQException e = new AMQException(AMQConstant.INTERNAL_ERROR, sb.toString(), null);
- AMQShortString message = e.getMessageAsShortString();
- assertEquals(sb.substring(0, AMQShortString.MAX_LENGTH - 3) + "...", message.toString());
- }
-
/**
* Private class that extends AMQException but does not have a default exception.
*/
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java b/qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java
index 9a805d87b3..92e7ce0a80 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java
@@ -20,10 +20,6 @@
package org.apache.qpid.framing;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-
import junit.framework.TestCase;
public class AMQShortStringTest extends TestCase
{
@@ -109,215 +105,5 @@ public class AMQShortStringTest extends TestCase
assertFalse(new AMQShortString("A").equals(new AMQShortString("a")));
}
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(byte[])}.
- */
- public void testCreateAMQShortStringByteArray()
- {
- byte[] bytes = null;
- try
- {
- bytes = "test".getBytes("UTF-8");
- }
- catch (UnsupportedEncodingException e)
- {
- fail("UTF-8 encoding is not supported anymore by JVM:" + e.getMessage());
- }
- AMQShortString string = new AMQShortString(bytes);
- assertEquals("constructed amq short string length differs from expected", 4, string.length());
- assertTrue("constructed amq short string differs from expected", string.equals("test"));
- }
-
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(java.lang.String)}
- * <p>
- * Tests short string construction from string with length less than 255.
- */
- public void testCreateAMQShortStringString()
- {
- AMQShortString string = new AMQShortString("test");
- assertEquals("constructed amq short string length differs from expected", 4, string.length());
- assertTrue("constructed amq short string differs from expected", string.equals("test"));
- }
-
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(char[])}.
- * <p>
- * Tests short string construction from char array with length less than 255.
- */
- public void testCreateAMQShortStringCharArray()
- {
- char[] chars = "test".toCharArray();
- AMQShortString string = new AMQShortString(chars);
- assertEquals("constructed amq short string length differs from expected", 4, string.length());
- assertTrue("constructed amq short string differs from expected", string.equals("test"));
- }
-
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(java.lang.CharSequence)}
- * <p>
- * Tests short string construction from char sequence with length less than 255.
- */
- public void testCreateAMQShortStringCharSequence()
- {
- AMQShortString string = new AMQShortString((CharSequence) "test");
- assertEquals("constructed amq short string length differs from expected", 4, string.length());
- assertTrue("constructed amq short string differs from expected", string.equals("test"));
- }
-
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(byte[])}.
- * <p>
- * Tests an attempt to create an AMQP short string from byte array with length over 255.
- */
- public void testCreateAMQShortStringByteArrayOver255()
- {
- String test = buildString('a', 256);
- byte[] bytes = null;
- try
- {
- bytes = test.getBytes("UTF-8");
- }
- catch (UnsupportedEncodingException e)
- {
- fail("UTF-8 encoding is not supported anymore by JVM:" + e.getMessage());
- }
- try
- {
- new AMQShortString(bytes);
- fail("It should not be possible to create AMQShortString with length over 255");
- }
- catch (IllegalArgumentException e)
- {
- assertEquals("Exception message differs from expected",
- "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
- }
- }
-
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(java.lang.String)}
- * <p>
- * Tests an attempt to create an AMQP short string from string with length over 255
- */
- public void testCreateAMQShortStringStringOver255()
- {
- String test = buildString('a', 256);
- try
- {
- new AMQShortString(test);
- fail("It should not be possible to create AMQShortString with length over 255");
- }
- catch (IllegalArgumentException e)
- {
- assertEquals("Exception message differs from expected",
- "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
- }
- }
-
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(char[])}.
- * <p>
- * Tests an attempt to create an AMQP short string from char array with length over 255.
- */
- public void testCreateAMQShortStringCharArrayOver255()
- {
- String test = buildString('a', 256);
- char[] chars = test.toCharArray();
- try
- {
- new AMQShortString(chars);
- fail("It should not be possible to create AMQShortString with length over 255");
- }
- catch (IllegalArgumentException e)
- {
- assertEquals("Exception message differs from expected",
- "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
- }
- }
-
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(java.lang.CharSequence)}
- * <p>
- * Tests an attempt to create an AMQP short string from char sequence with length over 255.
- */
- public void testCreateAMQShortStringCharSequenceOver255()
- {
- String test = buildString('a', 256);
- try
- {
- new AMQShortString((CharSequence) test);
- fail("It should not be possible to create AMQShortString with length over 255");
- }
- catch (IllegalArgumentException e)
- {
- assertEquals("Exception message differs from expected",
- "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
- }
- }
-
- /**
- * Tests joining of short strings into a short string with length over 255.
- */
- public void testJoinOverflow()
- {
- List<AMQShortString> data = new ArrayList<AMQShortString>();
- for (int i = 0; i < 25; i++)
- {
- data.add(new AMQShortString("test data!"));
- }
- try
- {
- AMQShortString.join(data, new AMQShortString(" "));
- fail("It should not be possible to create AMQShortString with length over 255");
- }
- catch (IllegalArgumentException e)
- {
- assertEquals("Exception message differs from expected",
- "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
- }
- }
-
- /**
- * Tests joining of short strings into a short string with length less than 255.
- */
- public void testJoin()
- {
- StringBuilder expected = new StringBuilder();
- List<AMQShortString> data = new ArrayList<AMQShortString>();
- data.add(new AMQShortString("test data 1"));
- expected.append("test data 1");
- data.add(new AMQShortString("test data 2"));
- expected.append(" test data 2");
- AMQShortString result = AMQShortString.join(data, new AMQShortString(" "));
- assertEquals("join result differs from expected", expected.toString(), result.asString());
- }
-
- /**
- * A helper method to generate a string with given length containing given
- * character
- *
- * @param ch
- * char to build string with
- * @param length
- * target string length
- * @return string
- */
- private String buildString(char ch, int length)
- {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < length; i++)
- {
- sb.append(ch);
- }
- return sb.toString();
- }
}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java b/qpid/java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java
index 89542e8125..8b470d555e 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java
@@ -25,22 +25,17 @@ import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import junit.framework.TestCase;
import junit.framework.TestResult;
import org.apache.log4j.Logger;
-import org.apache.mina.util.AvailablePortFinder;
public class QpidTestCase extends TestCase
{
protected static final Logger _logger = Logger.getLogger(QpidTestCase.class);
- private final Map<String, String> _propertiesSetForTest = new HashMap<String, String>();
-
/**
* Some tests are excluded when the property test.excludes is set to true.
* An exclusion list is either a file (prop test.excludesfile) which contains one test name
@@ -132,54 +127,4 @@ public class QpidTestCase extends TestCase
return storeClass != null ? storeClass : MEMORY_STORE_CLASS_NAME ;
}
-
- public int findFreePort()
- {
- return AvailablePortFinder.getNextAvailable(10000);
- }
-
- /**
- * Set a System property for duration of this test only. The tearDown will
- * guarantee to reset the property to its previous value after the test
- * completes.
- *
- * @param property The property to set
- * @param value the value to set it to.
- */
- protected void setTestSystemProperty(String property, String value)
- {
- if (!_propertiesSetForTest.containsKey(property))
- {
- // Record the current value so we can revert it later.
- _propertiesSetForTest.put(property, System.getProperty(property));
- }
-
- System.setProperty(property, value);
- }
-
- /**
- * Restore the System property values that were set by this test run.
- */
- protected void revertTestSystemProperties()
- {
- for (String key : _propertiesSetForTest.keySet())
- {
- String value = _propertiesSetForTest.get(key);
- if (value != null)
- {
- System.setProperty(key, value);
- }
- else
- {
- System.clearProperty(key);
- }
- }
-
- _propertiesSetForTest.clear();
- }
-
- protected void tearDown() throws java.lang.Exception
- {
- revertTestSystemProperties();
- }
}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/TestNetworkConnection.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/TestNetworkDriver.java
index 8686c17414..957a7190ee 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/TestNetworkConnection.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/transport/TestNetworkDriver.java
@@ -25,32 +25,32 @@ import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.protocol.ProtocolEngineFactory;
import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.transport.network.NetworkConnection;
/**
* Test implementation of IoSession, which is required for some tests. Methods not being used are not implemented,
* so if this class is being used and some methods are to be used, then please update those.
*/
-public class TestNetworkConnection implements NetworkConnection
+public class TestNetworkDriver implements NetworkDriver
{
+ private final ConcurrentMap attributes = new ConcurrentHashMap();
private String _remoteHost = "127.0.0.1";
private String _localHost = "127.0.0.1";
private int _port = 1;
private SocketAddress _localAddress = null;
private SocketAddress _remoteAddress = null;
- private final MockSender _sender;
- public TestNetworkConnection()
+ public TestNetworkDriver()
{
- _sender = new MockSender();
}
public void bind(int port, InetAddress[] addresses, ProtocolEngineFactory protocolFactory,
- NetworkTransportConfiguration config, SSLContextFactory sslFactory) throws BindException
+ NetworkDriverConfiguration config, SSLContextFactory sslFactory) throws BindException
{
}
@@ -65,7 +65,7 @@ public class TestNetworkConnection implements NetworkConnection
return (_remoteAddress != null) ? _remoteAddress : new InetSocketAddress(_remoteHost, _port);
}
- public void open(int port, InetAddress destination, ProtocolEngine engine, NetworkTransportConfiguration config,
+ public void open(int port, InetAddress destination, ProtocolEngine engine, NetworkDriverConfiguration config,
SSLContextFactory sslFactory) throws OpenException
{
@@ -130,9 +130,4 @@ public class TestNetworkConnection implements NetworkConnection
{
_remoteAddress = address;
}
-
- public Sender<ByteBuffer> getSender()
- {
- return _sender;
- }
}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/TransportTest.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/network/TransportTest.java
deleted file mode 100644
index 4e504c69eb..0000000000
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/TransportTest.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.transport.network;
-
-
-import java.nio.ByteBuffer;
-
-import org.apache.qpid.framing.ProtocolVersion;
-import org.apache.qpid.protocol.ProtocolEngineFactory;
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.test.utils.QpidTestCase;
-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.io.IoNetworkTransport;
-import org.apache.qpid.transport.network.mina.MinaNetworkTransport;
-
-public class TransportTest extends QpidTestCase
-{
-
-
-
- public void testDefaultGetOutgoingTransportForv0_8() throws Exception
- {
- final OutgoingNetworkTransport networkTransport = Transport.getOutgoingTransportInstance(ProtocolVersion.v8_0);
- assertNotNull(networkTransport);
- assertTrue(networkTransport instanceof MinaNetworkTransport);
- }
-
- public void testGloballyOverriddenOutgoingTransportForv0_8() throws Exception
- {
- setTestSystemProperty(Transport.QPID_TRANSPORT_PROPNAME, TestOutgoingNetworkTransport.class.getName());
-
- final OutgoingNetworkTransport networkTransport = Transport.getOutgoingTransportInstance(ProtocolVersion.v8_0);
- assertNotNull(networkTransport);
- assertTrue(networkTransport instanceof TestOutgoingNetworkTransport);
- }
-
- public void testProtocolSpecificOverriddenOutgoingTransportForv0_8() throws Exception
- {
- setTestSystemProperty(Transport.QPID_TRANSPORT_V0_8_PROPNAME, TestOutgoingNetworkTransport.class.getName());
-
- final OutgoingNetworkTransport networkTransport = Transport.getOutgoingTransportInstance(ProtocolVersion.v8_0);
- assertNotNull(networkTransport);
- assertTrue(networkTransport instanceof TestOutgoingNetworkTransport);
- }
-
- public void testDefaultGetOutgoingTransportForv0_10() throws Exception
- {
- final OutgoingNetworkTransport networkTransport = Transport.getOutgoingTransportInstance(ProtocolVersion.v0_10);
- assertNotNull(networkTransport);
- assertTrue(networkTransport instanceof IoNetworkTransport);
- }
-
- public void testDefaultGetIncomingTransport() throws Exception
- {
- final IncomingNetworkTransport networkTransport = Transport.getIncomingTransportInstance();
- assertNotNull(networkTransport);
- assertTrue(networkTransport instanceof MinaNetworkTransport);
- }
-
- public void testOverriddenGetIncomingTransport() throws Exception
- {
- setTestSystemProperty(Transport.QPID_BROKER_TRANSPORT_PROPNAME, TestIncomingNetworkTransport.class.getName());
-
- final IncomingNetworkTransport networkTransport = Transport.getIncomingTransportInstance();
- assertNotNull(networkTransport);
- assertTrue(networkTransport instanceof TestIncomingNetworkTransport);
- }
-
- public void testInvalidOutgoingTransportClassName() throws Exception
- {
- setTestSystemProperty(Transport.QPID_TRANSPORT_PROPNAME, "invalid");
-
- try
- {
- Transport.getOutgoingTransportInstance(ProtocolVersion.v0_10);
- fail("Should have failed to load the invalid class");
- }
- catch(TransportException te)
- {
- //expected, ignore
- }
- }
-
- public void testInvalidOutgoingTransportProtocolVersion() throws Exception
- {
- try
- {
- Transport.getOutgoingTransportInstance(new ProtocolVersion((byte)0, (byte)0));
- fail("Should have failed to load the transport for invalid protocol version");
- }
- catch(IllegalArgumentException iae)
- {
- //expected, ignore
- }
- }
-
- public static class TestOutgoingNetworkTransport implements OutgoingNetworkTransport
- {
-
- public void close()
- {
- throw new UnsupportedOperationException();
- }
-
- public NetworkConnection getConnection()
- {
- throw new UnsupportedOperationException();
- }
-
- public NetworkConnection connect(ConnectionSettings settings,
- Receiver<ByteBuffer> delegate, SSLContextFactory sslFactory)
- {
- throw new UnsupportedOperationException();
- }
- }
-
- public static class TestIncomingNetworkTransport implements IncomingNetworkTransport
- {
-
- public void close()
- {
- throw new UnsupportedOperationException();
- }
-
- public NetworkConnection getConnection()
- {
- throw new UnsupportedOperationException();
- }
-
- public void accept(NetworkTransportConfiguration config,
- ProtocolEngineFactory factory, SSLContextFactory sslFactory)
- {
- throw new UnsupportedOperationException();
- }
- }
-}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IoTransport.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IoTransport.java
deleted file mode 100644
index 796a845593..0000000000
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IoTransport.java
+++ /dev/null
@@ -1,165 +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.transport.network.io;
-
-import java.net.Socket;
-import java.nio.ByteBuffer;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.transport.Binding;
-import org.apache.qpid.transport.Sender;
-import org.apache.qpid.transport.TransportException;
-import org.apache.qpid.transport.network.security.ssl.SSLReceiver;
-import org.apache.qpid.transport.network.security.ssl.SSLSender;
-import org.apache.qpid.transport.util.Logger;
-
-/**
- * This class provides a socket based transport using the java.io
- * classes.
- *
- * The following params are configurable via JVM arguments
- * TCP_NO_DELAY - amqj.tcpNoDelay
- * SO_RCVBUF - amqj.receiveBufferSize
- * SO_SNDBUF - amqj.sendBufferSize
- */
-public final class IoTransport<E>
-{
-
- static
- {
- org.apache.mina.common.ByteBuffer.setAllocator
- (new org.apache.mina.common.SimpleByteBufferAllocator());
- org.apache.mina.common.ByteBuffer.setUseDirectBuffers
- (Boolean.getBoolean("amqj.enableDirectBuffers"));
- }
-
- private static final Logger log = Logger.get(IoTransport.class);
-
- private static int DEFAULT_READ_WRITE_BUFFER_SIZE = 64 * 1024;
- private static int readBufferSize = Integer.getInteger
- ("amqj.receiveBufferSize", DEFAULT_READ_WRITE_BUFFER_SIZE);
- private static int writeBufferSize = Integer.getInteger
- ("amqj.sendBufferSize", DEFAULT_READ_WRITE_BUFFER_SIZE);
-
- private Socket socket;
- private Sender<ByteBuffer> sender;
- private E endpoint;
- private IoReceiver receiver;
- private long timeout = 60000;
-
- IoTransport(Socket socket, Binding<E,ByteBuffer> binding, boolean ssl)
- {
- this.socket = socket;
-
- if (ssl)
- {
- setupSSLTransport(socket, binding);
- }
- else
- {
- setupTransport(socket, binding);
- }
- }
-
- private void setupTransport(Socket socket, Binding<E, ByteBuffer> binding)
- {
- IoSender ios = new IoSender(socket, 2*writeBufferSize, timeout);
- ios.initiate();
-
- this.sender = ios;
- this.endpoint = binding.endpoint(sender);
- this.receiver = new IoReceiver(socket, binding.receiver(endpoint),
- 2*readBufferSize, timeout);
- this.receiver.initiate();
-
- ios.registerCloseListener(this.receiver);
- }
-
- private void setupSSLTransport(Socket socket, Binding<E, ByteBuffer> binding)
- {
- SSLEngine engine = null;
- SSLContext sslCtx;
- try
- {
- sslCtx = createSSLContext();
- }
- catch (Exception e)
- {
- throw new TransportException("Error creating SSL Context", e);
- }
-
- try
- {
- engine = sslCtx.createSSLEngine();
- engine.setUseClientMode(true);
- }
- catch(Exception e)
- {
- throw new TransportException("Error creating SSL Engine", e);
- }
- IoSender ios = new IoSender(socket, 2*writeBufferSize, timeout);
- ios.initiate();
- this.sender = new SSLSender(engine,ios);
- this.endpoint = binding.endpoint(sender);
- this.receiver = new IoReceiver(socket, new SSLReceiver(engine,binding.receiver(endpoint),(SSLSender)sender),
- 2*readBufferSize, timeout);
- this.receiver.initiate();
- ios.registerCloseListener(this.receiver);
-
- log.info("SSL Sender and Receiver initiated");
- }
-
- public Sender<ByteBuffer> getSender()
- {
- return sender;
- }
-
- public IoReceiver getReceiver()
- {
- return receiver;
- }
-
- public Socket getSocket()
- {
- return socket;
- }
-
- private SSLContext createSSLContext() throws Exception
- {
- String trustStorePath = System.getProperty("javax.net.ssl.trustStore");
- String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
- String trustStoreCertType = System.getProperty("qpid.ssl.trustStoreCertType","SunX509");
-
- String keyStorePath = System.getProperty("javax.net.ssl.keyStore",trustStorePath);
- String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword",trustStorePassword);
- String keyStoreCertType = System.getProperty("qpid.ssl.keyStoreCertType","SunX509");
-
- SSLContextFactory sslContextFactory = new SSLContextFactory(trustStorePath,trustStorePassword,
- trustStoreCertType,keyStorePath,
- keyStorePassword,keyStoreCertType);
-
- return sslContextFactory.buildServerContext();
-
- }
-
-}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/mina/MinaNetworkHandlerTest.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/network/mina/MINANetworkDriverTest.java
index 1a1b5af805..fc8e689ca4 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/mina/MinaNetworkHandlerTest.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/transport/network/mina/MINANetworkDriverTest.java
@@ -21,57 +21,44 @@
package org.apache.qpid.transport.network.mina;
-import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-
+import java.net.BindException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
+import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import junit.framework.TestCase;
+
import org.apache.qpid.framing.AMQDataBlock;
import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.protocol.ProtocolEngineFactory;
-import org.apache.qpid.test.utils.QpidTestCase;
-import org.apache.qpid.transport.ConnectionSettings;
-import org.apache.qpid.transport.NetworkTransportConfiguration;
-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.Transport;
-
-public class MinaNetworkHandlerTest extends QpidTestCase
+import org.apache.qpid.transport.NetworkDriver;
+import org.apache.qpid.transport.OpenException;
+
+public class MINANetworkDriverTest extends TestCase
{
private static final String TEST_DATA = "YHALOTHAR";
- private int _testPort;
- private IncomingNetworkTransport _server;
- private OutgoingNetworkTransport _client;
+ private static int TEST_PORT = 2323;
+ private NetworkDriver _server;
+ private NetworkDriver _client;
private CountingProtocolEngine _countingEngine; // Keeps a count of how many bytes it's read
private Exception _thrownEx;
- private ConnectionSettings _clientSettings;
- private NetworkConnection _network;
- private TestNetworkTransportConfiguration _brokerSettings;
@Override
- public void setUp() throws Exception
+ public void setUp()
{
- String host = InetAddress.getLocalHost().getHostName();
- _testPort = findFreePort();
-
- _clientSettings = new ConnectionSettings();
- _clientSettings.setHost(host);
- _clientSettings.setPort(_testPort);
-
- _brokerSettings = new TestNetworkTransportConfiguration(_testPort, host);
-
- _server = new MinaNetworkTransport();
- _client = new MinaNetworkTransport();
+ _server = new MINANetworkDriver();
+ _client = new MINANetworkDriver();
_thrownEx = null;
_countingEngine = new CountingProtocolEngine();
+ // increment the port to prevent tests clashing with each other when
+ // the port is in TIMED_WAIT state.
+ TEST_PORT++;
}
@Override
@@ -91,40 +78,46 @@ public class MinaNetworkHandlerTest extends QpidTestCase
/**
* Tests that a socket can't be opened if a driver hasn't been bound
* to the port and can be opened if a driver has been bound.
+ * @throws BindException
+ * @throws UnknownHostException
+ * @throws OpenException
*/
- public void testBindOpen() throws Exception
+ public void testBindOpen() throws BindException, UnknownHostException, OpenException
{
try
{
- _client.connect(_clientSettings, _countingEngine, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
}
- catch (TransportException e)
+ catch (OpenException e)
{
_thrownEx = e;
}
assertNotNull("Open should have failed since no engine bound", _thrownEx);
- _server.accept(_brokerSettings, null, null);
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
- _client.connect(_clientSettings, _countingEngine, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
}
/**
* Tests that a socket can't be opened after a bound NetworkDriver has been closed
+ * @throws BindException
+ * @throws UnknownHostException
+ * @throws OpenException
*/
- public void testBindOpenCloseOpen() throws Exception
+ public void testBindOpenCloseOpen() throws BindException, UnknownHostException, OpenException
{
- _server.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
- _client.connect(_clientSettings, _countingEngine, null);
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
_client.close();
_server.close();
try
{
- _client.connect(_clientSettings, _countingEngine, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
}
- catch (TransportException e)
+ catch (OpenException e)
{
_thrownEx = e;
}
@@ -139,60 +132,43 @@ public class MinaNetworkHandlerTest extends QpidTestCase
{
try
{
- _server.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
}
- catch (TransportException e)
+ catch (BindException e)
{
fail("First bind should not fail");
}
try
{
- IncomingNetworkTransport second = new MinaNetworkTransport();
- second.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
+ _client.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
}
- catch (TransportException e)
+ catch (BindException e)
{
_thrownEx = e;
}
assertNotNull("Second bind should throw BindException", _thrownEx);
- }
-
- /**
- * Tests that binding to the wildcard address succeeds and a client can
- * connect via localhost.
- */
- public void testWildcardBind() throws Exception
- {
- TestNetworkTransportConfiguration serverSettings =
- new TestNetworkTransportConfiguration(_testPort, WILDCARD_ADDRESS);
-
- _server.accept(serverSettings, null, null);
-
- try
- {
- _client.connect(_clientSettings, _countingEngine, null);
- }
- catch (TransportException e)
- {
- fail("Open should have succeeded since we used a wildcard bind");
- }
- }
-
+ }
+
/**
* tests that bytes sent on a network driver are received at the other end
+ *
+ * @throws UnknownHostException
+ * @throws OpenException
+ * @throws InterruptedException
+ * @throws BindException
*/
- public void testSend() throws Exception
+ public void testSend() throws UnknownHostException, OpenException, InterruptedException, BindException
{
// Open a connection from a counting engine to an echo engine
- _server.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
- _network = _client.connect(_clientSettings, _countingEngine, null);
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
// Tell the counting engine how much data we're sending
_countingEngine.setNewLatch(TEST_DATA.getBytes().length);
// Send the data and wait for up to 2 seconds to get it back
- _network.getSender().send(ByteBuffer.wrap(TEST_DATA.getBytes()));
+ _client.send(ByteBuffer.wrap(TEST_DATA.getBytes()));
_countingEngine.getLatch().await(2, TimeUnit.SECONDS);
// Check what we got
@@ -201,30 +177,36 @@ public class MinaNetworkHandlerTest extends QpidTestCase
/**
* Opens a connection with a low read idle and check that it gets triggered
+ * @throws BindException
+ * @throws OpenException
+ * @throws UnknownHostException
*
*/
- public void testSetReadIdle() throws Exception
+ public void testSetReadIdle() throws BindException, UnknownHostException, OpenException
{
// Open a connection from a counting engine to an echo engine
- _server.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
- _network = _client.connect(_clientSettings, _countingEngine, null);
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
assertFalse("Reader should not have been idle", _countingEngine.getReaderHasBeenIdle());
- _network.setMaxReadIdle(1);
+ _client.setMaxReadIdle(1);
sleepForAtLeast(1500);
assertTrue("Reader should have been idle", _countingEngine.getReaderHasBeenIdle());
}
/**
* Opens a connection with a low write idle and check that it gets triggered
+ * @throws BindException
+ * @throws OpenException
+ * @throws UnknownHostException
*
*/
- public void testSetWriteIdle() throws Exception
+ public void testSetWriteIdle() throws BindException, UnknownHostException, OpenException
{
// Open a connection from a counting engine to an echo engine
- _server.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
- _network = _client.connect(_clientSettings, _countingEngine, null);
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
assertFalse("Reader should not have been idle", _countingEngine.getWriterHasBeenIdle());
- _network.setMaxWriteIdle(1);
+ _client.setMaxWriteIdle(1);
sleepForAtLeast(1500);
assertTrue("Reader should have been idle", _countingEngine.getWriterHasBeenIdle());
}
@@ -234,13 +216,16 @@ public class MinaNetworkHandlerTest extends QpidTestCase
* Creates and then closes a connection from client to server and checks that the server
* has its closed() method called. Then creates a new client and closes the server to check
* that the client has its closed() method called.
+ * @throws BindException
+ * @throws UnknownHostException
+ * @throws OpenException
*/
- public void testClosed() throws Exception
+ public void testClosed() throws BindException, UnknownHostException, OpenException
{
// Open a connection from a counting engine to an echo engine
EchoProtocolEngineSingletonFactory factory = new EchoProtocolEngineSingletonFactory();
- _server.accept(_brokerSettings, factory, null);
- _network = _client.connect(_clientSettings, _countingEngine, null);
+ _server.bind(TEST_PORT, null, factory, null, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
EchoProtocolEngine serverEngine = null;
while (serverEngine == null)
{
@@ -268,7 +253,7 @@ public class MinaNetworkHandlerTest extends QpidTestCase
}
assertTrue("Server should have been closed", serverEngine.getClosed());
- _client.connect(_clientSettings, _countingEngine, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
_countingEngine.setClosed(false);
assertFalse("Client should not have been closed", _countingEngine.getClosed());
_countingEngine.setNewLatch(1);
@@ -286,18 +271,22 @@ public class MinaNetworkHandlerTest extends QpidTestCase
/**
* Create a connection and instruct the client to throw an exception when it gets some data
* and that the latch gets counted down.
+ * @throws BindException
+ * @throws UnknownHostException
+ * @throws OpenException
+ * @throws InterruptedException
*/
- public void testExceptionCaught() throws Exception
+ public void testExceptionCaught() throws BindException, UnknownHostException, OpenException, InterruptedException
{
- _server.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
- _network = _client.connect(_clientSettings, _countingEngine, null);
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
assertEquals("Exception should not have been thrown", 1,
_countingEngine.getExceptionLatch().getCount());
_countingEngine.setErrorOnNextRead(true);
_countingEngine.setNewLatch(TEST_DATA.getBytes().length);
- _network.getSender().send(ByteBuffer.wrap(TEST_DATA.getBytes()));
+ _client.send(ByteBuffer.wrap(TEST_DATA.getBytes()));
_countingEngine.getExceptionLatch().await(2, TimeUnit.SECONDS);
assertEquals("Exception should have been thrown", 0,
_countingEngine.getExceptionLatch().getCount());
@@ -305,24 +294,28 @@ public class MinaNetworkHandlerTest extends QpidTestCase
/**
* Opens a connection and checks that the remote address is the one that was asked for
+ * @throws BindException
+ * @throws UnknownHostException
+ * @throws OpenException
*/
- public void testGetRemoteAddress() throws Exception
+ public void testGetRemoteAddress() throws BindException, UnknownHostException, OpenException
{
- _server.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
- _network = _client.connect(_clientSettings, _countingEngine, null);
- assertEquals(new InetSocketAddress(InetAddress.getLocalHost(), _testPort),
- _network.getRemoteAddress());
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
+ assertEquals(new InetSocketAddress(InetAddress.getLocalHost(), TEST_PORT),
+ _client.getRemoteAddress());
}
private class EchoProtocolEngineSingletonFactory implements ProtocolEngineFactory
{
- private EchoProtocolEngine _engine = null;
+ EchoProtocolEngine _engine = null;
- public ProtocolEngine newProtocolEngine(NetworkConnection network)
+ public ProtocolEngine newProtocolEngine(NetworkDriver driver)
{
if (_engine == null)
{
- _engine = new EchoProtocolEngine(network);
+ _engine = new EchoProtocolEngine();
+ _engine.setNetworkDriver(driver);
}
return getEngine();
}
@@ -335,6 +328,8 @@ public class MinaNetworkHandlerTest extends QpidTestCase
public class CountingProtocolEngine implements ProtocolEngine
{
+
+ protected NetworkDriver _driver;
public ArrayList<ByteBuffer> _receivedBytes = new ArrayList<ByteBuffer>();
private int _readBytes;
private CountDownLatch _latch = new CountDownLatch(0);
@@ -367,12 +362,26 @@ public class MinaNetworkHandlerTest extends QpidTestCase
public SocketAddress getRemoteAddress()
{
- return _network.getRemoteAddress();
+ if (_driver != null)
+ {
+ return _driver.getRemoteAddress();
+ }
+ else
+ {
+ return null;
+ }
}
public SocketAddress getLocalAddress()
{
- return _network.getLocalAddress();
+ if (_driver != null)
+ {
+ return _driver.getLocalAddress();
+ }
+ else
+ {
+ return null;
+ }
}
public long getWrittenBytes()
@@ -385,6 +394,11 @@ public class MinaNetworkHandlerTest extends QpidTestCase
_readerHasBeenIdle = true;
}
+ public void setNetworkDriver(NetworkDriver driver)
+ {
+ _driver = driver;
+ }
+
public void writeFrame(AMQDataBlock frame)
{
@@ -451,18 +465,12 @@ public class MinaNetworkHandlerTest extends QpidTestCase
private class EchoProtocolEngine extends CountingProtocolEngine
{
- private NetworkConnection _echoNetwork;
-
- public EchoProtocolEngine(NetworkConnection network)
- {
- _echoNetwork = network;
- }
public void received(ByteBuffer msg)
{
super.received(msg);
msg.rewind();
- _echoNetwork.getSender().send(msg);
+ _driver.send(msg);
}
}
@@ -483,52 +491,4 @@ public class MinaNetworkHandlerTest extends QpidTestCase
timeLeft = period - (System.currentTimeMillis() - start);
}
}
-
- private static class TestNetworkTransportConfiguration implements NetworkTransportConfiguration
- {
- private int _port;
- private String _host;
-
- public TestNetworkTransportConfiguration(final int port, final String host)
- {
- _port = port;
- _host = host;
- }
-
- public Boolean getTcpNoDelay()
- {
- return true;
- }
-
- public Integer getReceiveBufferSize()
- {
- return 32768;
- }
-
- public Integer getSendBufferSize()
- {
- return 32768;
- }
-
- public Integer getPort()
- {
- return _port;
- }
-
- public String getHost()
- {
- return _host;
- }
-
- public String getTransport()
- {
- return Transport.TCP;
- }
-
- public Integer getConnectorProcessors()
- {
- return 4;
- }
-
- }
} \ No newline at end of file
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java b/qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java
index d6767eb9c0..7eba5f092e 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java
@@ -27,9 +27,7 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
-import java.io.InputStream;
import java.util.List;
-import java.util.Properties;
public class FileUtilsTest extends TestCase
{
@@ -184,20 +182,6 @@ public class FileUtilsTest extends TestCase
}
}
-
- /**
- * Helper method to create a temporary file with test content.
- *
- * @param test_data The data to store in the file
- *
- * @return The File reference
- */
- private File createTestFileInTmpDir(final String testData) throws Exception
- {
- final File tmpFile = File.createTempFile("test", "tmp");
-
- return createTestFile(tmpFile.getCanonicalPath(), testData);
- }
/**
* Helper method to create a test file with a string content
*
@@ -318,74 +302,8 @@ public class FileUtilsTest extends TestCase
// expected path
}
}
-
- /**
- * Tests that openFileOrDefaultResource can open a file on the filesystem.
- *
- */
- public void testOpenFileOrDefaultResourceOpensFileOnFileSystem() throws Exception
- {
- final File testFile = createTestFileInTmpDir("src=tmpfile");
- final String filenameOnFilesystem = testFile.getCanonicalPath();
- final String defaultResource = "org/apache/qpid/util/default.properties";
-
-
- final InputStream is = FileUtils.openFileOrDefaultResource(filenameOnFilesystem, defaultResource, this.getClass().getClassLoader());
- assertNotNull("Stream must not be null", is);
- final Properties p = new Properties();
- p.load(is);
- assertEquals("tmpfile", p.getProperty("src"));
- }
/**
- * Tests that openFileOrDefaultResource can open a file on the classpath.
- *
- */
- public void testOpenFileOrDefaultResourceOpensFileOnClasspath() throws Exception
- {
- final String mydefaultsResource = "org/apache/qpid/util/mydefaults.properties";
- final String defaultResource = "org/apache/qpid/util/default.properties";
-
-
- final InputStream is = FileUtils.openFileOrDefaultResource(mydefaultsResource, defaultResource, this.getClass().getClassLoader());
- assertNotNull("Stream must not be null", is);
- final Properties p = new Properties();
- p.load(is);
- assertEquals("mydefaults", p.getProperty("src"));
- }
-
- /**
- * Tests that openFileOrDefaultResource returns the default resource when file cannot be found.
- */
- public void testOpenFileOrDefaultResourceOpensDefaultResource() throws Exception
- {
- final File fileThatDoesNotExist = new File("/does/not/exist.properties");
- assertFalse("Test must not exist", fileThatDoesNotExist.exists());
-
- final String defaultResource = "org/apache/qpid/util/default.properties";
-
- final InputStream is = FileUtils.openFileOrDefaultResource(fileThatDoesNotExist.getCanonicalPath(), defaultResource, this.getClass().getClassLoader());
- assertNotNull("Stream must not be null", is);
- Properties p = new Properties();
- p.load(is);
- assertEquals("default.properties", p.getProperty("src"));
- }
-
- /**
- * Tests that openFileOrDefaultResource returns null if neither the file nor
- * the default resource can be found..
- */
- public void testOpenFileOrDefaultResourceReturnsNullWhenNeitherCanBeFound() throws Exception
- {
-
- final String mydefaultsResource = "org/apache/qpid/util/doesnotexisteiether.properties";
- final String defaultResource = "org/apache/qpid/util/doesnotexisteiether.properties";
-
- final InputStream is = FileUtils.openFileOrDefaultResource(mydefaultsResource, defaultResource, this.getClass().getClassLoader());
- assertNull("Stream must be null", is);
- }
-
- /**
* Given two lists of File arrays ensure they are the same length and all entries in Before are in After
*
* @param filesBefore File[]
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/util/default.properties b/qpid/java/common/src/test/java/org/apache/qpid/util/default.properties
deleted file mode 100644
index cb522ea9a7..0000000000
--- a/qpid/java/common/src/test/java/org/apache/qpid/util/default.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-# Used by FileUtilsTests
-src=default.properties \ No newline at end of file
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/util/mydefaults.properties b/qpid/java/common/src/test/java/org/apache/qpid/util/mydefaults.properties
deleted file mode 100644
index 6a49d927d0..0000000000
--- a/qpid/java/common/src/test/java/org/apache/qpid/util/mydefaults.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-# Used by FileUtilsTests
-src=mydefaults \ No newline at end of file
diff --git a/qpid/java/ivy.xml b/qpid/java/ivy.xml
deleted file mode 100644
index 1399db5248..0000000000
--- a/qpid/java/ivy.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
-
- <info organisation="org/apache" module="qpid" revision="0.13"/>
-
- <publications xmlns:e="urn:ant.apache.org:ivy-extras">
- <artifact name="qpid-client" type="pom" ext="pom"/>
- <artifact name="qpid-client" type="pom.asc" ext="pom.asc"/>
- <artifact name="qpid-client" type="jar" ext="jar"/>
- <artifact name="qpid-client" type="jar.asc" ext="jar.asc"/>
- <artifact name="qpid-client" type="source" ext="jar" e:classifier="sources"/>
- <artifact name="qpid-client" type="source.asc" ext="jar.asc" e:classifier="sources"/>
- <artifact name="qpid-common" type="pom" ext="pom"/>
- <artifact name="qpid-common" type="pom.asc" ext="pom.asc"/>
- <artifact name="qpid-common" type="jar" ext="jar"/>
- <artifact name="qpid-common" type="jar.asc" ext="jar.asc"/>
- <artifact name="qpid-common" type="source" ext="jar" e:classifier="sources"/>
- <artifact name="qpid-common" type="source.asc" ext="jar.asc" e:classifier="sources"/>
- </publications>
-
- <dependencies/>
-</ivy-module>
diff --git a/qpid/java/lib/backport-util-concurrent-2.2.jar b/qpid/java/lib/backport-util-concurrent-2.2.jar
new file mode 100644
index 0000000000..20a16877bd
--- /dev/null
+++ b/qpid/java/lib/backport-util-concurrent-2.2.jar
Binary files differ
diff --git a/qpid/java/lib/commons-pool-1.4.jar b/qpid/java/lib/commons-pool-1.4.jar
new file mode 100644
index 0000000000..d6bc185450
--- /dev/null
+++ b/qpid/java/lib/commons-pool-1.4.jar
Binary files differ
diff --git a/qpid/java/lib/core-3.1.1.jar b/qpid/java/lib/core-3.1.1.jar
new file mode 100644
index 0000000000..ae0b635867
--- /dev/null
+++ b/qpid/java/lib/core-3.1.1.jar
Binary files differ
diff --git a/qpid/java/lib/geronimo-servlet_2.5_spec-1.2.jar b/qpid/java/lib/geronimo-servlet_2.5_spec-1.2.jar
new file mode 100644
index 0000000000..00a2010036
--- /dev/null
+++ b/qpid/java/lib/geronimo-servlet_2.5_spec-1.2.jar
Binary files differ
diff --git a/qpid/java/lib/ivy/README.txt b/qpid/java/lib/ivy/README.txt
deleted file mode 100644
index f8a01f39b4..0000000000
--- a/qpid/java/lib/ivy/README.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-Folder used to store Ivy libs for use in publishing Maven artifacts.
-
-Ivy must be downloaded and extracted into this directory if it is not available in the Ant lib dir.
-
-File may be downloaded in 2 ways:
-1. By running the following command from the qpid/java dir:
- ant -buildfile upload.xml download-ivy
-2. Manually download and extract via http://ant.apache.org/ivy.
-
-Note for method 1 you may also have to set proxy server settings in advance, eg:
-export ANT_OPTS="-Dhttp.proxyHost=<hostname> -Dhttp.proxyPort=<port>"
diff --git a/qpid/java/lib/javassist.jar b/qpid/java/lib/javassist.jar
new file mode 100644
index 0000000000..a6bde77812
--- /dev/null
+++ b/qpid/java/lib/javassist.jar
Binary files differ
diff --git a/qpid/java/lib/jline-0.9.94.jar b/qpid/java/lib/jline-0.9.94.jar
new file mode 100644
index 0000000000..dafca7c46e
--- /dev/null
+++ b/qpid/java/lib/jline-0.9.94.jar
Binary files differ
diff --git a/qpid/java/lib/jsp-2.1.jar b/qpid/java/lib/jsp-2.1.jar
new file mode 100644
index 0000000000..bfdb566c13
--- /dev/null
+++ b/qpid/java/lib/jsp-2.1.jar
Binary files differ
diff --git a/qpid/java/lib/jsp-api-2.1.jar b/qpid/java/lib/jsp-api-2.1.jar
new file mode 100644
index 0000000000..ac3a7a8f7e
--- /dev/null
+++ b/qpid/java/lib/jsp-api-2.1.jar
Binary files differ
diff --git a/qpid/java/lib/junit-4.4.jar b/qpid/java/lib/junit-4.4.jar
new file mode 100644
index 0000000000..649b0b327f
--- /dev/null
+++ b/qpid/java/lib/junit-4.4.jar
Binary files differ
diff --git a/qpid/java/lib/mina-core-1.0.1.jar b/qpid/java/lib/mina-core-1.0.1.jar
new file mode 100755
index 0000000000..f12067aa90
--- /dev/null
+++ b/qpid/java/lib/mina-core-1.0.1.jar
Binary files differ
diff --git a/qpid/java/lib/mina-core-1.1.7.jar b/qpid/java/lib/mina-core-1.1.7.jar
deleted file mode 100644
index a5fc451cc7..0000000000
--- a/qpid/java/lib/mina-core-1.1.7.jar
+++ /dev/null
Binary files differ
diff --git a/qpid/java/lib/mina-filter-ssl-1.0.1.jar b/qpid/java/lib/mina-filter-ssl-1.0.1.jar
new file mode 100755
index 0000000000..53738e6498
--- /dev/null
+++ b/qpid/java/lib/mina-filter-ssl-1.0.1.jar
Binary files differ
diff --git a/qpid/java/lib/mina-filter-ssl-1.1.7.jar b/qpid/java/lib/mina-filter-ssl-1.1.7.jar
deleted file mode 100644
index 40bdc919e1..0000000000
--- a/qpid/java/lib/mina-filter-ssl-1.1.7.jar
+++ /dev/null
Binary files differ
diff --git a/qpid/java/lib/muse-core-2.2.0.jar b/qpid/java/lib/muse-core-2.2.0.jar
new file mode 100644
index 0000000000..674ec26f58
--- /dev/null
+++ b/qpid/java/lib/muse-core-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-platform-mini-2.2.0.jar b/qpid/java/lib/muse-platform-mini-2.2.0.jar
new file mode 100644
index 0000000000..1782083231
--- /dev/null
+++ b/qpid/java/lib/muse-platform-mini-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-util-2.2.0.jar b/qpid/java/lib/muse-util-2.2.0.jar
new file mode 100644
index 0000000000..8bb7348180
--- /dev/null
+++ b/qpid/java/lib/muse-util-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-util-qname-2.2.0.jar b/qpid/java/lib/muse-util-qname-2.2.0.jar
new file mode 100644
index 0000000000..af0c76ece4
--- /dev/null
+++ b/qpid/java/lib/muse-util-qname-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-util-xml-2.2.0.jar b/qpid/java/lib/muse-util-xml-2.2.0.jar
new file mode 100644
index 0000000000..016b303c62
--- /dev/null
+++ b/qpid/java/lib/muse-util-xml-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsa-soap-2.2.0.jar b/qpid/java/lib/muse-wsa-soap-2.2.0.jar
new file mode 100644
index 0000000000..f83322beac
--- /dev/null
+++ b/qpid/java/lib/muse-wsa-soap-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsdm-muws-adv-api-2.2.0.jar b/qpid/java/lib/muse-wsdm-muws-adv-api-2.2.0.jar
new file mode 100644
index 0000000000..ba3bf4aa40
--- /dev/null
+++ b/qpid/java/lib/muse-wsdm-muws-adv-api-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsdm-muws-adv-impl-2.2.0.jar b/qpid/java/lib/muse-wsdm-muws-adv-impl-2.2.0.jar
new file mode 100644
index 0000000000..780a20f474
--- /dev/null
+++ b/qpid/java/lib/muse-wsdm-muws-adv-impl-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsdm-muws-api-2.2.0.jar b/qpid/java/lib/muse-wsdm-muws-api-2.2.0.jar
new file mode 100644
index 0000000000..2a0cab200a
--- /dev/null
+++ b/qpid/java/lib/muse-wsdm-muws-api-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsdm-muws-impl-2.2.0.jar b/qpid/java/lib/muse-wsdm-muws-impl-2.2.0.jar
new file mode 100644
index 0000000000..a9954bb27e
--- /dev/null
+++ b/qpid/java/lib/muse-wsdm-muws-impl-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsdm-wef-api-2.2.0.jar b/qpid/java/lib/muse-wsdm-wef-api-2.2.0.jar
new file mode 100644
index 0000000000..e9206b2eb3
--- /dev/null
+++ b/qpid/java/lib/muse-wsdm-wef-api-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsdm-wef-impl-2.2.0.jar b/qpid/java/lib/muse-wsdm-wef-impl-2.2.0.jar
new file mode 100644
index 0000000000..12856123b1
--- /dev/null
+++ b/qpid/java/lib/muse-wsdm-wef-impl-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsn-api-2.2.0.jar b/qpid/java/lib/muse-wsn-api-2.2.0.jar
new file mode 100644
index 0000000000..72b70a043d
--- /dev/null
+++ b/qpid/java/lib/muse-wsn-api-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsn-impl-2.2.0.jar b/qpid/java/lib/muse-wsn-impl-2.2.0.jar
new file mode 100644
index 0000000000..615f2a5f62
--- /dev/null
+++ b/qpid/java/lib/muse-wsn-impl-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsrf-api-2.2.0.jar b/qpid/java/lib/muse-wsrf-api-2.2.0.jar
new file mode 100644
index 0000000000..efa36e9fbc
--- /dev/null
+++ b/qpid/java/lib/muse-wsrf-api-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsrf-impl-2.2.0.jar b/qpid/java/lib/muse-wsrf-impl-2.2.0.jar
new file mode 100644
index 0000000000..a19b1e7149
--- /dev/null
+++ b/qpid/java/lib/muse-wsrf-impl-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsrf-rmd-2.2.0.jar b/qpid/java/lib/muse-wsrf-rmd-2.2.0.jar
new file mode 100644
index 0000000000..e03676cad8
--- /dev/null
+++ b/qpid/java/lib/muse-wsrf-rmd-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsx-api-2.2.0.jar b/qpid/java/lib/muse-wsx-api-2.2.0.jar
new file mode 100644
index 0000000000..1533d8dc59
--- /dev/null
+++ b/qpid/java/lib/muse-wsx-api-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsx-impl-2.2.0.jar b/qpid/java/lib/muse-wsx-impl-2.2.0.jar
new file mode 100644
index 0000000000..9ce78ef0b7
--- /dev/null
+++ b/qpid/java/lib/muse-wsx-impl-2.2.0.jar
Binary files differ
diff --git a/qpid/java/ivysettings-nexus.xml b/qpid/java/lib/poms/backport-util-concurrent-2.2.xml
index 1d9c393e23..6df4cfca40 100644
--- a/qpid/java/ivysettings-nexus.xml
+++ b/qpid/java/lib/poms/backport-util-concurrent-2.2.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@@ -14,17 +15,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<ivysettings>
- <credentials host="${nexus.host}" realm="Sonatype Nexus Repository Manager" username="${nexus.user}" passwd="${nexus.password}"/>
- <caches defaultCacheDir="${user.home}/.ivy2/cache"/>
- <resolvers>
- <ibiblio name="public" m2compatible="true"/>
- <url name="nexus">
- <artifact pattern="${nexus.upload.url}/[organisation]/[module]/[artifact]/[revision]/[artifact]-[revision](-[classifier]).[ext]" />
- </url>
- </resolvers>
- <modules>
- <module organisation="${nexus.organisation}" name="qpid" resolver="nexus"/>
- </modules>
- <settings defaultResolver="public"/>
-</ivysettings>
+<dep>
+ <groupId>backport-util-concurrent</groupId>
+ <artifactId>backport-util-concurrent</artifactId>
+ <version>2.2</version>
+</dep>
diff --git a/qpid/java/lib/poms/mina-core-1.1.7.xml b/qpid/java/lib/poms/mina-core-1.0.1.xml
index eee6108082..87fb96999f 100644
--- a/qpid/java/lib/poms/mina-core-1.1.7.xml
+++ b/qpid/java/lib/poms/mina-core-1.0.1.xml
@@ -18,5 +18,5 @@
<dep>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
- <version>1.1.7</version>
+ <version>1.0.1</version>
</dep>
diff --git a/qpid/java/lib/poms/mina-filter-ssl-1.1.7.xml b/qpid/java/lib/poms/mina-filter-ssl-1.0.1.xml
index 52daba7eed..ae41d7ed63 100644
--- a/qpid/java/lib/poms/mina-filter-ssl-1.1.7.xml
+++ b/qpid/java/lib/poms/mina-filter-ssl-1.0.1.xml
@@ -18,5 +18,5 @@
<dep>
<groupId>org.apache.mina</groupId>
<artifactId>mina-filter-ssl</artifactId>
- <version>1.1.7</version>
+ <version>1.0.1</version>
</dep>
diff --git a/qpid/java/lib/start.jar b/qpid/java/lib/start.jar
new file mode 100644
index 0000000000..63685df7cc
--- /dev/null
+++ b/qpid/java/lib/start.jar
Binary files differ
diff --git a/qpid/java/lib/wsdl4j-1.6.1.jar b/qpid/java/lib/wsdl4j-1.6.1.jar
new file mode 100644
index 0000000000..67a35fcbaa
--- /dev/null
+++ b/qpid/java/lib/wsdl4j-1.6.1.jar
Binary files differ
diff --git a/qpid/java/lib/xercesImpl-2.8.1.jar b/qpid/java/lib/xercesImpl-2.8.1.jar
new file mode 100644
index 0000000000..3b351f6e2b
--- /dev/null
+++ b/qpid/java/lib/xercesImpl-2.8.1.jar
Binary files differ
diff --git a/qpid/java/lib/xml-apis-1.3.03.jar b/qpid/java/lib/xml-apis-1.3.03.jar
new file mode 100644
index 0000000000..b338fb6693
--- /dev/null
+++ b/qpid/java/lib/xml-apis-1.3.03.jar
Binary files differ
diff --git a/qpid/java/management/agent/build.xml b/qpid/java/management/agent/build.xml
new file mode 100644
index 0000000000..a410c74c1f
--- /dev/null
+++ b/qpid/java/management/agent/build.xml
@@ -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.
+ -
+ -->
+<project name="QMF Agent" default="build">
+
+ <property name="module.depends" value="common client"/>
+
+ <import file="../../module.xml"/>
+
+</project>
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java
new file mode 100644
index 0000000000..b1a4a8c93e
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java
@@ -0,0 +1,706 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.agent;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.jms.BytesMessage;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.binding.BindingContext;
+import org.apache.qpid.agent.binding.BindingUtils;
+import org.apache.qpid.agent.binding.ClassBinding;
+import org.apache.qpid.agent.binding.BindingException;
+import org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.ParameterBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+import org.apache.qpid.agent.binding.TypeBinding;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * The main class for interacting with the QMF bus. Objects which are to be
+ * managed can be registered with the agent, as can classes to be exposed via
+ * the schema.
+ */
+public class Agent implements MessageListener
+{
+ // The following are settings to configure the Agent
+ protected AMQConnection connection;
+ protected boolean sessionTransacted = false;
+ protected int acknowledgeMode = Session.AUTO_ACKNOWLEDGE;
+ protected String label;
+ protected UUID systemId;
+ // this list holds the objects until the agent is started
+ protected List managedObjects = new ArrayList();
+ protected List registeredClasses = new ArrayList();
+ // The following instance variables are not
+ // able to be set by the end user.
+ protected Session session;
+ protected MessageProducer prod;
+ protected MessageConsumer cons;
+ protected Queue reply;
+ protected BindingContext bctx = new BindingContext();
+ protected Map<Long, ManagedObject> objects = new Hashtable<Long, ManagedObject>();
+ protected long bbank;
+ protected long abank;
+ protected static final Log log = LogFactory.getLog(Agent.class);
+ protected volatile boolean inside = false;
+ protected ClassLoader classLoader = null;
+
+ public Agent()
+ {
+ systemId = UUID.randomUUID();
+ log.debug(String.format("Agent with uid %s created", systemId
+ .toString()));
+ }
+
+ public Agent(String label, UUID systemId)
+ {
+ this.systemId = systemId;
+ this.label = label;
+ log.debug(String.format("Agent with name %s and uid %s created", label,
+ systemId.toString()));
+ }
+
+ public void register(ManagedObject managedObject)
+ {
+ Class managedClass = managedObject.getObjectClass();
+ long id = managedObject.getId();
+ ClassBinding cb = bctx.register(managedClass);
+ managedObject.setManagedClassName(cb.getName());
+ managedObject.setManagedPackageName(cb.getPackage());
+ log.debug(String.format(
+ "Added managed object id '%d' for package '%s' class '%s'", id,
+ managedObject.getManagedPackageName(), managedObject
+ .getManagedClassName()));
+ objects.put(id, managedObject);
+ managedObjects.add(managedObject);
+ }
+
+ public void registerClass(Class cls)
+ {
+ bctx.register(cls);
+ if (!registeredClasses.contains(cls))
+ {
+ registeredClasses.add(cls);
+ }
+ }
+
+ /**
+ * Stops the agents connection to the bus
+ */
+ public void stop()
+ {
+ try
+ {
+ cons.close();
+ prod.close();
+ connection.stop();
+ connection.close();
+ session.close();
+ } catch (JMSException e)
+ {
+ log.error("Exception:", e);
+ }
+ }
+
+ /**
+ * Starts up the agent. Many bean containers may call this by default which
+ * aids in deployment
+ */
+ public void start()
+ {
+ log.debug(String.format("Agent with uid %s and name %s starting",
+ systemId.toString(), label));
+ for (Object clsName : registeredClasses.toArray())
+ {
+ try
+ {
+ Class cls = null;
+ if (String.class.isAssignableFrom(clsName.getClass()))
+ {
+ cls = getClass(clsName.toString());
+ } else
+ {
+ cls = (Class) clsName;
+ }
+ this.registerClass(cls);
+ } catch (Exception e)
+ {
+ log.error("Could not register class " + clsName);
+ }
+ }
+ for (Object obj : managedObjects.toArray())
+ {
+ this.register((ManagedObject) obj);
+ }
+ try
+ {
+ session = connection.createSession(sessionTransacted,
+ acknowledgeMode);
+ reply = session
+ .createQueue(String
+ .format(
+ "direct://amq.direct//%s-%s?exclusive='True'&autodelete='True'",
+ label, systemId));
+ cons = session.createConsumer(reply);
+ cons.setMessageListener(this);
+ prod = session.createProducer(null);
+ } catch (JMSException e)
+ {
+ throw new AgentException(e);
+ }
+ attachRequest(label, systemId);
+ try
+ {
+ connection.start();
+ } catch (JMSException e)
+ {
+ throw new AgentException(e);
+ }
+ }
+
+ /**
+ * Send an event object to the bus
+ */
+ public void raiseEvent(Object value, EventSeverity sev)
+ {
+ log.debug(String.format("Sending event of class %s with Severity %s",
+ value.getClass(), sev.ordinal()));
+ BBEncoder enc = this.init('e');
+ ClassBinding cb = bctx.getClassBinding(value.getClass());
+ String pkg = cb.getPackage();
+ String cls = cb.getName();
+ enc.writeStr8(pkg);
+ enc.writeStr8(cls);
+ enc.writeBin128(cb.getSchemaHash());
+ long now = System.currentTimeMillis() * 1000000;
+ enc.writeInt64(now);
+ enc.writeUint8((short) sev.ordinal());
+ for (PropertyBinding p : cb.getProperties())
+ {
+ p.getType().encode(enc, BindingUtils.get(p, value));
+ }
+ send(
+ String.format("console.event.%d.%d.%s.%s", bbank, abank, pkg,
+ cls), enc);
+ }
+
+ public void onMessage(Message message)
+ {
+ if (inside)
+ {
+ new Throwable().printStackTrace();
+ }
+ inside = true;
+ Decoder dec = readBody(message);
+ Destination replyTo;
+ try
+ {
+ replyTo = message.getJMSReplyTo();
+ } catch (JMSException e)
+ {
+ throw new AgentException(e);
+ }
+ byte[] magic = dec.readBytes(3);
+ if (magic[0] != 'A' || magic[1] != 'M' || magic[2] != '2')
+ {
+ throw new AgentException("bad magic: " + new String(magic));
+ }
+ short op = dec.readUint8();
+ long seq = dec.readUint32();
+ log.debug("Message recieved: " + (char) op);
+ switch (op)
+ {
+ case 'a':
+ this.handleAgentAttach(seq, replyTo, dec);
+ break;
+ case 'G':
+ this.handleGetQuery(seq, replyTo, dec);
+ break;
+ case 'M':
+ this.handleMethodRequest(seq, replyTo, dec);
+ break;
+ case 'S':
+ this.handleSchemaRequest(seq, replyTo, dec);
+ break;
+ case 'x':
+ // TODO
+ break;
+ default:
+ throw new IllegalArgumentException("opcode: " + ((char) op));
+ }
+ inside = false;
+ }
+
+ protected ClassBinding getClassBinding(ManagedObject mobj)
+ {
+ return bctx.getClassBinding(mobj.getObjectClass());
+ }
+
+ private byte[] ensure(int capacity, byte[] body, int size)
+ {
+ if (capacity > body.length)
+ {
+ byte[] copy = new byte[capacity];
+ System.arraycopy(body, 0, copy, 0, size);
+ body = copy;
+ }
+ return body;
+ }
+
+ private Decoder readBody(Message message)
+ {
+ BytesMessage msg = (BytesMessage) message;
+ BBDecoder dec = new BBDecoder();
+ byte[] buf = new byte[1024];
+ byte[] body = new byte[1024];
+ int size = 0;
+ int n;
+ try
+ {
+ while ((n = msg.readBytes(buf)) > 0)
+ {
+ body = ensure(size + n, body, size);
+ System.arraycopy(buf, 0, body, size, n);
+ size += n;
+ }
+ } catch (JMSException e)
+ {
+ throw new AgentException(e);
+ }
+ dec.init(ByteBuffer.wrap(body, 0, size));
+ return dec;
+ }
+
+ protected void handleAgentAttach(long seq, Destination replyTo, Decoder dec)
+ {
+ log.debug("Agent Attach Message");
+ bbank = dec.readUint32();
+ abank = dec.readUint32();
+ try
+ {
+ MessageConsumer mc = session
+ .createConsumer(session
+ .createQueue(String
+ .format(
+ "management://qpid.management//%s-%s?routingkey='agent.%d.%d'&exclusive='True'&autodelete='True'",
+ label, systemId, bbank, abank)));
+ mc.setMessageListener(this);
+ } catch (JMSException e)
+ {
+ throw new AgentException(e);
+ }
+ for (String packageName : bctx.getPackages())
+ {
+ packageIndication(packageName);
+ }
+ for (ClassBinding cb : bctx.getAllBindings())
+ {
+ classIndication(cb);
+ }
+ for (ManagedObject mo : objects.values())
+ {
+ content('i', seq, null, mo);
+ }
+ }
+
+ protected void handleMethodRequest(long seq, Destination replyTo,
+ Decoder dec)
+ {
+ dec.readUint64(); // first part of object-id
+ long id = dec.readUint64();
+ ManagedObject mo = objects.get(id);
+ if (mo == null)
+ {
+ methodResponse(seq, replyTo, 1, String.format(
+ "no such object: 0x%x", id));
+ } else
+ {
+ dec.readStr8(); // pkg
+ dec.readStr8(); // cls
+ dec.readBin128(); // hash
+ String mname = dec.readStr8();
+ ClassBinding cls = getClassBinding(mo);
+ MethodBinding method = cls.getMethod(mname);
+ if (method == null)
+ {
+ methodResponse(seq, replyTo, 2, String.format(
+ "no such method: %s", mname));
+ } else
+ {
+ log.trace("Handle method: " + method.getName());
+ List<ParameterBinding> params = method.getInParameters();
+ Object[] args = new Object[params.size()];
+ int idx = 0;
+ for (ParameterBinding p : params)
+ {
+ TypeBinding typeBinding = p.getType();
+ log
+ .trace(String
+ .format(
+ "Decoding parameter with type %s ref package %s ref class %s ",
+ typeBinding.getCode(), typeBinding
+ .getRefPackage(),
+ typeBinding.getRefClass()));
+ args[idx++] = typeBinding.decode(dec);
+ log.trace("Done");
+ }
+ try
+ {
+ Object[] result = mo.invoke(method, args);
+ methodResponse(seq, replyTo, 0, null, method, result);
+ } catch (BindingException ex)
+ {
+ log
+ .error(
+ String
+ .format(
+ "An exception occured invoking method %s. Stack trace sent to console.",
+ method.getName()), ex);
+ StringWriter str = new StringWriter();
+ PrintWriter writer = new PrintWriter(str);
+ ex.printStackTrace(writer);
+ writer.flush();
+ methodResponse(seq, replyTo, 7, str.toString());
+ }
+ log.trace("Done with method: " + method.getName());
+ }
+ }
+ }
+
+ protected void handleGetQuery(long seq, Destination replyTo, Decoder dec)
+ {
+ Map<String, Object> data = dec.readMap();
+ if (data.containsKey("_objectid"))
+ {
+ long objId = (Long) data.get("_objectid");
+ log.debug("Get Request message for object id " + objId);
+ ManagedObject mo = objects.get(objId);
+ if (mo == null)
+ {
+ methodResponse(seq, replyTo, 1, String.format(
+ "no such object: 0x%x", objId));
+ } else
+ {
+ content('g', seq, replyTo, mo);
+ }
+ } else if (data.containsKey("_class"))
+ {
+ String className = (String) data.get("_class");
+ String packageName = (String) data.get("_package");
+ log.debug(String.format(
+ "Get Request message for package '%s' class '%s'",
+ packageName, className));
+ for (ManagedObject mo : objects.values())
+ {
+ if (mo.getManagedClassName().equals(className))
+ {
+ if ((packageName == null) || packageName.equals("")
+ || packageName.equals(mo.getManagedPackageName()))
+ {
+ content('g', seq, replyTo, mo);
+ }
+ }
+ }
+ } else
+ {
+ for (ManagedObject mo : objects.values())
+ {
+ content('g', seq, replyTo, mo);
+ }
+ }
+ complete(seq, replyTo);
+ }
+
+ protected void handleSchemaRequest(long seq, Destination replyTo,
+ Decoder dec)
+ {
+ String pkg = dec.readStr8();
+ String cls = dec.readStr8();
+ log.debug(String.format(
+ "SchemaRequest message for package '%s' class '%s'", pkg, cls));
+ ClassBinding cb = bctx.getClassBinding(pkg, cls);
+ if (cb == null)
+ {
+ throw new AgentException("no such class: " + pkg + ", " + cls);
+ }
+ schemaResponse(seq, cb);
+ }
+
+ protected BBEncoder init(char opcode)
+ {
+ return init(opcode, 0);
+ }
+
+ protected BBEncoder init(char opcode, long sequence)
+ {
+ BBEncoder enc = new BBEncoder(1024);
+ enc.init();
+ enc.writeUint8((short) 'A');
+ enc.writeUint8((short) 'M');
+ enc.writeUint8((short) '2');
+ enc.writeUint8((short) opcode);
+ enc.writeUint32(sequence);
+ return enc;
+ }
+
+ protected void send(BBEncoder enc)
+ {
+ send("broker", enc);
+ }
+
+ protected void send(Destination dest, BBEncoder enc)
+ {
+ try
+ {
+ byte[] buf = new byte[1024];
+ BytesMessage msg = session.createBytesMessage();
+ ByteBuffer slice = enc.segment();
+ while (slice.hasRemaining())
+ {
+ int n = Math.min(buf.length, slice.remaining());
+ slice.get(buf, 0, n);
+ msg.writeBytes(buf, 0, n);
+ }
+ msg.setJMSReplyTo(reply);
+ // ???: I assume this is thread safe.
+ prod.send(dest, msg);
+ } catch (JMSException e)
+ {
+ throw new AgentException(e);
+ }
+ }
+
+ protected void send(String routingKey, BBEncoder enc)
+ {
+ try
+ {
+ send(session
+ .createQueue("management://qpid.management//?routingkey='"
+ + routingKey + "'"), enc);
+ } catch (JMSException e)
+ {
+ throw new AgentException(e);
+ }
+ }
+
+ protected void attachRequest(String label, UUID systemId)
+ {
+ BBEncoder enc = init('A');
+ enc.writeStr8(label);
+ enc.writeUuid(systemId);
+ enc.writeUint32(0);
+ enc.writeUint32(0);
+ send(enc);
+ }
+
+ protected void packageIndication(String pkg)
+ {
+ BBEncoder enc = init('p');
+ enc.writeStr8(pkg);
+ send(enc);
+ }
+
+ protected void classIndication(ClassBinding cb)
+ {
+ BBEncoder enc = init('q');
+ enc.writeUint8(cb.getKind());
+ enc.writeStr8(cb.getPackage());
+ enc.writeStr8(cb.getName());
+ enc.writeBin128(cb.getSchemaHash()); // schema hash?
+ send(enc);
+ }
+
+ protected void schemaResponse(long seq, ClassBinding cb)
+ {
+ BBEncoder enc = init('s', seq);
+ cb.encode(enc);
+ send(enc);
+ }
+
+ protected void content(char c, long seq, Destination dest, ManagedObject mo)
+ {
+ BBEncoder enc = init(c, seq);
+ ClassBinding cb = getClassBinding(mo);
+ String pkg = cb.getPackage();
+ String cls = cb.getName();
+ enc.writeStr8(pkg);
+ enc.writeStr8(cls);
+ enc.writeBin128(cb.getSchemaHash());
+ long now = System.currentTimeMillis() * 1000000;
+ enc.writeUint64(now);
+ enc.writeUint64(now);
+ enc.writeUint64(0);
+ enc.writeUint64(0x0000FFFFFFFFFFFFL & ((bbank << 28) | abank));
+ enc.writeUint64(mo.getId());
+ for (PropertyBinding p : cb.getProperties())
+ {
+ p.getType().encode(enc, mo.get(p));
+ }
+ if (dest == null)
+ {
+ send(String.format("console.obj.%d.%d.%s.%s", bbank, abank, pkg,
+ cls), enc);
+ } else
+ {
+ send(dest, enc);
+ }
+ }
+
+ protected void complete(long seq, Destination dest)
+ {
+ BBEncoder enc = init('z', seq);
+ enc.writeUint32(0);
+ enc.writeStr8("");
+ send(dest, enc);
+ }
+
+ protected void methodResponse(long seq, Destination dest, int status,
+ String text)
+ {
+ methodResponse(seq, dest, status, text, null, null);
+ }
+
+ protected void methodResponse(long seq, Destination dest, int status,
+ String text, MethodBinding method, Object[] result)
+ {
+ BBEncoder enc = init('m', seq);
+ enc.writeUint32(status);
+ enc.writeStr16(text == null ? "" : text);
+ if (method != null)
+ {
+ int idx = 0;
+ for (ParameterBinding p : method.getOutParameters())
+ {
+ p.getType().encode(enc, result[idx++]);
+ }
+ }
+ send(dest, enc);
+ }
+
+ protected Class getClass(String className)
+ {
+ try
+ {
+ if (classLoader != null)
+ {
+ return classLoader.loadClass(className);
+ } else
+ {
+ return Class.forName(className);
+ }
+ } catch (ClassNotFoundException e)
+ {
+ throw new AgentException(String.format(
+ "No class named %s was found", className), e);
+ }
+ }
+
+ public String getLabel()
+ {
+ return label;
+ }
+
+ public void setLabel(String label)
+ {
+ this.label = label;
+ }
+
+ public AMQConnection getConnection()
+ {
+ return connection;
+ }
+
+ public void setConnection(AMQConnection connection)
+ {
+ this.connection = connection;
+ }
+
+ public boolean isSessionTransacted()
+ {
+ return sessionTransacted;
+ }
+
+ public void setSessionTransacted(boolean sessionTransacted)
+ {
+ this.sessionTransacted = sessionTransacted;
+ }
+
+ public void setManagedObjects(List objectList)
+ {
+ this.managedObjects = objectList;
+ }
+
+ public List getManagedObjects()
+ {
+ return managedObjects;
+ }
+
+ public void setRegisteredClasses(List objectList)
+ {
+ this.registeredClasses = objectList;
+ }
+
+ public List getRegisteredClasses()
+ {
+ return this.registeredClasses;
+ }
+
+ public static void main(String[] args) throws Exception
+ {
+ String broker = args[0];
+ String name = args[1];
+ String url = String.format(
+ "amqp://guest:guest@/?brokerlist='tcp://%s'", broker);
+ AMQConnection conn = new AMQConnection(url);
+ Agent agent = new Agent(name, UUID.randomUUID());
+ agent.setConnection(conn);
+ for (int i = 2; i < args.length; i++)
+ {
+ Class<?> cls = Class.forName(args[i]);
+ agent.register(new ManagedPOJO(cls.newInstance()));
+ }
+ agent.start();
+ while (true)
+ {
+ Thread.sleep(1000);
+ }
+ }
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/QpidMessageProperties.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java
index b30afafa35..410cad2d8c 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/QpidMessageProperties.java
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java
@@ -18,17 +18,28 @@
* under the License.
*
*/
-package org.apache.qpid.client.message;
+package org.apache.qpid.agent;
/**
- * Place holder for Qpid specific message properties
+ * AgentException
+ *
*/
-public class QpidMessageProperties
+public class AgentException extends RuntimeException
{
+ private static final long serialVersionUID = 1L;
+
+ public AgentException(String msg)
+ {
+ super(msg);
+ }
+
+ public AgentException(Throwable t)
+ {
+ super(t);
+ }
- public static final String QPID_SUBJECT = "qpid.subject";
-
- // AMQP 0-10 related properties
- public static final String AMQP_0_10_APP_ID = "x-amqp-0-10.app-id";
- public static final String AMQP_0_10_ROUTING_KEY = "x-amqp-0-10.routing-key";
+ public AgentException(String msg, Throwable t)
+ {
+ super(msg, t);
+ }
}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java
new file mode 100644
index 0000000000..28735286c4
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java
@@ -0,0 +1,27 @@
+package org.apache.qpid.agent;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+
+public enum EventSeverity
+{
+ EMERGENCY, ALERT, CRIT, ERROR, WARN, NOTICE, INFO, DEBUG
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java
new file mode 100644
index 0000000000..60efb1e284
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.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.agent;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.binding.BindingUtils;
+import org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+
+/**
+ * Wrapper classe for adding EJBS which are to be managed by the QMF Agent. The
+ * jndi location and the public interface to exposed are used to generate the
+ * schema.
+ */
+public class ManagedEJB extends ManagedObjectBase
+{
+ private Log log = LogFactory.getLog(ManagedEJB.class);
+ protected String className;
+ protected String jndiLocation;
+ protected ClassLoader classLoader;
+
+ protected Object getEJB()
+ {
+ ClassLoader previousCL = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ if (classLoader != null)
+ {
+ Thread.currentThread().setContextClassLoader(classLoader);
+ }
+ InitialContext ctx = new InitialContext();
+ return ctx.lookup(jndiLocation);
+ } catch (NamingException e)
+ {
+ throw new AgentException("Error looking up EJB at " + jndiLocation,
+ e);
+ } finally
+ {
+ Thread.currentThread().setContextClassLoader(previousCL);
+ }
+ }
+
+ @Override
+ public Object get(PropertyBinding property)
+ {
+ return BindingUtils.get(property, this.getEJB());
+ }
+
+ @Override
+ public long getId()
+ {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public Class getObjectClass()
+ {
+ try
+ {
+ if (classLoader != null)
+ {
+ log.debug("Using the classloader");
+ return classLoader.loadClass(className);
+ } else
+ {
+ return Class.forName(className);
+ }
+ } catch (ClassNotFoundException e)
+ {
+ throw new AgentException(String.format(
+ "No class named %s was found", className), e);
+ }
+ }
+
+ @Override
+ public Object[] invoke(MethodBinding method, Object... args)
+ {
+ return BindingUtils.invoke(method, this.getEJB(), args);
+ }
+
+ @Override
+ public void set(PropertyBinding property, Object value)
+ {
+ BindingUtils.set(property, value, this.getEJB());
+ }
+
+ public String getClassName()
+ {
+ return className;
+ }
+
+ public void setClassName(String className)
+ {
+ this.className = className;
+ }
+
+ public String getJndiLocation()
+ {
+ return jndiLocation;
+ }
+
+ public void setJndiLocation(String jndiLocation)
+ {
+ this.jndiLocation = jndiLocation;
+ }
+
+ public ClassLoader getClassLoader()
+ {
+ return classLoader;
+ }
+
+ public void setClassLoader(ClassLoader cloader)
+ {
+ this.classLoader = cloader;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java
new file mode 100644
index 0000000000..aa3bbf3894
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.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.agent;
+
+import org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+
+/**
+ * Objects which are to be managed and controlled by the QMF Agent.
+ */
+public interface ManagedObject
+{
+ public abstract long getId();
+
+ public abstract Class getObjectClass();
+
+ public abstract Object get(PropertyBinding property);
+
+ public abstract void set(PropertyBinding property, Object value);
+
+ public abstract Object[] invoke(MethodBinding method, Object... args);
+
+ public abstract String getName();
+
+ public abstract void setName(String name);
+
+ public String getManagedClassName();
+
+ public String getManagedPackageName();
+
+ public void setManagedClassName(String aName);
+
+ public void setManagedPackageName(String aName);
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java
new file mode 100644
index 0000000000..51789ae11f
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.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.agent;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+
+public abstract class ManagedObjectBase implements ManagedObject
+{
+ private static Log log = LogFactory.getLog(ManagedObjectBase.class);
+ protected String name;
+ protected String managedClassName;
+ protected String managedPackageName;
+
+ public abstract long getId();
+
+ public abstract Object get(PropertyBinding property);
+
+ public abstract void set(PropertyBinding property, Object value);
+
+ public abstract Object[] invoke(MethodBinding method, Object... args);
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public String getManagedClassName()
+ {
+ return managedClassName;
+ }
+
+ public void setManagedClassName(String managedClassName)
+ {
+ this.managedClassName = managedClassName;
+ }
+
+ public String getManagedPackageName()
+ {
+ return managedPackageName;
+ }
+
+ public void setManagedPackageName(String managedPackageName)
+ {
+ this.managedPackageName = managedPackageName;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java
new file mode 100644
index 0000000000..94d9b9d0a8
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java
@@ -0,0 +1,90 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.agent;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.binding.BindingUtils;
+import org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+
+/**
+ * Wrapper classe for adding POJOS which are to be managed by the QMF Agent.
+ */
+public class ManagedPOJO extends ManagedObjectBase implements ManagedObject
+{
+ private Log log = LogFactory.getLog(ManagedPOJO.class);
+ private Object managed;
+
+ public ManagedPOJO()
+ {
+ super();
+ }
+
+ public ManagedPOJO(Object managed)
+ {
+ super();
+ this.setManaged(managed);
+ }
+
+ @Override
+ public long getId()
+ {
+ if (managed == null)
+ {
+ throw new AgentException("The managed object is null");
+ }
+ return System.identityHashCode(managed);
+ }
+
+ public Class getObjectClass()
+ {
+ return managed.getClass();
+ }
+
+ public Object getManaged()
+ {
+ return managed;
+ }
+
+ public void setManaged(Object managed)
+ {
+ this.managed = managed;
+ }
+
+ @Override
+ public Object get(PropertyBinding property)
+ {
+ return BindingUtils.get(property, managed);
+ }
+
+ @Override
+ public Object[] invoke(MethodBinding method, Object... args)
+ {
+ return BindingUtils.invoke(method, managed, args);
+ }
+
+ @Override
+ public void set(PropertyBinding property, Object value)
+ {
+ BindingUtils.set(property, value, managed);
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFAgent.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFAgent.java
new file mode 100644
index 0000000000..b9fcf40fc1
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFAgent.java
@@ -0,0 +1,34 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.agent.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Target(ElementType.FIELD)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFAgent
+{
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java
new file mode 100644
index 0000000000..314f2a7e68
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.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.agent.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Tells the QMF Agent that this object will be passed as a QMF event. This will
+ * cause only properties to be sent across the wire.
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFEvent
+{
+ String eventName();
+
+ String packageName();
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java
new file mode 100644
index 0000000000..db6cb0412f
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.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.agent.annotations;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Causes the property which is annotated to not be added to the QMF schema when
+ * it is built.
+ */
+@Target(ElementType.METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFHide
+{
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java
new file mode 100644
index 0000000000..7d1713cdbe
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.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.agent.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Tells the QMF Agent that this object will be a managed object. This will
+ * allow users to query for it, as well as invoke methods on it.
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFObject
+{
+ String className();
+
+ String packageName();
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java
new file mode 100644
index 0000000000..f309fa95b5
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.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.agent.annotations;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Controls the QMF schema which is generated for this property.
+ */
+@Target(ElementType.FIELD)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFProperty
+{
+ boolean optional() default false;
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java
new file mode 100644
index 0000000000..bb9b87805d
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.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.agent.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Augements the schema generation process to look for known subclasses of a
+ * type. Modeled after the JAXB @XMLSeeAlso.
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFSeeAlso
+{
+ Class[] value();
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java
new file mode 100644
index 0000000000..8da1e15124
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.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.agent.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Tells the QMF Agent that this object will be a type only This will cause only
+ * properties to be sent across the wire.
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFType
+{
+ String className();
+
+ String packageName();
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java
new file mode 100644
index 0000000000..a60178e8b9
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java
@@ -0,0 +1,213 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.agent.binding;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.annotations.QMFEvent;
+import org.apache.qpid.agent.annotations.QMFObject;
+import org.apache.qpid.agent.annotations.QMFSeeAlso;
+import org.apache.qpid.agent.annotations.QMFType;
+
+/**
+ * Contains the mappings from java classes to QMF schema and back. There is one
+ * context per agent, and it contains all the metadata.
+ */
+public class BindingContext
+{
+ private static Log log = LogFactory.getLog(BindingContext.class);
+ private Map<Key, ClassBinding> classes = new Hashtable<Key, ClassBinding>();
+ private ArrayList<String> packages = new ArrayList<String>();
+
+ static class Key
+ {
+ String packageName = "";
+ String className = "";
+ boolean object = false;
+
+ @Override
+ public int hashCode()
+ {
+ return (packageName + "." + className).hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ return (obj instanceof Key
+ && (((Key) obj).packageName.equals(packageName)) && (((Key) obj).className
+ .equals(className)));
+ }
+ }
+
+ public BindingContext()
+ {
+ Key key = new Key();
+ key.className = "Object";
+ key.packageName = "org.apache.qmf";
+ key.object = false;
+ ClassBinding cb = new ClassBinding("org.apache.qmf", "Object",
+ Object.class, false, this);
+ classes.put(key, cb);
+ packages.add("org.apache.qmf");
+ }
+
+ public ClassBinding getClassBinding(Class clazz)
+ {
+ return classes.get(getClassKey(clazz));
+ }
+
+ public ClassBinding getClassBinding(String packageName, String className)
+ {
+ Key key = new Key();
+ key.packageName = packageName;
+ key.className = className;
+ return classes.get(key);
+ }
+
+ public ClassBinding register(Class cls)
+ {
+ String name = cls.getName();
+ ClassBinding cb = getClassBinding(cls);
+ if (cb == null)
+ {
+ Key key = getClassKey(cls);
+ // Create and store the internal representations
+ if (cls.isEnum())
+ {
+ cb = new EnumBinding(key.packageName, key.className, cls,
+ key.object, this);
+ } else
+ {
+ cb = new ClassBinding(key.packageName, key.className, cls,
+ key.object, this);
+ }
+ log.debug(String.format(
+ "Added class binding '%s' in package %s for class %s'",
+ key.className, key.packageName, cls.getCanonicalName()));
+ classes.put(key, cb);
+ if (!packages.contains(key.packageName))
+ {
+ packages.add(key.packageName);
+ }
+ // Parse the methods after adding the class to avoid recursion
+ cb.parse();
+ // See if there are other classes which should be looked at
+ QMFSeeAlso seeAlso = (QMFSeeAlso) cls
+ .getAnnotation(QMFSeeAlso.class);
+ if (seeAlso != null)
+ {
+ for (Class seeAlsoCls : seeAlso.value())
+ {
+ this.register(seeAlsoCls);
+ }
+ }
+ }
+ return cb;
+ }
+
+ public TypeBinding getTypeBinding(Class cls)
+ {
+ // Look for a built in type
+ TypeBinding type = QMFTypeBinding.forClass(cls);
+ // Have we seen it before?
+ if (type == null)
+ {
+ type = this.getClassBinding(cls);
+ }
+ if ((type == null) && List.class.isAssignableFrom(cls))
+ {
+ type = new ListBinding(this, cls);
+ }
+ if ((type == null) && Map.class.isAssignableFrom(cls))
+ {
+ type = new MapBinding(this, cls);
+ }
+ // Add it, but since we have not seen it before do not expose methods
+ if (type == null)
+ {
+ type = this.register(cls);
+ }
+ return type;
+ }
+
+ // FIXME: Need to store these keys off so we dont create alot of objects
+ protected Key getClassKey(Class cls)
+ {
+ Key key = new Key();
+ QMFObject objAnnotation = (QMFObject) cls
+ .getAnnotation(QMFObject.class);
+ if (objAnnotation != null)
+ {
+ key.className = objAnnotation.className();
+ key.packageName = objAnnotation.packageName();
+ key.object = true;
+ } else
+ {
+ QMFType typeAnnotation = (QMFType) cls.getAnnotation(QMFType.class);
+ if (typeAnnotation != null)
+ {
+ key.className = typeAnnotation.className();
+ key.packageName = typeAnnotation.packageName();
+ } else
+ {
+ QMFEvent eventAnnotation = (QMFEvent) cls
+ .getAnnotation(QMFEvent.class);
+ if (eventAnnotation != null)
+ {
+ key.className = eventAnnotation.eventName();
+ key.packageName = eventAnnotation.packageName();
+ } else
+ {
+ // If this is Object, we return the fake
+ // object value
+ if (cls == Object.class)
+ {
+ key.className = "Object";
+ key.packageName = "org.apache.qmf";
+ } else
+ {
+ String name = cls.getName();
+ int lastDot = name.lastIndexOf('.');
+ key.className = name.substring(lastDot + 1);
+ key.packageName = name.substring(0, lastDot);
+ }
+ }
+ }
+ }
+ return key;
+ }
+
+ public ArrayList<String> getPackages()
+ {
+ return packages;
+ }
+
+ public Collection<ClassBinding> getAllBindings()
+ {
+ return classes.values();
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java
new file mode 100644
index 0000000000..f8e436290c
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.agent.binding;
+
+/**
+ * ManagedException
+ *
+ */
+public class BindingException extends RuntimeException
+{
+ private static final long serialVersionUID = -7350845525748113340L;
+
+ public BindingException(Throwable t)
+ {
+ super(t);
+ }
+
+ public BindingException()
+ {
+ super();
+ }
+
+ public BindingException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ public BindingException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java
new file mode 100644
index 0000000000..14f3fda0f1
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.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.agent.binding;
+
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class BindingUtils
+{
+ private static Log log = LogFactory.getLog(BindingUtils.class);
+
+ public static Object get(PropertyBinding property, Object managed)
+ {
+ String name = property.getName();
+ return get(name, managed);
+ }
+
+ public static void set(PropertyBinding property, Object value,
+ Object managed)
+ {
+ String name = property.getName();
+ TypeBinding type = property.getType();
+ try
+ {
+ Method meth = managed.getClass().getMethod(accessor("set", name),
+ type.getJavaClass());
+ meth.invoke(managed, value);
+ } catch (NoSuchMethodException e)
+ {
+ throw new BindingException(e);
+ } catch (IllegalAccessException e)
+ {
+ throw new BindingException(e);
+ } catch (InvocationTargetException e)
+ {
+ throw new BindingException(e.getTargetException());
+ }
+ }
+
+ public static Object[] invoke(MethodBinding method, Object managed,
+ Object... args)
+ {
+ log.debug(String.format("Invoking %s on %s", method.getName(), managed
+ .getClass()));
+ List<ParameterBinding> in = method.getInParameters();
+ List<ParameterBinding> out = method.getOutParameters();
+ Class<?>[] classes = new Class<?>[in.size()];
+ int idx = 0;
+ for (ParameterBinding p : in)
+ {
+ classes[idx++] = p.getType().getJavaClass();
+ }
+ Object result;
+ try
+ {
+ Method meth = managed.getClass().getMethod(method.getName(),
+ classes);
+ result = meth.invoke(managed, args);
+ } catch (NoSuchMethodException e)
+ {
+ throw new BindingException(e);
+ } catch (IllegalAccessException e)
+ {
+ throw new BindingException(e);
+ } catch (InvocationTargetException e)
+ {
+ throw new BindingException(e.getTargetException());
+ }
+ Object[] results = new Object[out.size()];
+ // XXX: need better way to distinguish this case
+ if (out.size() == 1 && out.get(0).getName().equals("result"))
+ {
+ results[0] = result;
+ } else
+ {
+ for (int i = 0; i < results.length; i++)
+ {
+ results[i] = get(out.get(i).getName(), result);
+ }
+ }
+ return results;
+ }
+
+ public static String accessor(String pfx, String property)
+ {
+ return pfx + Character.toUpperCase(property.charAt(0))
+ + property.substring(1);
+ }
+
+ public static Object get(String name, Object obj)
+ {
+ Object returnValue = null;
+ try
+ {
+ BeanInfo info = Introspector.getBeanInfo(obj.getClass());
+ PropertyDescriptor[] pds = info.getPropertyDescriptors();
+ for (PropertyDescriptor pd : pds)
+ {
+ if (pd.getName().equals(name))
+ {
+ Method getMethod = pd.getReadMethod();
+ returnValue = getMethod.invoke(obj);
+ break;
+ }
+ }
+ } catch (Exception e)
+ {
+ throw new BindingException(e);
+ }
+ return returnValue;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java
new file mode 100644
index 0000000000..469939a52f
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java
@@ -0,0 +1,601 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.agent.binding;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.annotations.QMFEvent;
+import org.apache.qpid.agent.annotations.QMFObject;
+import org.apache.qpid.agent.annotations.QMFProperty;
+import org.apache.qpid.agent.annotations.QMFSeeAlso;
+import org.apache.qpid.agent.annotations.QMFType;
+import org.apache.qpid.agent.annotations.QMFHide;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding information from a custom java class to a QMF schema
+ */
+public class ClassBinding implements TypeBinding
+{
+ private static final Log log = LogFactory.getLog(ClassBinding.class);
+
+ private static enum MethodType
+ {
+ READ_ONLY, READ_WRITE, METHOD, IGNORE
+ }
+
+ protected boolean exposeBehaviour = true;
+ protected String pkg;
+ protected BindingContext bctx;
+ protected String name;
+ protected ArrayList<PropertyBinding> properties = new ArrayList<PropertyBinding>();
+ protected ArrayList<MethodBinding> methods = new ArrayList<MethodBinding>();
+ protected Map<String, MethodBinding> methodsByName = new HashMap<String, MethodBinding>();
+ protected Class javaClass;
+ protected short kind = 1;
+ protected byte hash[] = null;
+ protected ClassBinding superType = null;
+
+ public ClassBinding(String pkg, String name, Class cls,
+ boolean exposeBehaviour, BindingContext bctx)
+ {
+ this.pkg = pkg;
+ this.name = name;
+ this.bctx = bctx;
+ this.javaClass = cls;
+ this.exposeBehaviour = exposeBehaviour;
+ }
+
+ protected MethodType classify(Class<?> cls, Method m)
+ {
+ String name = m.getName();
+ MethodType returnValue = MethodType.METHOD;
+ String propPrefixes[] =
+ { "get", "is" };
+ for (String prefix : propPrefixes)
+ {
+ if (name.startsWith(prefix) && m.getParameterTypes().length == 0)
+ {
+ try
+ {
+ Class<?> type = m.getReturnType();
+ Method setter = cls.getMethod("set"
+ + name.substring(prefix.length()), type);
+ returnValue = MethodType.READ_WRITE;
+ } catch (NoSuchMethodException e)
+ {
+ returnValue = MethodType.READ_ONLY;
+ }
+ break;
+ }
+ }
+ return returnValue;
+ }
+
+ protected String property(Method m)
+ {
+ String name = m.getName();
+ String propPrefixes[] =
+ { "get", "is" };
+ for (String prefix : propPrefixes)
+ {
+ if (name.startsWith(prefix) && m.getParameterTypes().length == 0)
+ {
+ String sfx = name.substring(prefix.length());
+ return Character.toLowerCase(sfx.charAt(0)) + sfx.substring(1);
+ }
+ }
+ // If we got here, it is n invalid property
+ throw new IllegalArgumentException("" + m);
+ }
+
+ protected ArrayList<Method> getMethods(Class cls)
+ {
+ ArrayList returnValue = new ArrayList();
+ ArrayList nameList = new ArrayList();
+ if ((cls != null) && (!cls.equals(Object.class)))
+ {
+ for (Method m : cls.getDeclaredMethods())
+ {
+ if (m.getAnnotation(QMFHide.class) == null)
+ // && (!Modifier.isAbstract(m.getModifiers())))
+ {
+ returnValue.add(m);
+ nameList.add(m.getName());
+ }
+ }
+ // Look at the superclass, if it is also a
+ // QMF object then stop.
+ if (!this.hasQMFSupertype(cls))
+ {
+ for (Method m : this.getMethods(cls.getSuperclass()))
+ {
+ if (!nameList.contains(m.getName()))
+ {
+ returnValue.add(m);
+ nameList.add(m.getName());
+ }
+ }
+ }
+ }
+ return returnValue;
+ }
+
+ protected boolean hasQMFSupertype(Class cls)
+ {
+ boolean returnValue = false;
+ Class superType = cls.getSuperclass();
+ if (superType != null)
+ {
+ if ((superType.getAnnotation(QMFObject.class) != null)
+ || (superType.getAnnotation(QMFType.class) != null)
+ || (superType.getAnnotation(QMFSeeAlso.class) != null)
+ || (superType.getAnnotation(QMFEvent.class) != null))
+ {
+ returnValue = true;
+ }
+ }
+ return returnValue;
+ }
+
+ protected boolean isOptional(Method m, TypeBinding type)
+ {
+ boolean returnValue = false;
+ // Look for the annotaiton first
+ QMFProperty ann = m.getAnnotation(QMFProperty.class);
+ if (ann != null)
+ {
+ returnValue = ann.optional();
+ } else
+ {
+ returnValue = type.optionalDefault();
+ }
+ return returnValue;
+ }
+
+ public ClassBinding parse()
+ {
+ log.debug(String.format(
+ "Parsing class binding '%s' for package '%s' from class %s",
+ name, pkg, javaClass.getName()));
+ for (Method m : this.getMethods(javaClass))
+ {
+ String mname = m.getName();
+ Class<?> type = m.getReturnType();
+ switch (classify(javaClass, m))
+ {
+ case READ_ONLY:
+ TypeBinding tb = bctx.getTypeBinding(type);
+ boolean optional = isOptional(m, tb);
+ properties.add(new PropertyBinding(property(m), tb,
+ PropertyBinding.READ_ONLY, optional));
+ break;
+ case READ_WRITE:
+ TypeBinding tbnd = bctx.getTypeBinding(type);
+ boolean opt = isOptional(m, tbnd);
+ properties.add(new PropertyBinding(property(m), tbnd,
+ PropertyBinding.READ_WRITE, opt));
+ break;
+ case METHOD:
+ // Only expose methods if told to
+ if (exposeBehaviour)
+ {
+ List<ParameterBinding> params = new ArrayList<ParameterBinding>();
+ int arg = 0;
+ for (Class pcls : m.getParameterTypes())
+ {
+ params.add(new ParameterBinding("arg" + arg++, bctx
+ .getTypeBinding(pcls), true, false));
+ }
+ if (type != void.class)
+ {
+ params.add(new ParameterBinding("result", bctx
+ .getTypeBinding(type), false, true));
+ }
+ methods.add(new MethodBinding(mname, params));
+ }
+ break;
+ case IGNORE:
+ break;
+ }
+ }
+ for (MethodBinding m : methods)
+ {
+ methodsByName.put(m.getName(), m);
+ }
+ QMFEvent eventAnnotation = (QMFEvent) javaClass
+ .getAnnotation(QMFEvent.class);
+ if (eventAnnotation != null)
+ {
+ kind = 2; // Event Type
+ }
+ // if (this.hasQMFSupertype(javaClass)) {
+ if ((javaClass.getSuperclass() != Object.class)
+ && (javaClass.getSuperclass() != null))
+ {
+ superType = bctx.register(javaClass.getSuperclass());
+ }
+ return this;
+ }
+
+ public String getPackage()
+ {
+ return pkg;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public List<PropertyBinding> getProperties()
+ {
+ return properties;
+ }
+
+ public List<PropertyBinding> getAllProperties()
+ {
+ if (this.superType == null)
+ {
+ return properties;
+ } else
+ {
+ List<PropertyBinding> newList = new ArrayList<PropertyBinding>(
+ properties);
+ for (PropertyBinding p : superType.getAllProperties())
+ {
+ if (!newList.contains(p))
+ {
+ newList.add(p);
+ }
+ }
+ return newList;
+ }
+ }
+
+ public List<MethodBinding> getMethods()
+ {
+ return methods;
+ }
+
+ public MethodBinding getMethod(String name)
+ {
+ return methodsByName.get(name);
+ }
+
+ // Use this format
+ // bytes value
+ // 0-3 package name
+ // 4-7 class name
+ // 8-11 property signature hash
+ // 12-15 method signature hash
+ // FIXME: Hash codes seem to mess things up
+ public byte[] getSchemaHash()
+ {
+ if (null == hash)
+ {
+ hash = new byte[16];
+ StringBuilder blder = new StringBuilder();
+ int packageHash = pkg.hashCode();
+ int classHash = name.hashCode();
+ int propertyHash = 0;
+ int methodHash = 0;
+ for (PropertyBinding p : properties)
+ {
+ blder.append(p.getName()).append(":").append(
+ p.getType().getCode()).append(":")
+ .append(p.getAccess()).append(":").append(
+ p.isOptional());
+ }
+ propertyHash = blder.toString().hashCode();
+ blder = new StringBuilder();
+ for (MethodBinding m : methods)
+ {
+ blder.append(m.getName());
+ for (ParameterBinding p : m.getParameters())
+ {
+ String direction = p.isIn() ? "in" : "out";
+ blder.append(":").append(p.getName()).append(":").append(
+ direction).append(":")
+ .append(p.getType().getCode());
+ }
+ }
+ methodHash = blder.toString().hashCode();
+ hash[0] = (byte) (packageHash >> 24);
+ hash[1] = (byte) (packageHash >> 16);
+ hash[2] = (byte) (packageHash >> 8);
+ hash[3] = (byte) (packageHash);
+ hash[4] = (byte) (classHash >> 24);
+ hash[5] = (byte) (classHash >> 16);
+ hash[6] = (byte) (classHash >> 8);
+ hash[7] = (byte) (classHash);
+ hash[8] = (byte) (propertyHash >> 24);
+ hash[9] = (byte) (propertyHash >> 16);
+ hash[10] = (byte) (propertyHash >> 8);
+ hash[11] = (byte) (propertyHash);
+ hash[12] = (byte) (methodHash >> 24);
+ hash[13] = (byte) (methodHash >> 16);
+ hash[14] = (byte) (methodHash >> 8);
+ hash[15] = (byte) (methodHash);
+ }
+ return hash;
+ }
+
+ public void encode(Encoder enc)
+ {
+ log.debug(String.format("encoding %s %s with superclass %s", this
+ .getRefClass(), this.getRefPackage(), superType));
+ enc.writeUint8(kind); // kind
+ enc.writeStr8(pkg);
+ enc.writeStr8(name);
+ enc.writeBin128(this.getSchemaHash()); // schema hash
+ // Send true (1) if we have a super-type
+ //if (superType == null)
+ //{
+ // enc.writeUint8((short) 0);
+ //} else
+ //{
+ // enc.writeUint8((short) 1);
+ //}
+ enc.writeUint16(properties.size());
+ // Events do not have the method size sent
+ if (kind == 1)
+ {
+ enc.writeUint16(0);
+ enc.writeUint16(methods.size());
+ }
+ // Add the super type information if we have it
+ //if (superType != null)
+ //{
+ // enc.writeStr8(superType.pkg);
+ // enc.writeStr8(superType.name);
+ // enc.writeBin128(superType.getSchemaHash()); // schema hash
+ //}
+ for (PropertyBinding p : properties)
+ {
+ log.trace("encoding property " + p.getName());
+ p.encode(enc);
+ }
+ for (MethodBinding m : methods)
+ {
+ m.encode(enc);
+ }
+ }
+
+ // Type Binding functions
+ public short getCode()
+ {
+ return (short) 20;
+ }
+
+ public Class<?> getJavaClass()
+ {
+ return javaClass;
+ }
+
+ public Object decode(Decoder dec)
+ {
+ // FIXME This only works with POJOs
+ short typeCode = dec.readUint8();
+ log.trace("Type code: " + typeCode);
+ if (typeCode == 20)
+ {
+ String packageName = dec.readStr8();
+ String className = dec.readStr8();
+ log
+ .debug(String
+ .format(
+ "Decoding an object for package %s class %s with bindings for %s %s",
+ packageName, className, this.pkg, this.name));
+ byte schemaHash[] = dec.readBin128();
+ // Check to see that this is me, and not a subclass
+ if (packageName.equals(this.pkg) && className.equals(this.name))
+ {
+ return decodeWithNoHeaders(dec);
+ } else
+ {
+ ClassBinding mcls = bctx
+ .getClassBinding(packageName, className);
+ return mcls.decodeWithNoHeaders(dec);
+ }
+ } else
+ {
+ TypeBinding tb = QMFTypeBinding.getType(typeCode);
+ return tb.decode(dec);
+ }
+ }
+
+ protected Object decodeWithNoHeaders(Decoder dec)
+ {
+ Object instance = null;
+ try
+ {
+ log.trace("Creating a new instance of " + this.javaClass.getName());
+ instance = this.javaClass.newInstance();
+ } catch (Exception e)
+ {
+ log.error("Could not instantiate object of class"
+ + this.javaClass.getName());
+ throw new BindingException(e);
+ }
+ List<String> excludes = this.processPresenceMasks(dec);
+ for (PropertyBinding p : getAllProperties())
+ {
+ if (!excludes.contains(p.getName()))
+ {
+ Object value = p.getType().decode(dec);
+ BindingUtils.set(p, value, instance);
+ }
+ }
+ return instance;
+ }
+
+ protected List<String> processPresenceMasks(Decoder dec)
+ {
+ List<String> excludes = new ArrayList<String>();
+ short bit = 0;
+ short mask = 0;
+ for (PropertyBinding prop : properties)
+ {
+ if (prop.isOptional())
+ {
+ if (bit == 0)
+ {
+ mask = dec.readUint8();
+ bit = 1;
+ }
+ if ((mask & bit) == 0)
+ {
+ log.trace("Going in exclude " + prop.getName());
+ excludes.add(prop.getName());
+ }
+ bit *= 2;
+ if (bit == 256)
+ {
+ bit = 0;
+ }
+ }
+ }
+ return excludes;
+ }
+
+ public void encode(Encoder enc, Object value)
+ {
+ // if the object is null, assume this is the
+ // correct class
+ if (value == null || (value.getClass().equals(this.javaClass)))
+ {
+ String pkg = getPackage();
+ String cls = getName();
+ log.debug(String.format("Encoding class %s:%s", pkg, cls));
+ enc.writeUint8(this.getCode());
+ enc.writeStr8(pkg);
+ enc.writeStr8(cls);
+ enc.writeBin128(this.getSchemaHash());
+ short bit = 0;
+ short mask = 0;
+ if (value != null)
+ {
+ // Encode the property presence masks first.
+ // if this is not an event
+ if (!isEvent())
+ {
+ for (PropertyBinding p : getAllProperties())
+ {
+ if (p.isOptional())
+ {
+ Object pValue = BindingUtils.get(p, value);
+ if (bit == 0)
+ bit = 1;
+ if (pValue != null)
+ {
+ mask |= bit;
+ }
+ if (bit == 128)
+ {
+ enc.writeUint8(mask);
+ bit = 0;
+ mask = 0;
+ } else
+ {
+ bit = (short) (bit << 1);
+ }
+ }
+ }
+ if (bit != 0)
+ {
+ enc.writeUint8(mask);
+ }
+ }
+ // Now put the actual properties
+ for (PropertyBinding p : getAllProperties())
+ {
+ Object pValue = BindingUtils.get(p, value);
+ if (!p.isOptional() || !(pValue == null))
+ {
+ log.trace(String.format("Encoding property %s", p
+ .getName()));
+ p.getType().encode(enc, pValue);
+ }
+ }
+ }
+ log.debug(String.format("Done with %s:%s", pkg, cls));
+ } else
+ {
+ TypeBinding tb = bctx.getTypeBinding(value.getClass());
+ if (tb == null)
+ {
+ throw new BindingException(String.format(
+ "No class named %s defined for this context ", value
+ .getClass()));
+ } else
+ {
+ if (tb.isNative())
+ {
+ enc.writeUint8(tb.getCode());
+ }
+ tb.encode(enc, value);
+ }
+ }
+ }
+
+ public boolean isNative()
+ {
+ return false;
+ }
+
+ public boolean optionalDefault()
+ {
+ return true;
+ }
+
+ public String getRefClass()
+ {
+ return this.name;
+ }
+
+ public String getRefPackage()
+ {
+ return this.pkg;
+ }
+
+ public short getKind()
+ {
+ return kind;
+ }
+
+ public boolean isEvent()
+ {
+ return kind == 2;
+ }
+
+ public void setKind(short kind)
+ {
+ this.kind = kind;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java
new file mode 100644
index 0000000000..dcb619b736
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.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.agent.binding;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding information from a java enum to a QMF schema
+ */
+public class EnumBinding extends ClassBinding
+{
+ private static Log log = LogFactory.getLog(EnumBinding.class);
+
+ public EnumBinding(String pkg, String name, Class cls,
+ boolean exposeBehaviour, BindingContext bctx)
+ {
+ super(pkg, name, cls, exposeBehaviour, bctx);
+ }
+
+ @Override
+ public void encode(Encoder enc)
+ {
+ enc.writeUint8((short) 1); // kind
+ enc.writeStr8(pkg);
+ enc.writeStr8(name);
+ enc.writeBin128(new byte[16]); // schema hash
+ // FIXME Is there a way to send the valid types?
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ if (value != null)
+ {
+ enc.writeStr16(value.toString());
+ } else
+ {
+ enc.writeStr16("");
+ }
+ }
+
+ @Override
+ public Object decode(Decoder dec)
+ {
+ // FIXME This only works with POJOs
+ Object instance = null;
+ String value = null;
+ try
+ {
+ value = dec.readStr16();
+ if ((value != null) && (!value.isEmpty()))
+ {
+ instance = Enum.valueOf((Class<Enum>) this.getJavaClass(),
+ value);
+ }
+ } catch (Exception e)
+ {
+ log.error(String.format(
+ "Could not create an enum of type %s with value %s",
+ this.javaClass.getName(), value));
+ throw new BindingException(e);
+ }
+ return instance;
+ }
+
+ // Make this look like a String
+ @Override
+ public short getCode()
+ {
+ return (short) 7;
+ }
+
+ @Override
+ public EnumBinding parse()
+ {
+ log.debug(String.format(
+ "Parsing enum binding '%s' for package '%s' from class %s",
+ name, pkg, javaClass.getName()));
+ return this;
+ }
+
+ @Override
+ public boolean optionalDefault()
+ {
+ return false;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java
new file mode 100644
index 0000000000..a3658a812c
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java
@@ -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.
+ *
+ */
+package org.apache.qpid.agent.binding;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding information from a java list to a QMF schema.
+ */
+public class ListBinding implements TypeBinding
+{
+ private static Log log = LogFactory.getLog(ListBinding.class);
+ protected BindingContext bctx;
+ protected Class javaClass;
+
+ public ListBinding(BindingContext bctx, Class javaClass)
+ {
+ this.bctx = bctx;
+ this.javaClass = javaClass;
+ }
+
+ public void encode(Encoder enc, Object value)
+ {
+ List list = (List) value;
+ BBEncoder newEncoder = new BBEncoder(10);
+ if (list != null)
+ {
+ newEncoder.writeUint32(list.size());
+ for (Object obj : list)
+ {
+ TypeBinding type = bctx.getTypeBinding(obj.getClass());
+ newEncoder.writeUint8(type.getCode());
+ type.encode(newEncoder, obj);
+ }
+ } else
+ {
+ newEncoder.writeUint32(0);
+ }
+ enc.writeVbin32(newEncoder.buffer().array());
+ }
+
+ public Object decode(Decoder dec)
+ {
+ List list = null;
+ try
+ {
+ list = (List) javaClass.newInstance();
+ } catch (Exception e)
+ {
+ throw new BindingException(
+ "Could not create a List implementation for "
+ + javaClass.getName(), e);
+ }
+ BBDecoder newDecoder = new BBDecoder();
+ newDecoder.init(ByteBuffer.wrap(dec.readVbin32()));
+ long count = newDecoder.readUint32();
+ while (count > 0)
+ {
+ short typeCode = newDecoder.readUint8();
+ TypeBinding type = QMFTypeBinding.getType(typeCode);
+ if (type == null)
+ {
+ type = bctx.getTypeBinding(Object.class);
+ }
+ list.add(type.decode(newDecoder));
+ count -= 1;
+ }
+ return list;
+ }
+
+ // QMF List Type
+ public short getCode()
+ {
+ return (short) 21;
+ }
+
+ @Override
+ public Class<?> getJavaClass()
+ {
+ return javaClass;
+ }
+
+ @Override
+ public String getRefClass()
+ {
+ return null;
+ }
+
+ @Override
+ public String getRefPackage()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean isNative()
+ {
+ return true;
+ }
+
+ public boolean optionalDefault()
+ {
+ return false;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java
new file mode 100644
index 0000000000..02d562a59a
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.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.agent.binding;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding information from a java Map to a QMF schema.
+ */
+public class MapBinding implements TypeBinding
+{
+ private static Log log = LogFactory.getLog(MapBinding.class);
+ protected BindingContext bctx;
+ protected Class javaClass;
+
+ public MapBinding(BindingContext bctx, Class javaClass)
+ {
+ this.bctx = bctx;
+ this.javaClass = javaClass;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void encode(Encoder enc, Object value)
+ {
+ Map map = (Map) value;
+ enc.writeMap(map);
+ }
+
+ public Object decode(Decoder dec)
+ {
+ Map map = dec.readMap();
+ return map;
+ }
+
+ // QMF List Type
+ public short getCode()
+ {
+ return (short) 15;
+ }
+
+ @Override
+ public Class<?> getJavaClass()
+ {
+ return javaClass;
+ }
+
+ @Override
+ public String getRefClass()
+ {
+ return null;
+ }
+
+ @Override
+ public String getRefPackage()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean isNative()
+ {
+ return true;
+ }
+
+ public boolean optionalDefault()
+ {
+ return false;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java
new file mode 100644
index 0000000000..fc05c7393a
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java
@@ -0,0 +1,91 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.agent.binding;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Metadata for mapping a method to a QMF schema
+ */
+public class MethodBinding
+{
+ private final String name;
+ private final List<ParameterBinding> parameters;
+ private final List<ParameterBinding> inParameters = new ArrayList<ParameterBinding>();
+ private final List<ParameterBinding> outParameters = new ArrayList<ParameterBinding>();
+ private Log log = LogFactory.getLog(MethodBinding.class);
+
+ public MethodBinding(String name, List<ParameterBinding> parameters)
+ {
+ this.name = name;
+ this.parameters = parameters;
+ for (ParameterBinding p : parameters)
+ {
+ if (p.isIn())
+ {
+ inParameters.add(p);
+ }
+ if (p.isOut())
+ {
+ outParameters.add(p);
+ }
+ }
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public List<ParameterBinding> getParameters()
+ {
+ return parameters;
+ }
+
+ public List<ParameterBinding> getInParameters()
+ {
+ return inParameters;
+ }
+
+ public List<ParameterBinding> getOutParameters()
+ {
+ return outParameters;
+ }
+
+ void encode(Encoder enc)
+ {
+ Map map = new HashMap();
+ map.put("name", name);
+ map.put("argCount", parameters.size());
+ enc.writeMap(map);
+ for (ParameterBinding p : parameters)
+ {
+ p.encode(enc);
+ }
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java
new file mode 100644
index 0000000000..7362976e0e
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.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.agent.binding;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Metadata for mapping a method argument to a QMF schema
+ */
+public class ParameterBinding
+{
+ private final String name;
+ private final TypeBinding type;
+ private final boolean in;
+ private final boolean out;
+
+ public ParameterBinding(String name, TypeBinding type, boolean in,
+ boolean out)
+ {
+ this.name = name;
+ this.type = type;
+ this.in = in;
+ this.out = out;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public TypeBinding getType()
+ {
+ return type;
+ }
+
+ public boolean isIn()
+ {
+ return in;
+ }
+
+ public boolean isOut()
+ {
+ return out;
+ }
+
+ void encode(Encoder enc)
+ {
+ Map map = new HashMap();
+ map.put("name", name);
+ map.put("type", type.getCode());
+ map.put("dir", (in ? "I" : "") + (out ? "O" : ""));
+ if (!type.isNative())
+ {
+ map.put("refClass", type.getRefClass());
+ map.put("refPackage", type.getRefPackage());
+ }
+ enc.writeMap(map);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (in ? 1231 : 1237);
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + (out ? 1231 : 1237);
+ result = prime * result + ((type == null) ? 0 : type.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ParameterBinding other = (ParameterBinding) obj;
+ if (in != other.in)
+ return false;
+ if (name == null)
+ {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (out != other.out)
+ return false;
+ if (type == null)
+ {
+ if (other.type != null)
+ return false;
+ } else if (!type.equals(other.type))
+ return false;
+ return true;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java
new file mode 100644
index 0000000000..604d66c818
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java
@@ -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.
+ *
+ */
+package org.apache.qpid.agent.binding;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Metadata for mapping a java property (getter/setter) to a QMF schema
+ */
+public class PropertyBinding
+{
+ private static Log log = LogFactory.getLog(PropertyBinding.class);
+ public final static int READ_CREATE = 1;
+ public final static int READ_WRITE = 2;
+ public final static int READ_ONLY = 3;
+ private String name;
+ private TypeBinding type;
+ private int accessType;
+ private boolean optional;
+
+ public PropertyBinding(String name, TypeBinding type, int accessType,
+ boolean optional)
+ {
+ this.name = name;
+ this.type = type;
+ this.accessType = accessType;
+ this.optional = optional;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + accessType;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + ((type == null) ? 0 : type.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ PropertyBinding other = (PropertyBinding) obj;
+ if (accessType != other.accessType)
+ return false;
+ if (name == null)
+ {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (type == null)
+ {
+ if (other.type != null)
+ return false;
+ } else if (!type.equals(other.type))
+ return false;
+ return true;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public TypeBinding getType()
+ {
+ return type;
+ }
+
+ public int getAccess()
+ {
+ return accessType;
+ }
+
+ public boolean isIndex()
+ {
+ return false;
+ }
+
+ public boolean isOptional()
+ {
+ return optional;
+ }
+
+ void encode(Encoder enc)
+ {
+ Map map = new HashMap();
+ map.put("name", name);
+ map.put("type", type.getCode());
+ map.put("access", getAccess());
+ map.put("index", isIndex() ? 1 : 0);
+ map.put("optional", isOptional() ? 1 : 0);
+ if (!type.isNative())
+ {
+ map.put("refClass", type.getRefClass());
+ map.put("refPackage", type.getRefPackage());
+ }
+ enc.writeMap(map);
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java
new file mode 100644
index 0000000000..11ccf1b1a7
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java
@@ -0,0 +1,465 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.agent.binding;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Basic type mappings for QMF schema
+ */
+public abstract class QMFTypeBinding implements TypeBinding
+{
+ private static final Map<Class<?>, QMFTypeBinding> TYPES = new HashMap<Class<?>, QMFTypeBinding>();
+ private static final Map<Short, QMFTypeBinding> TYPES_BY_CODE = new HashMap<Short, QMFTypeBinding>();
+ static
+ {
+ new QMFTypeBinding(null, (short) 1)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Short.valueOf(dec.readUint8());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeUint8(((Number) value).shortValue());
+ }
+ };
+ new QMFTypeBinding(null, (short) 2)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Integer.valueOf(dec.readUint16());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeUint16(((Number) value).intValue());
+ }
+ };
+ new QMFTypeBinding(null, (short) 3)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Long.valueOf(dec.readUint32());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeUint32(((Number) value).longValue());
+ }
+ };
+ new QMFTypeBinding(null, (short) 4)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Long.valueOf(dec.readUint64());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeUint64(((Number) value).longValue());
+ }
+ };
+ new QMFTypeBinding(null, (short) 6) // short string
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readStr8();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ if (null == value)
+ value = "";
+ enc.writeStr8((String) value);
+ }
+ };
+ new QMFTypeBinding(String.class, (short) 7) // long string
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readStr16();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ if (null == value)
+ value = "";
+ enc.writeStr16((String) value);
+ }
+ };
+ new QMFTypeBinding(Date.class, (short) 8)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return new Date(dec.readDatetime());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeDatetime(((Date) value).getTime());
+ }
+ };
+ new QMFTypeBinding(Boolean.class, (short) 11)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Boolean.valueOf(dec.readUint8() != 0);
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ if (((Boolean) value).booleanValue())
+ {
+ enc.writeUint8((short) 1);
+ } else
+ {
+ enc.writeUint8((short) 0);
+ }
+ }
+
+ @Override
+ public short[] alternateTypes()
+ {
+ short[] types =
+ { 5 };
+ return types;
+ }
+ };
+ new QMFTypeBinding(boolean.class, (short) 11)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readUint8() != 0;
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ if (((Boolean) value).booleanValue())
+ {
+ enc.writeUint8((short) 1);
+ } else
+ {
+ enc.writeUint8((short) 0);
+ }
+ }
+ };
+ new QMFTypeBinding(Float.class, (short) 12)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Float.valueOf(dec.readFloat());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeFloat(((Number) value).floatValue());
+ }
+ };
+ new QMFTypeBinding(float.class, (short) 12)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readFloat();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeFloat(((Number) value).floatValue());
+ }
+ };
+ new QMFTypeBinding(Double.class, (short) 13)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Double.valueOf(dec.readDouble());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeDouble(((Number) value).doubleValue());
+ }
+ };
+ new QMFTypeBinding(double.class, (short) 13)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readDouble();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeDouble(((Number) value).doubleValue());
+ }
+ };
+ new QMFTypeBinding(UUID.class, (short) 14)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readUuid();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeUuid((UUID) value);
+ }
+ };
+ new QMFTypeBinding(byte.class, (short) 16)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readInt8();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeInt8(((Number) value).byteValue());
+ }
+ };
+ new QMFTypeBinding(Short.class, (short) 17)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Short.valueOf(dec.readInt16());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeInt16(((Number) value).shortValue());
+ }
+ };
+ new QMFTypeBinding(short.class, (short) 17)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readInt16();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeInt16(((Number) value).shortValue());
+ }
+ };
+ new QMFTypeBinding(Integer.class, (short) 18)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Integer.valueOf(dec.readInt32());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeInt32(((Number) value).intValue());
+ }
+ };
+ new QMFTypeBinding(int.class, (short) 18)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readInt32();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeInt32(((Number) value).intValue());
+ }
+ };
+ new QMFTypeBinding(Long.class, (short) 19)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Long.valueOf(dec.readInt64());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeInt64(((Number) value).longValue());
+ }
+ };
+ new QMFTypeBinding(long.class, (short) 19)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readInt64();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeInt64(((Number) value).longValue());
+ }
+ };
+ }
+
+ public static final QMFTypeBinding forClass(Class<?> cls)
+ {
+ QMFTypeBinding t = TYPES.get(cls);
+ return t;
+ }
+
+ public static final boolean isBound(Class<?> cls)
+ {
+ return TYPES.containsKey(cls);
+ }
+
+ public static QMFTypeBinding getType(short code)
+ {
+ return TYPES_BY_CODE.get(code);
+ }
+
+ private final Class<?> cls;
+ private final short code;
+
+ private QMFTypeBinding(Class<?> cls, short code)
+ {
+ this.cls = cls;
+ this.code = code;
+ if (cls != null)
+ {
+ TYPES.put(cls, this);
+ }
+ TYPES_BY_CODE.put(code, this);
+ for (short type : this.alternateTypes())
+ {
+ TYPES_BY_CODE.put(type, this);
+ }
+ }
+
+ public Class<?> getJavaClass()
+ {
+ return cls;
+ }
+
+ public short getCode()
+ {
+ return code;
+ }
+
+ public boolean isNative()
+ {
+ return true;
+ }
+
+ public boolean optionalDefault()
+ {
+ return false;
+ }
+
+ public String getRefClass()
+ {
+ return null;
+ }
+
+ public String getRefPackage()
+ {
+ return null;
+ }
+
+ public abstract Object decode(Decoder dec);
+
+ public abstract void encode(Encoder enc, Object value);
+
+ public short[] alternateTypes()
+ {
+ short[] types =
+ {};
+ return types;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((cls == null) ? 0 : cls.hashCode());
+ result = prime * result + code;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ QMFTypeBinding other = (QMFTypeBinding) obj;
+ if (cls == null)
+ {
+ if (other.cls != null)
+ return false;
+ } else if (!cls.equals(other.cls))
+ return false;
+ if (code != other.code)
+ return false;
+ return true;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java
new file mode 100644
index 0000000000..97ec943bfd
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.agent.binding;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding between Java Type and QMF type
+ */
+public interface TypeBinding
+{
+ public Object decode(Decoder dec);
+
+ public void encode(Encoder enc, Object value);
+
+ public Class<?> getJavaClass();
+
+ public short getCode();
+
+ public boolean isNative();
+
+ public String getRefClass();
+
+ public String getRefPackage();
+
+ public boolean optionalDefault();
+}
diff --git a/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java
new file mode 100644
index 0000000000..67095c809b
--- /dev/null
+++ b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.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.agent;
+
+import java.util.ArrayList;
+
+import org.apache.qpid.agent.annotations.QMFSeeAlso;
+import org.apache.qpid.agent.annotations.QMFType;
+
+/**
+ * Crumpet
+ *
+ */
+@QMFType(className = "Crumpet", packageName = "org.apache.test")
+@QMFSeeAlso(
+{ Pikelet.class })
+public class Crumpet
+{
+ private String foo = "fooValue";
+ private String bar = "barValue";
+ private ArrayList<String> ingredients = new ArrayList<String>();
+
+ public String getFoo()
+ {
+ return foo;
+ }
+
+ public void setFoo(String foo)
+ {
+ this.foo = foo;
+ }
+
+ public String getBar()
+ {
+ return bar;
+ }
+
+ public void setBar(String bar)
+ {
+ this.bar = bar;
+ }
+
+ public ArrayList<String> getIngredients()
+ {
+ return ingredients;
+ }
+
+ public void setIngredients(ArrayList<String> ingredients)
+ {
+ this.ingredients = ingredients;
+ }
+}
diff --git a/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java
new file mode 100644
index 0000000000..f039ab9baa
--- /dev/null
+++ b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java
@@ -0,0 +1,113 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.agent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.annotations.QMFObject;
+
+@QMFObject(className = "Muppet", packageName = "org.apache.test")
+public class Muppet extends Puppet
+{
+ private Log log = LogFactory.getLog(Muppet.class);
+
+ public String getSomething()
+ {
+ return "something";
+ }
+
+ public void doSomething(String str)
+ {
+ log.debug(String.format("doSomething: %s", str));
+ }
+
+ public String returnSomething()
+ {
+ log.debug("returning something");
+ return "asdf";
+ }
+
+ public Crumpet gimmieCrumpet(String asdf, int n, float f, Map foo)
+ {
+ log.debug(String
+ .format("mmm, crumpet: %s, %s, %s, %s", asdf, n, f, foo));
+ Crumpet crumpet = new Crumpet();
+ crumpet.getIngredients().add("Butter");
+ crumpet.getIngredients().add("Salt");
+ crumpet.getIngredients().add("Flour");
+ return crumpet;
+ }
+
+ public Crumpet gimmieCrumpet2()
+ {
+ Pikelet pik = new Pikelet();
+ pik.getIngredients().add("Butter");
+ pik.getIngredients().add("Salt");
+ pik.getIngredients().add("Eggs");
+ pik.getCrumpets().put("Crumpet1",
+ this.gimmieCrumpet("2121", 1, 1, null));
+ return pik;
+ }
+
+ public List gimmeLotsOfCrumpets()
+ {
+ log.debug("Asking for lots of Crumpets");
+ ArrayList<Crumpet> returnValue = new ArrayList<Crumpet>();
+ Crumpet crumpet = new Crumpet();
+ crumpet.getIngredients().add("Chocolate");
+ returnValue.add(crumpet);
+ crumpet = new Crumpet();
+ crumpet.getIngredients().add("Pecans");
+ returnValue.add(crumpet);
+ crumpet = new Pikelet();
+ crumpet.getIngredients().add("Poached Eggs");
+ returnValue.add(crumpet);
+ return returnValue;
+ }
+
+ public int divideByZero()
+ {
+ return 1 / 0;
+ }
+
+ public Crumpet takeCrumpet(Crumpet newCrumpet)
+ {
+ log.debug(String.format("I gots me a crumpet: foo: '%s' bar: '%s'",
+ newCrumpet.getFoo(), newCrumpet.getBar()));
+ log.debug("My crumpet's class is " + newCrumpet.getClass().getName());
+ for (String ingredient : newCrumpet.getIngredients())
+ {
+ log.debug("My crumpet is made of " + ingredient);
+ }
+ return newCrumpet;
+ }
+
+ public Object takeSomething(Object obj)
+ {
+ log.debug(String.format("I gots me a something: '%s'", obj.getClass()
+ .getName()));
+ return obj;
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java
index 340f00fed8..f820fa6258 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java
+++ b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java
@@ -18,33 +18,35 @@
* under the License.
*
*/
-package org.apache.qpid.test.utils;
+package org.apache.qpid.agent;
-import org.apache.log4j.Logger;
-import org.apache.qpid.server.Broker;
+import java.util.HashMap;
-public class InternalBrokerHolder implements BrokerHolder
+import org.apache.qpid.agent.annotations.QMFType;
+
+@QMFType(className = "Pikelet", packageName = "org.apache.test")
+public class Pikelet extends Crumpet
{
- private static final Logger LOGGER = Logger.getLogger(InternalBrokerHolder.class);
- private final Broker _broker;
+ protected String shape;
+ HashMap<String, Crumpet> crumpets = new HashMap<String, Crumpet>();
- public InternalBrokerHolder(final Broker broker)
+ public String getShape()
{
- if(broker == null)
- {
- throw new IllegalArgumentException("Broker must not be null");
- }
-
- _broker = broker;
+ return shape;
}
- public void shutdown()
+ public void setShape(String shape)
{
- LOGGER.info("Shutting down Broker instance");
+ this.shape = shape;
+ }
- _broker.shutdown();
-
- LOGGER.info("Broker instance shutdown");
+ public HashMap<String, Crumpet> getCrumpets()
+ {
+ return crumpets;
}
+ public void setCrumpets(HashMap<String, Crumpet> crumpets)
+ {
+ this.crumpets = crumpets;
+ }
}
diff --git a/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java
new file mode 100644
index 0000000000..bfd34840f8
--- /dev/null
+++ b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.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.agent;
+
+public class Puppet
+{
+ public int countStrings()
+ {
+ return 4;
+ }
+}
diff --git a/qpid/java/management/client/README.txt b/qpid/java/management/client/README.txt
new file mode 100644
index 0000000000..ecd61da75e
--- /dev/null
+++ b/qpid/java/management/client/README.txt
@@ -0,0 +1,42 @@
+QMan - Qpid JMX & WS-DM Management Bridge
+---------------------------------------------------------
+
+Documentation
+--------------
+All of our user documentation for QMan module can be accessed on our wiki at:
+
+http://cwiki.apache.org/qpid/qman-qpid-management-bridge.html
+
+This includes a Getting Started and User Guide as well as detailed developer documentation.
+However, here's a VERY quick guide to running QMan, once you have installed it somewhere !
+
+Running
+------------------
+
+Once you installed QMan, under the root folder you should have the following structure
+
+- bin (folder) : contains startup & shutdown scripts;
+- app (folder) : contains the web application module;
+- etc (folder) : contains configuration files;
+- examples (folder) : contains examples (and a nested README as well)
+- lib (folder) : contains dependency libraries;
+- log (folder) : this is the default log folder.
+
+To run QMan,
+
+1) edit the $QMAN_HOME/etc/qman-config.xml file and configure broker connection data (host,port, username, etc...)
+2) under the $QMAN_HOME/bin directory run :
+
+> ./qman-wsdm-start.sh
+
+now, under $QMAN_HOME/log directory you should see two files :
+
+1) server.log : contains web server log messages;
+2) qman.log : contains qman log messages;
+
+Administration
+-----------------------
+
+After QMan has been started successfully you can browse its administration console pointing your browser to :
+
+http://<host>:<port>/qman/console
diff --git a/qpid/java/management/client/bin/qman-jmx.cmd b/qpid/java/management/client/bin/qman-jmx.cmd
new file mode 100644
index 0000000000..c04241494d
--- /dev/null
+++ b/qpid/java/management/client/bin/qman-jmx.cmd
@@ -0,0 +1,78 @@
+@echo off
+
+@rem Licensed to the Apache Software Foundation (ASF) under one
+@rem or more contributor license agreements. See the NOTICE file
+@rem distributed with this work for additional information
+@rem regarding copyright ownership. The ASF licenses this file
+@rem to you under the Apache License, Version 2.0 (the
+@rem "License"); you may not use this file except in compliance
+@rem with the License. You may obtain a copy of the License at
+@rem
+@rem http://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing,
+@rem software distributed under the License is distributed on an
+@rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@rem KIND, either express or implied. See the License for the
+@rem specific language governing permissions and limitations
+@rem under the License.
+
+@rem *************************************************************************
+@rem This script is used to initialize environment to start QMan JMX Adapter.
+@rem It uses several environment variables described below.
+@rem You can edit this file according to your environment or (reccommended) set their
+@rem values outside this script.
+@rem
+@rem It sets (or retrieve from the environment if defined) the following variables:
+@rem
+@rem QMAN_HOME - The home directory of your QMan installation.
+@rem JAVA_HOME - Location of the version of Java runtime used to start QMan.
+@rem QMAN_CONFIG_FILE - Location of the QMan configuration file.
+@rem **************************************************************************
+
+cls
+
+:CHECK JVM
+set JAVA=%JAVA_HOME%\bin\java
+set JAVA_OPTS=-Xms128m -Xmx512m
+
+if not "%JAVA_HOME%" == "" goto CONFIGURE AND START
+
+set JAVA=java
+
+echo.
+echo WARNING : JAVA_HOME is not set so unexpected results may occur.
+echo Please set JAVA_HOME to the directory of your local JDK / JRE to avoid this message.
+
+:CONFIGURE AND START
+
+if "%QMAN_HOME%" == "" SET QMAN_HOME=..
+if "%QMAN_CONFIG_FILE%" == "" SET QMAN_CONFIG_FILE=%QMAN_HOME%\etc\qman-config.xml
+
+SET QMAN_LIBS=%QMAN_HOME%\lib
+SET QMAN_CLASSPATH=%QMAN_HOME%\etc
+
+setlocal ENABLEDELAYEDEXPANSION
+
+FOR /R %QMAN_LIBS% %%G IN (*.jar) DO set QMAN_CLASSPATH=!QMAN_CLASSPATH!;%%G
+
+:START
+echo ===============================================================================
+echo.
+echo QMan JMX Bridge Bootstrap Environment
+echo --------------------------------------------------
+echo.
+echo QMan HOME : %QMAN_HOME%
+echo.
+echo Java executable : %JAVA%
+echo.
+echo Java Opts : %JAVA_OPTS%
+echo.
+echo Configuration file : %QMAN_CONFIG_FILE%
+echo.
+echo Bootstrap classpath : %QMAN_CLASSPATH%
+echo.
+echo ===============================================================================
+echo.
+
+"%JAVA%" %JAVA_OPTS% -Dcom.sun.management.jmxremote -Dqman-config=%QMAN_CONFIG_FILE% -classpath "%QMAN_CLASSPATH%" org.apache.qpid.management.domain.services.QMan \ No newline at end of file
diff --git a/qpid/java/management/client/bin/qman-jmx.sh b/qpid/java/management/client/bin/qman-jmx.sh
new file mode 100644
index 0000000000..1003117128
--- /dev/null
+++ b/qpid/java/management/client/bin/qman-jmx.sh
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# *************************************************************************
+# This script is used to initialize environment to start QMan JMX Adapter.
+# It uses several environment variables described below.
+# You can edit this file according to your environment or (reccommended) set their
+# values outside this script.
+#
+# It sets (or retrieve from the environment if defined) the following variables:
+#
+# QMAN_HOME - The home directory of your QMan installation.
+# JAVA_HOME - Location of the version of Java runtime used to start QMan.
+# QMAN_CONFIG_FILE - Location of the QMan configuration file.
+# **************************************************************************
+
+clear
+
+JAVA=$JAVA_HOME/bin/java
+JAVA_OPTS="-Xms128m -Xmx512m"
+
+if [ "$JAVA_HOME" = "" ] ; then
+ echo "JAVA_HOME is not set. Unexpected results may occur."
+ echo "Set JAVA_HOME to the directory of your local JDK to avoid this message."
+ JAVA=java
+fi
+
+if [ "$QMAN_HOME" = "" ] ; then
+ QMAN_HOME=..
+fi
+
+if [ "$QMAN_CONFIG_FILE" = "" ] ; then
+ QMAN_CONFIG_FILE=$QMAN_HOME/etc/qman-config.xml
+fi
+
+if [ "$QMAN_LIBS" = "" ] ; then
+ QMAN_LIBS=$QMAN_HOME/lib
+fi
+QMAN_CLASSPATH=`find $QMAN_LIBS | tr '\n' ":"`
+QMAN_CLASSPATH=$QMAN_HOME/etc:$QMAN_CLASSPATH
+
+echo "==============================================================================="
+echo ""
+echo "QMan JMX Bridge Bootstrap Environment"
+echo "--------------------------------------------------"
+echo ""
+echo "QMan HOME : $QMAN_HOME"
+echo ""
+echo "Java executable : $JAVA"
+echo ""
+echo "Java Opts : $JAVA_OPTS"
+echo ""
+echo "Configuration file : $QMAN_CONFIG_FILE"
+echo ""
+echo "Bootstrap classpath : $QMAN_CLASSPATH"
+echo ""
+echo "==============================================================================="
+echo ""
+
+"$JAVA" $JAVA_OPTS -cp $QMAN_CLASSPATH -Dcom.sun.management.jmxremote -Dqman-config=$QMAN_CONFIG_FILE org.apache.qpid.management.domain.services.QMan
diff --git a/qpid/java/management/client/bin/qman-wsdm-start.cmd b/qpid/java/management/client/bin/qman-wsdm-start.cmd
new file mode 100644
index 0000000000..ec8321c6b8
--- /dev/null
+++ b/qpid/java/management/client/bin/qman-wsdm-start.cmd
@@ -0,0 +1,88 @@
+@echo off
+
+@rem Licensed to the Apache Software Foundation (ASF) under one
+@rem or more contributor license agreements. See the NOTICE file
+@rem distributed with this work for additional information
+@rem regarding copyright ownership. The ASF licenses this file
+@rem to you under the Apache License, Version 2.0 (the
+@rem "License"); you may not use this file except in compliance
+@rem with the License. You may obtain a copy of the License at
+@rem
+@rem http://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing,
+@rem software distributed under the License is distributed on an
+@rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@rem KIND, either express or implied. See the License for the
+@rem specific language governing permissions and limitations
+@rem under the License.
+
+@rem *************************************************************************
+@rem This script is used to initialize environment to start QMan WS-DM Adapter.
+@rem It uses several environment variables described below.
+@rem You can edit this file according to your environment or (reccommended) set their
+@rem values outside this script.
+@rem
+@rem It sets (or retrieve from the environment if defined) the following variables:
+@rem
+@rem QMAN_HOME - The home directory of your QMan installation.
+@rem JAVA_HOME - Location of the version of Java runtime used to start QMan.
+@rem QMAN_WSDM_ADAPTER_PORT - The TCP port that QMan will use to listen for incoming connections.
+@rem QMAN_WSDM_ADAPTER_HOST - The IP address or DNS name QMan will use to listen for incoming connections
+@rem QMAN_CONFIG_FILE - Location of the QMan configuration file.
+@rem **************************************************************************
+
+set JAVA=%JAVA_HOME%\bin\java
+set JAVA_OPTS=-Xms128m -Xmx512m
+SET CLASSPATH=
+
+if not "%JAVA_HOME%" == "" goto CONFIGURE AND START
+set JAVA=java
+
+echo JAVA_HOME is not set. Unexpected results may occur.
+echo Set JAVA_HOME to the directory of your local JDK to avoid this message.
+
+:CONFIGURE AND START
+
+if "%QMAN_HOME%" == "" SET QMAN_HOME=..
+if "%QMAN_WSDM_ADAPTER_PORT%" == "" SET QMAN_WSDM_ADAPTER_PORT=8080
+if "%QMAN_WSDM_ADAPTER_HOST%" == "" SET QMAN_WSDM_ADAPTER_HOST=%COMPUTERNAME%
+if "%QMAN_CONFIG_FILE%" == "" SET QMAN_CONFIG_FILE=%QMAN_HOME%\etc\qman-config.xml
+
+SET ADMIN_PORT=8079
+SET ADMIN_KEY=gazzax
+SET QMAN_LIBS=%QMAN_HOME%\lib
+SET JETTY_CONFIG_FILE=%QMAN_HOME%\etc\jetty.xml
+
+SET CLASSPATH=%QMAN_HOME%\etc
+SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\start.jar
+SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\jetty-6.1.14.jar
+SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\jetty-util-6.1.14.jar
+SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\geronimo-servlet_2.5_spec-1.2.jar
+SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\slf4j-api-1.6.1.jar
+SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\slf4j-log4j12-1.6.1.jar
+SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\log4j-1.2.12.jar
+
+echo ===============================================================================
+echo.
+echo QMan WS-DM Bridge Bootstrap Environment
+echo ------------------------------------------------------
+echo.
+echo QMan HOME: %QMAN_HOME%
+echo.
+echo Java executable : %JAVA%
+echo.
+echo QMan configuration file : %QMAN_CONFIG_FILE%
+echo.
+echo Web Server configuration file : %JETTY_CONFIG_FILE%
+echo.
+echo Web Server HTTP port : %QMAN_WSDM_ADAPTER_PORT%
+echo.
+echo Web Server Admin port : %ADMIN_PORT%
+echo.
+echo Bootstrap classpath : %CLASSPATH%
+echo.
+echo ===============================================================================
+echo.
+
+%JAVA% -cp %CLASSPATH% -DQMAN_HOME=%QMAN_HOME% -Djetty.home=%QMAN_HOME% -Dqman.host=%QMAN_WSDM_ADAPTER_HOST% -Dqman.port=%QMAN_WSDM_ADAPTER_PORT% -DSTOP.PORT=%ADMIN_PORT% -DSTOP.KEY=%ADMIN_KEY% -Dqman-config=%QMAN_CONFIG_FILE% org.mortbay.start.Main %JETTY_CONFIG_FILE%
diff --git a/qpid/java/management/client/bin/qman-wsdm-start.sh b/qpid/java/management/client/bin/qman-wsdm-start.sh
new file mode 100644
index 0000000000..0024890527
--- /dev/null
+++ b/qpid/java/management/client/bin/qman-wsdm-start.sh
@@ -0,0 +1,89 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# *************************************************************************
+# This script is used to initialize environment to start QMan WS-DM Adapter.
+# It uses several environment variables described below.
+# You can edit this file according to your environment or (reccommended) set their
+# values outside this script.
+#
+# It sets (or retrieve from the environment if defined) the following variables:
+#
+# QMAN_HOME - The home directory of your QMan installation.
+# JAVA_HOME - Location of the version of Java runtime used to start QMan.
+# QMAN_WSDM_ADAPTER_PORT - The TCP port that QMan will use to listen for incoming connections.
+# QMAN_WSDM_ADAPTER_HOST - The IP address or DNS name QMan will use to listen for incoming connections
+# QMAN_CONFIG_FILE - Location of the QMan configuration file.
+# **************************************************************************
+
+JAVA=$JAVA_HOME/bin/java
+JAVA_OPTS="-Xms128m -Xmx512m"
+
+if [ "$JAVA_HOME" = "" ] ; then
+ echo "JAVA_HOME is not set. Unexpected results may occur."
+ echo "Set JAVA_HOME to the directory of your local JDK to avoid this message."
+ JAVA=java
+fi
+if [ "$QMAN_HOME" = "" ] ; then
+ QMAN_HOME=..
+fi
+if [ "$QMAN_WSDM_ADAPTER_PORT" = "" ] ; then
+ QMAN_WSDM_ADAPTER_PORT=8080
+fi
+if [ "$QMAN_WSDM_ADAPTER_HOST" = "" ] ; then
+ QMAN_WSDM_ADAPTER_HOST=$HOSTNAME
+fi
+if [ "$QMAN_CONFIG_FILE" = "" ] ; then
+ QMAN_CONFIG_FILE=$QMAN_HOME/etc/qman-config.xml
+fi
+
+ADMIN_PORT=8079
+ADMIN_KEY=gazzax
+QMAN_LIBS=$QMAN_HOME/lib
+JETTY_CONFIG_FILE=$QMAN_HOME/etc/jetty.xml
+
+QMAN_CLASSPATH=$QMAN_HOME/etc:$QMAN_LIBS/start.jar:$QMAN_LIBS/jetty-6.1.14.jar:$QMAN_LIBS/jetty-util-6.1.14.jar:$QMAN_LIBS/geronimo-servlet_2.5_spec-1.2.jar:$QMAN_LIBS/slf4j-api-1.6.1.jar:$QMAN_LIBS/slf4j-log4j12-1.6.1.jar:$QMAN_LIBS/log4j-1.2.12.jar
+
+echo "==============================================================================="
+echo""
+echo "QMan WS-DM Bridge Bootstrap Environment"
+echo "------------------------------------------------------"
+echo""
+echo "QMan HOME: $QMAN_HOME"
+echo""
+echo "Java executable : $JAVA"
+echo""
+echo "Java Opts : $JAVA_OPTS"
+echo""
+echo "Configuration file : $QMAN_CONFIG_FILE"
+echo""
+echo "Web Server Configuration File : $JETTY_CONFIG_FILE"
+echo""
+echo "Web Server HTTP port : $QMAN_WSDM_ADAPTER_PORT"
+echo""
+echo "Web Server HTTP host : $QMAN_WSDM_ADAPTER_HOST"
+echo""
+echo "Web Server Admin port : $ADMIN_PORT"
+echo""
+echo "Bootstrap classpath : $QMAN_CLASSPATH"
+echo""
+echo "==============================================================================="
+echo""
+
+"$JAVA" $JAVA_OPTS -cp $QMAN_CLASSPATH -DQMAN_HOME=$QMAN_HOME -Djetty.home=$QMAN_HOME -Dqman.host=$QMAN_WSDM_ADAPTER_HOST -Dqman.port=$QMAN_WSDM_ADAPTER_PORT -DSTOP.PORT=$ADMIN_PORT -DSTOP.KEY=$ADMIN_KEY -Dqman-config=$QMAN_CONFIG_FILE org.mortbay.start.Main $JETTY_CONFIG_FILE
diff --git a/qpid/java/management/client/bin/qman-wsdm-stop.cmd b/qpid/java/management/client/bin/qman-wsdm-stop.cmd
new file mode 100644
index 0000000000..6449c70227
--- /dev/null
+++ b/qpid/java/management/client/bin/qman-wsdm-stop.cmd
@@ -0,0 +1,37 @@
+@echo off
+
+rem Licensed to the Apache Software Foundation (ASF) under one
+rem or more contributor license agreements. See the NOTICE file
+rem distributed with this work for additional information
+rem regarding copyright ownership. The ASF licenses this file
+rem to you under the Apache License, Version 2.0 (the
+rem "License"); you may not use this file except in compliance
+rem with the License. You may obtain a copy of the License at
+rem
+rem http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing,
+rem software distributed under the License is distributed on an
+rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem KIND, either express or implied. See the License for the
+rem specific language governing permissions and limitations
+rem under the License.
+
+set JAVA=%JAVA_HOME%\bin\java
+
+if not "%JAVA_HOME%" == "" goto CONFIGURE AND START
+
+set JAVA=java
+
+echo JAVA_HOME is not set. Unexpected results may occur.
+echo Set JAVA_HOME to the directory of your local JDK to avoid this message.
+
+:CONFIGURE AND START
+
+if "%QMAN_HOME%" == "" SET QMAN_HOME=..
+SET ADMIN_PORT=8079
+SET ADMIN_KEY=gazzax
+
+"%JAVA%" -DSTOP.PORT=%ADMIN_PORT% -DSTOP.KEY=%ADMIN_KEY% -jar %QMAN_HOME%\lib\start.jar --stop
+
+echo QMan WS-DM Adapter shut down successfully. \ No newline at end of file
diff --git a/qpid/java/management/client/bin/qman-wsdm-stop.sh b/qpid/java/management/client/bin/qman-wsdm-stop.sh
new file mode 100644
index 0000000000..0de9a995ef
--- /dev/null
+++ b/qpid/java/management/client/bin/qman-wsdm-stop.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+JAVA=$JAVA_HOME/bin/java
+
+if [ "$JAVA_HOME" = "" ] ; then
+ echo "JAVA_HOME is not set. Unexpected results may occur."
+ echo "Set JAVA_HOME to the directory of your local JDK to avoid this message."
+ JAVA=java
+fi
+
+if [ "$QMAN_HOME" = "" ] ; then
+ QMAN_HOME=..
+fi
+
+ADMIN_PORT=8079
+ADMIN_KEY=gazzax
+
+"$JAVA" -DSTOP.PORT=$ADMIN_PORT -DSTOP.KEY=$ADMIN_KEY -jar $QMAN_HOME/lib/start.jar --stop
+
+echo "QMan WS-DM Adapter shut down successfully." \ No newline at end of file
diff --git a/qpid/java/management/client/build.xml b/qpid/java/management/client/build.xml
new file mode 100644
index 0000000000..415840f70d
--- /dev/null
+++ b/qpid/java/management/client/build.xml
@@ -0,0 +1,213 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<project name="QMan - Qpid JMX / WS-DM Adapter" default="build">
+
+ <property name="module.depends" value="client common"/>
+ <property name="module.test.depends" value="client common"/>
+
+ <import file="../../module.xml"/>
+
+ <property name="build.root" value="${module.build}"/>
+ <property name="web.module" value="${module.build}${file.separator}wsdm-module"/>
+ <property name="web-inf.folder" value="${web.module}${file.separator}WEB-INF"/>
+ <property name="classes.folder" value="${web-inf.folder}${file.separator}classes"/>
+ <property name="examples.folder" value="${module.build}${file.separator}examples"/>
+
+ <target name="release-bin-other">
+ <mkdir dir="${module.release}${file.separator}log"/>
+ <mkdir dir="${module.release}${file.separator}examples"/>
+ <mkdir dir="${module.release}${file.separator}examples${file.separator}sample_messages"/>
+
+ </target>
+
+ <target name="release-bin" depends="release-bin-tasks"/>
+
+ <target name="resources-release" description="copy resources into module release">
+ <copy todir="${module.release}" failonerror="false" flatten="true">
+ <fileset dir="${resources}" excludes="META-INF">
+ <exclude name="META-INF"/>
+ <exclude name="README.txt"/>
+ </fileset>
+ <fileset file="${module.build}${file.separator}README.txt"/>
+ </copy>
+ </target>
+
+ <target name="libs-release" description="copy dependencies into module release">
+ <copy todir="${module.release}${file.separator}" failonerror="true" verbose="true">
+ <fileset dir="${build}" casesensitive="yes" includes="${module.libs}">
+ <not><filename name="**/*javassist*"/></not>
+ <not><filename name="**/*xml-api*"/></not>
+ <not><filename name="**/*xerces*"/></not>
+ <not><filename name="**/*xalan*"/></not>
+ <not><filename name="**/*wsdl*"/></not>
+ <not><filename name="**/*muse*"/></not>
+ <not><filename name="**/*jsp*"/></not>
+ <not><filename name="**/*core-3.1.1.jar*"/></not>
+ </fileset>
+ </copy>
+ <copy todir="${module.release}${file.separator}lib" failonerror="true">
+ <fileset file="${module.jar}"/>
+ <fileset dir="${build.lib}" includes="${module.depends.jars}"/>
+ </copy>
+ <mkdir dir="${module.release}${file.separator}app${file.separator}qman"/>
+ <copy todir="${module.release}${file.separator}app${file.separator}qman" failonerror="true">
+ <fileset dir="${web.module}" includes="*/**"/>
+ </copy>
+ <mkdir dir="${module.release}${file.separator}examples"/>
+ <copy todir="${module.release}${file.separator}examples">
+ <fileset dir="${examples.folder}"/>
+ </copy>
+ </target>
+
+ <target name="prepare-wsdm-module">
+ <mkdir dir="${web.module}"/>
+ <mkdir dir="${web-inf.folder}"/>
+ <mkdir dir="${classes.folder}"/>
+ <copy file=".${file.separator}web.xml" todir="${web-inf.folder}" verbose="false"/>
+ <copy todir="${classes.folder}" verbose="false">
+ <fileset dir="${module.classes}">
+ <include name="wsdl/**"/>
+ <include name="muse.xml"/>
+ <include name="router-entries/**"/>
+ </fileset>
+ </copy>
+ <copy todir="${web-inf.folder}">
+ <fileset dir="${build}" includes="${module.libs}">
+ <exclude name="lib/jetty*.jar"/>
+ <exclude name="lib/start*.jar"/>
+ </fileset>
+ </copy>
+ <copy todir="${web-inf.folder}${file.separator}lib">
+ <fileset dir="${build}/lib">
+ <include name="qpid-client-*.jar"/>
+ <include name="qpid-common-*.jar"/>
+ <include name="qpid-management-client-*.jar"/>
+ <exclude name="qpid-client-example*.jar"/>
+ <exclude name="qpid-client-tests*.jar"/>
+ <exclude name="qpid-common-tests*.jar"/>
+ <exclude name="qpid-management-client-tests*.jar"/>
+ </fileset>
+ </copy>
+ <copy todir="${web.module}">
+ <fileset dir="${module.src}${file.separator}..${file.separator}..${file.separator}..${file.separator}console">
+ <include name="*/**"/>
+ </fileset>
+ </copy>
+ </target>
+ <target name="jar.manifest" depends="compile" if="module.manifest">
+ <jar destfile="${module.jar}" manifest="${module.manifest}">
+ <fileset dir="${module.classes}" casesensitive="yes">
+ <include name="**/**"/>
+ <exclude name="wsdl/**"/>
+ <exclude name="muse.xml"/>
+ <exclude name="router-entries/**"/>
+ </fileset>
+ </jar>
+ </target>
+ <target name="jar.nomanifest" depends="compile" unless="module.manifest">
+ <jar destfile="${module.jar}">
+ <metainf dir="${project.root}${file.separator}resources/" />
+ <fileset dir="${module.classes}" casesensitive="yes">
+ <include name="**/**"/>
+ <exclude name="wsdl/**"/>
+ <exclude name="muse.xml"/>
+ <exclude name="router-entries/**"/>
+ </fileset>
+ </jar>
+ </target>
+ <target name="postbuild" depends="prepare-wsdm-module,copy-examples-to-build,copy-README-to-build" description="Build WS-DM module"/>
+
+ <path id="module.test.path">
+ <pathelement path="${module.test.classes}" />
+ <path refid="module.test.libs"/>
+ <fileset dir="${build}/lib">
+ <include name="qpid-client-*.jar"/>
+ <include name="qpid-common-*.jar"/>
+ <include name="qpid-management-client-*.jar"/>
+ <exclude name="qpid-client-example*.jar"/>
+ <exclude name="qpid-client-tests*.jar"/>
+ <exclude name="qpid-common-tests*.jar"/>
+ <exclude name="qpid-management-client-tests*.jar"/>
+ </fileset>
+ </path>
+
+ <target name="copy-README-to-build">
+ <copy todir="${module.build}">
+ <fileset dir="${module.src}${file.separator}..${file.separator}..${file.separator}..">
+ <include name="README.txt"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="copy-examples-to-build">
+ <mkdir dir="${examples.folder}${file.separator}src"/>
+ <mkdir dir="${examples.folder}${file.separator}sample_messages"/>
+ <copy todir="${examples.folder}">
+ <fileset dir="${module.src}${file.separator}..${file.separator}..${file.separator}example">
+ <include name="README.txt"/>
+ </fileset>
+ </copy>
+ <copy todir="${examples.folder}${file.separator}src">
+ <fileset dir="${module.src}${file.separator}..${file.separator}..${file.separator}example">
+ <include name="**/*.java"/>
+ <exclude name="**/*.out.*"/>
+ </fileset>
+ </copy>
+ <copy todir="${examples.folder}${file.separator}sample_messages">
+ <fileset dir="${module.src}${file.separator}..${file.separator}..${file.separator}example" >
+ <exclude name="**/*.java"/>
+ <exclude name="**/README.txt"/>
+ <include name="**/*.out.*"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="test" depends="build,compile-tests" if="module.test.src.exists" unless="${dontruntest}" description="execute unit tests">
+ <delete file="${module.failed}"/>
+ <echo message="Using profile:${profile}" level="info"/>
+ <junit fork="${test.fork}" maxmemory="1024M" reloading="no"
+ haltonfailure="${haltonfailure}" haltonerror="${haltonerror}"
+ failureproperty="test.failures" printsummary="on" timeout="600000" >
+
+ <jvmarg value="${jvm.args}"/>
+ <sysproperty key="qman.war" value="${web.module}"/>
+
+ <formatter type="plain"/>
+ <formatter type="xml"/>
+
+ <classpath refid="module.test.path"/>
+
+ <batchtest fork="${test.fork}" todir="${module.results}">
+ <fileset dir="${module.test.src}" excludes="${module.test.excludes}">
+ <include name="**/${test}.java"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ <antcall target="touch-failed"/>
+ <condition property="failed">
+ <and>
+ <isfalse value="${test.failures.ignore}"/>
+ <available file="${module.failed}"/>
+ </and>
+ </condition>
+ <fail if="failed" message="TEST SUITE FAILED"/>
+ </target>
+</project>
diff --git a/qpid/java/management/client/console/brokers_management.jsp b/qpid/java/management/client/console/brokers_management.jsp
new file mode 100644
index 0000000000..f307006ac1
--- /dev/null
+++ b/qpid/java/management/client/console/brokers_management.jsp
@@ -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.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<%@page import="org.apache.qpid.management.web.action.BrokerModel"%>
+<%@page import="java.util.Set"%>
+<%@page import="javax.management.ObjectName"%>
+<%@page import="org.apache.qpid.management.Names"%>
+<%@page import="java.util.List"%>
+<%@page import="java.util.*"%>
+<%@page import="java.net.URI"%>
+<%@page import="javax.xml.namespace.QName"%>
+<%@page import="org.w3c.dom.Element"%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Brokers Management"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div class="panel" align="justify">
+ <span class="bodytext">
+ <table width="100%">
+ <tr>
+ <td valign="top">
+ <fieldset>
+ <legend>Connected Brokers</legend>
+ <table width="100%" cellspacing="1">
+ <tr>
+ <th nowrap="nowrap" align="center">Host</th>
+ <th nowrap="nowrap" align="center" >Port</th>
+ <th nowrap="nowrap" align="center">Virtual Host</th>
+ <th nowrap="nowrap" align="center">Username</th>
+ <th nowrap="nowrap" align="center">Initial Pool Capacity</th>
+ <th nowrap="nowrap" align="center">Max Pool Capacity</th>
+ <th nowrap="nowrap" align="center">Max Wait Timeout</th>
+ </tr>
+ <c:forEach var="broker" items="${model}" varStatus="rowCounter">
+ <c:choose>
+ <c:when test="${rowCounter.count % 2 == 0}">
+ <c:set var="bgcolor" scope="page" value="EAEAEA"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="bgcolor" scope="page" value="FFFFFF"/>
+ </c:otherwise>
+ </c:choose>
+ <tr>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${broker.host}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${broker.port}"/></td>
+ <td style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${broker.virtualHost}"/></td>
+ <td style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${broker.username}"/></td>
+ <td style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${broker.initialPoolCapacity}"/></td>
+ <td style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${broker.maxPoolCapacity}"/></td>
+ <td style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${broker.maxWaitTimeout}"/></td>
+ </tr>
+ </c:forEach>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <form name="form" action="<%=request.getContextPath()%>/brokers_management" method="post">
+ <fieldset>
+ <legend>New Broker Connection Data</legend>
+ <table>
+ <tr>
+ <td>
+ Host :
+ </td>
+ <td>
+ <input type="text" name="host"/>
+ </td>
+ <td style="font-size: x-small;">
+ The hostname where the broker is running.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Port :
+ </td>
+ <td>
+ <input type="text" name="port"/>
+ </td>
+ <td style="font-size: x-small;">
+ The port number where the broker is running.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Virtual Host :
+ </td>
+ <td>
+ <input type="text" name="virtualHost"/>
+ </td>
+ <td style="font-size: x-small;">
+ The virtual host name.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Username :
+ </td>
+ <td>
+ <input type="text" name="username"/>
+ </td>
+ <td style="font-size: x-small;">
+ The username used for estabilish connection with broker.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Password :
+ </td>
+ <td>
+ <input type="text" name="password"/>
+ </td>
+ <td style="font-size: x-small;">
+ The password used for estabilish connection with broker.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Initial Pool Capacity :
+ </td>
+ <td>
+ <input type="text" name="initialCapacity"/>
+ </td>
+ <td style="font-size: x-small;">
+ The number of connections that must be immediately opened.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Max Pool Capacity :
+ </td>
+ <td>
+ <input type="text" name="maxCapacity"/>
+ </td>
+ <td style="font-size: x-small;">
+ The maximum number of open connections.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Max Wait Timeout :
+ </td>
+ <td>
+ <input type="text" name="maxWaitTimeout"/>
+ </td>
+ <td style="font-size: x-small;">
+ The maximum amount of time that a client will wait for obtaining a connection.
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3" align="center">
+ <input type="submit" value="Connect"/>
+ </td>
+ </tr>
+ </table>
+ </fieldset>
+ </td>
+ </form>
+ </tr>
+ <tr>
+ <td nowrap style="font-size: x-small; font-weight: bold; color=red;">
+ <ul>
+ <c:forEach var="errorMessage" items="${errors}">
+ <li><span style="font-size: medium; font-weight: bold; color:red;">${errorMessage}</span></li>
+ </c:forEach>
+ </ul>
+ </td>
+ </tr>
+
+ </table>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/console.jsp b/qpid/java/management/client/console/console.jsp
new file mode 100644
index 0000000000..d1a207fe32
--- /dev/null
+++ b/qpid/java/management/client/console/console.jsp
@@ -0,0 +1,122 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="System Overview"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div class="panel" align="justify" style="height:500px; overflow-y:auto;">
+ <span class="bodytext">
+ <table width="100%" border="0">
+ <tr>
+ <td valign="top" nowrap align="center">
+ <fieldset>
+ <legend>QMan</legend>
+ <table cellspacing="2">
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold;" align="center">Version</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.version}</td></tr>
+ <tr><td><br /></td></tr>
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold" align="center">Version Name</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.versionName}</td></tr>
+ <tr><td><br /></td></tr>
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold" align="center">Start Date</td></tr>
+ <tr>
+ <td style="font-size: xx-small;" align="center">
+ <fmt:formatDate
+ value="${requestScope.model.startDate}"
+ pattern="MM/dd/yyyy hh:mm:ss"/>
+ </td>
+ </tr>
+ <tr><td><br /></td></tr>
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold" align="center">Host</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.host}</td></tr>
+ <tr><td><br /></td></tr>
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold" align="center">Port</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.port}</td></tr>
+ </table>
+ </fieldset>
+ <fieldset>
+ <legend>Operating System</legend>
+ <table cellspacing="2">
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold;" align="center">Name</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.osName}</td></tr>
+ <tr><td><br /></td></tr>
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold" align="center">Version</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.osVersion}</td></tr>
+ <tr><td><br /></td></tr>
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold" align="center">Arch</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.archName}</td></tr>
+ <tr><td><br /></td></tr>
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold" align="center">Processors</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.processors}</td></tr>
+ </table>
+ </fieldset>
+ </td>
+ <td valign="top">
+ <fieldset>
+ <legend>JVM Environment</legend>
+ <table cellspacing="5">
+ <tr>
+ <td valign="top">
+ <h4 style="color: #006633; font-size: xx-small">Boot Classpath :
+ <p/>
+ <c:forEach var="entry" items="${model.bootClasspath}">
+ <c:out value="${entry}"/>;
+ <br/>
+ </c:forEach>
+ </h4>
+ </td>
+ <td valign="top">
+ <h4 style="color: #006633; font-size: xx-small">
+ Input Arguments :
+ <p/>
+ <c:forEach var="argument" items="${model.inputArguments}">
+ <c:out value="${argument}"/>;
+ <br/>
+ </c:forEach>
+ </h4>
+ </td>
+ </tr>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+ </table>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/error_page.jsp b/qpid/java/management/client/console/error_page.jsp
new file mode 100644
index 0000000000..73d2f9edc3
--- /dev/null
+++ b/qpid/java/management/client/console/error_page.jsp
@@ -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.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Error Page"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div class="panel" align="justify" style="height:500px; overflow-y:auto;">
+ <span class="bodytext">
+ <table width="100%">
+ <tr><td nowrap style="font-weight: bold;">
+ We are not able to satify your request because an error has happened.
+ <br>Message : ${errorMessage}
+ </td></tr>
+ <tr><td nowrap style="font-size: xx-small; font-weight: bold;">
+ <c:forEach var="stackTrace" items="${exception.stackTrace}">
+ ${stackTrace}
+ <br>
+ </c:forEach>
+ </td></tr>
+ </table>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/fragments/header.jsp b/qpid/java/management/client/console/fragments/header.jsp
new file mode 100644
index 0000000000..b401fee7a0
--- /dev/null
+++ b/qpid/java/management/client/console/fragments/header.jsp
@@ -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.
+
+-->
+
+<div id="header" align="center">
+ <div id="pagetitle">
+ <div id="asf-header" align="left">
+ <table width="100%">
+ <tr>
+ <td align="left"><img src="images/qpid-logo.png" height="100" width="200" /></td>
+ <td align="right"><img src="images/asf-logo.png" height="69" width="225" /></td>
+ </tr>
+ </table>
+ </div>
+ <div id="title" class="titletext" align="right">
+ <span class="bluetitle"><%=request.getParameter("title")%></span>
+ </div>
+ </div>
+</div>
diff --git a/qpid/java/management/client/console/fragments/menu.jsp b/qpid/java/management/client/console/fragments/menu.jsp
new file mode 100644
index 0000000000..6924fd5d43
--- /dev/null
+++ b/qpid/java/management/client/console/fragments/menu.jsp
@@ -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.
+
+-->
+
+<div id="menu" align="center">
+ <div id="linksmenu" align="left">
+ <a href="<%=request.getContextPath()%>/console"> &nbsp; &gt; System Overview</a>
+ <a href="<%=request.getContextPath()%>/brokers_management">&nbsp; &gt; Brokers Management</a>
+ <a href="<%=request.getContextPath()%>/resources_management">&nbsp; &gt; Resources Management</a>
+ <a>&nbsp; &gt; Subscriptions Management</a>
+ <a>&nbsp; &gt; System Health</a>
+ <a href="<%=request.getContextPath()%>/logging_configuration">&nbsp; &gt; Logging Configuration</a>
+ </div>
+</div>
diff --git a/qpid/java/management/client/console/images/asf-logo.png b/qpid/java/management/client/console/images/asf-logo.png
new file mode 100644
index 0000000000..d824fab768
--- /dev/null
+++ b/qpid/java/management/client/console/images/asf-logo.png
Binary files differ
diff --git a/qpid/java/management/client/console/images/menu.gif b/qpid/java/management/client/console/images/menu.gif
new file mode 100644
index 0000000000..9946e8e231
--- /dev/null
+++ b/qpid/java/management/client/console/images/menu.gif
Binary files differ
diff --git a/qpid/java/management/client/console/images/menuleft.gif b/qpid/java/management/client/console/images/menuleft.gif
new file mode 100644
index 0000000000..f986ecfc27
--- /dev/null
+++ b/qpid/java/management/client/console/images/menuleft.gif
Binary files differ
diff --git a/qpid/java/management/client/console/images/menuright.gif b/qpid/java/management/client/console/images/menuright.gif
new file mode 100644
index 0000000000..afdd8bd04b
--- /dev/null
+++ b/qpid/java/management/client/console/images/menuright.gif
Binary files differ
diff --git a/qpid/java/management/client/console/images/qpid-logo.png b/qpid/java/management/client/console/images/qpid-logo.png
new file mode 100644
index 0000000000..5f4ccc3081
--- /dev/null
+++ b/qpid/java/management/client/console/images/qpid-logo.png
Binary files differ
diff --git a/qpid/java/management/client/console/images/style.css b/qpid/java/management/client/console/images/style.css
new file mode 100644
index 0000000000..a32682fa2f
--- /dev/null
+++ b/qpid/java/management/client/console/images/style.css
@@ -0,0 +1,202 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+body
+{
+ margin-left: 0px;
+ margin-top: 0px;
+ margin-right: 0px;
+ margin-bottom: 0px;
+}
+
+tr th {
+ padding: 4px 8px 4px 8px;
+ background: #5E7796;
+ border: 1px solid #CCC;
+ color:#b8ce83;
+ font-size: smaller;
+}
+
+fieldset
+{
+ font-size: xx-small;
+}
+
+#header
+{
+ width:1024px;
+}
+
+#content
+{
+ width:1024px;
+}
+
+#contenttext
+{
+ float:left; width:824px;
+ background-color:#FFFFFF;
+ border-left:solid 1px #999999; border-right:solid 1px #999999;
+ border-bottom:solid 1px #999999; border-top:dotted 1px #CCCCCC;
+ min-height:360px;
+}
+
+#asf-header
+{
+ float:left;
+ width:1007px;
+ height:110px;
+ background-color:#FFFFFF;
+ border-right:solid 1px #999999;
+ border-left:solid 1px #999999;
+}
+
+#pagetitle
+{
+ position:relative;
+ float:left;
+ width:1024px;
+ height:110px;
+ background-color:#FFFFFF;
+}
+
+#title
+{
+ position:absolute;
+ right:20px;
+ bottom:0px;
+ width:1008px;
+}
+
+#menu
+{
+ float:left; width: 190px; margin: 0 0 0 -7px;
+}
+
+.panel{
+ padding:12px;
+ margin: 5px;
+ padding:10px;
+}
+
+.bodytext {
+ font: 0.7em Tahoma, sans-serif;
+ color: #666666;
+}
+
+.titletext {
+ font: 0.7em Tahoma, sans-serif;
+ font-size:36px;
+ font-weight:bold;
+ color: #CCCCCC;
+}
+
+.orangelogotext {
+ font: 0.7em Tahoma, sans-serif;
+ font-size:36px;
+ font-weight:bold;
+ color:#FF9900;
+}
+.orangetitle {
+ font: 0.7em Tahoma, sans-serif;
+ font-size:24px;
+ font-weight:bold;
+ color:#FF9900;
+}
+
+.bluetitle {
+ font: 0.7em Tahoma, sans-serif;
+ font-size:24px;
+ font-weight:bold;
+ color:#369;
+}
+
+#linksmenu a{
+ float:right;
+ width:183px;
+ height:20px;
+ background-color:#5E7796;
+ border-left:solid 1px #FFFFFF;
+ border-bottom:solid 1px #FFFFFF;
+ font: 0.7em Tahoma, sans-serif;
+ font-size: 11px;
+ font-weight:bold;
+ color: #FFFFFF;
+ text-decoration:none;
+ padding-top:5px;
+}
+#linksmenu a:hover
+{
+ background-color:#336;
+}
+
+
+#wsdmmenu
+{
+ float:left;
+ position: relative;
+ width: 600px;
+ font-size:75%;
+ margin: 0 0 0px 5px;
+ line-height:normal;
+}
+
+#wsdmmenu ul
+{
+ margin:0;
+ padding:0px 0px 0 0px;
+ list-style: none;
+}
+
+#wsdmmenu li
+{
+ display:inline;
+ margin:0;
+ padding:0;
+}
+
+#wsdmmenu a {
+ float:left;
+ background: url(menuleft.gif) no-repeat left top;
+ margin:0;
+ padding:0 0 0 4px;
+ text-decoration:none;
+}
+
+#wsdmmenu a span {
+ float:left;
+ display:block;
+ background: url(menuright.gif) no-repeat right top;
+ padding:5px 15px 4px 6px;
+ color:#888;
+}
+
+#wsdmmenu a span {float:none;}
+
+#wsdmmenu a:hover
+{
+ background-position:0% -42px;
+}
+
+#wsdmmenu a:hover span
+{
+ background-position:100% -42px;
+}
diff --git a/qpid/java/management/client/console/jmx_perspective.jsp b/qpid/java/management/client/console/jmx_perspective.jsp
new file mode 100644
index 0000000000..5d276a0edc
--- /dev/null
+++ b/qpid/java/management/client/console/jmx_perspective.jsp
@@ -0,0 +1,157 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<%@page import="org.apache.qpid.management.web.action.BrokerModel"%>
+<%@page import="java.util.Set"%>
+<%@page import="javax.management.ObjectName"%>
+<%@page import="org.apache.qpid.management.Names"%>
+<%@page import="java.util.List"%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Resource Management - JMX Perspective"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div id="wsdmmenu" align="left">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/jmx_perspective?resourceId=${resourceId}"><span>JMX</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?resourceId=${resourceId}"><span>WS-DM</span></a></li>
+ </ul>
+ </div>
+ <br />
+ <div class="panel" align="justify">
+ <span class="bodytext">
+ <table width="100%">
+ <tr>
+ <td valign="top" colspan="2">
+ <fieldset>
+ <legend>ObjectName</legend>
+ <ul>
+ <c:forEach var="property" items="${nameAttributes}">
+ <li>
+ <c:out value="${property}"/>
+ </li>
+ </c:forEach>
+ </ul>
+ </fieldset>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <fieldset>
+ <legend>Attributes</legend>
+ <table width="100%" cellspacing="1">
+ <tr>
+ <th>Name</th>
+ <th>Type</th>
+ <th>Value</th>
+ <th>Access</th>
+ </tr>
+ <c:forEach var="attribute" items="${metadata.attributes}" varStatus="rowCounter">
+ <c:choose>
+ <c:when test="${rowCounter.count % 2 == 0}">
+ <c:set var="bgcolor" scope="page" value="EAEAEA"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="bgcolor" scope="page" value="FFFFFF"/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${attribute.writable}">
+ <c:set var="access" scope="page" value="RW"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="access" scope="page" value="RO"/>
+ </c:otherwise>
+ </c:choose>
+ <tr>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${attribute.name}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${attribute.type}"/></td>
+ <td style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${attributes[attribute.name]}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${access}"/></td>
+ </tr>
+ </c:forEach>
+ </table>
+ </fieldset>
+ </td>
+ <td valign="top">
+ <fieldset>
+ <legend>Operations</legend>
+ <table width="100%" cellspacing="0">
+ <tr>
+ <th>Name</th>
+ <th>Arguments</th>
+ </tr>
+
+ <c:forEach var="operation" items="${metadata.operations}" varStatus="rowCounter">
+ <c:choose>
+ <c:when test="${rowCounter.count % 2 == 0}">
+ <c:set var="bgcolor" scope="page" value="EAEAEA"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="bgcolor" scope="page" value="FFFFFF"/>
+ </c:otherwise>
+ </c:choose>
+ <tr>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${operation.name}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}">
+ <ul>
+ <c:forEach var="argument" items="${operation.signature}">
+ <li>
+ <c:out value="${argument.name}"/> (<c:out value="${argument.type}"/>)
+ </li>
+ </c:forEach>
+ </ul>
+ </td>
+ </tr>
+ </c:forEach>
+ </fieldset>
+ </td>
+ </tr>
+ </table>
+ </span>
+ </div>
+ </div>
+
+
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/logging_configuration.jsp b/qpid/java/management/client/console/logging_configuration.jsp
new file mode 100644
index 0000000000..89f10567fa
--- /dev/null
+++ b/qpid/java/management/client/console/logging_configuration.jsp
@@ -0,0 +1,241 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Logging Configuration"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div class="panel" align="justify" style="height:500px; overflow-y:auto;">
+ <span class="bodytext">
+ <form method="post" name="form" action="<%=request.getContextPath() %>/logging_configuration">
+ <table>
+ <tr>
+ <td>
+ <fieldset>
+ <legend>WSDL & RDM Debugger</legend>
+ <table>
+ <tr>
+ <td>
+ <c:choose>
+ <c:when test="${wsdlDebugEnabled}">
+ <c:set var="checked" scope="page" value="checked"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="checked" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <input type="checkbox" ${checked} name="wsdlDebugEnabled" />
+ </td>
+ <td nowrap style="font-size: x-small;">
+ When this flag is checked all WSDL and RMD messages are written on log file (or console depending on your configuration.)
+ </td>
+ </tr>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <fieldset>
+ <legend>SOAP Messages Debugger</legend>
+ <table>
+
+ <tr>
+ <td>
+ <c:choose>
+ <c:when test="${soapDebugEnabled}">
+ <c:set var="checked" scope="page" value="checked"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="checked" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <input ${checked} type="checkbox" name="soapDebugEnabled"/>
+ </td>
+ <td nowrap style="font-size: x-small;">
+ When this flag is checked all SOAP messages (requests & responses) are written on log file (or console depending on your configuration.)
+ </td>
+ </tr>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <fieldset>
+ <legend>QMan Logger Level</legend>
+ <table>
+ <tr>
+ <td>
+ <c:choose>
+ <c:when test="${qmanLogLevel == 'DEBUG'}">
+ <c:set var="qmanDebug" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="qmanDebug" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${qmanLogLevel == 'INFO'}">
+ <c:set var="qmanInfo" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="qmanInfo" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${qmanLogLevel == 'WARN'}">
+ <c:set var="qmanWarn" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="qmanWarn" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${qmanLogLevel == 'ERROR'}">
+ <c:set var="qmanError" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="qmanError" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${qmanLogLevel == 'FATAL'}">
+ <c:set var="qmanFatal" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="qmanFatal" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+
+ <select name="qmanLogLevel">
+ <option ${qmanDebug} value="DEBUG">DEBUG</option>
+ <option ${qmanWarn} value="WARN">WARNING</option>
+ <option ${qmanInfo} value="INFO">INFO</option>
+ <option ${qmanError} value="ERROR">ERROR</option>
+ <option ${qmanFatal} value="FATAL">FATAL</option>
+ </select>
+ </td>
+ <td nowrap style="font-size: x-small;">
+ This is the current priority level set for QMan module (and sub-modules). Note that a WARNING level is recomended in production.
+ </td>
+ </tr>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <fieldset>
+ <legend>Web Server Logger Level</legend>
+ <table>
+
+ <tr>
+ <td>
+ <c:choose>
+ <c:when test="${webServerLogLevel == 'DEBUG'}">
+ <c:set var="webServerDebug" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="webServerDebug" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${webServerLogLevel == 'INFO'}">
+ <c:set var="webServerInfo" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="webServerInfo" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${webServerLogLevel == 'WARN'}">
+ <c:set var="webServerWarn" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="webServerWarn" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${webServerLogLevel == 'ERROR'}">
+ <c:set var="webServerError" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="webServerError" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${webServerLogLevel == 'FATAL'}">
+ <c:set var="webServerFatal" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="webServerFatal" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+
+ <select name="webServerLogLevel">
+ <option ${webServerDebug} value="DEBUG" >DEBUG</option>
+ <option ${webServerWarn} value="WARN">WARNING</option>
+ <option ${webServerInfo} value="INFO">INFO</option>
+ <option ${webServerError} value="ERROR">ERROR</option>
+ <option ${webServerFatak} value="FATAL">FATAL</option>
+ </select>
+ </td>
+ <td nowrap style="font-size: x-small; ">
+ This is the current priority level set for QMan module (and sub-modules). Note that a WARNING level is recomended in production.
+ </td>
+ </tr>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <input type="submit" value="Submit" title="Submit"/>
+ </td>
+ </tr>
+ </table>
+ <br/></br>
+ <span style="fony-size: medium; color: red; font-weight: bold">Note that in general a DEBUG level is not reccommended in production (especially for WSDL and SOAP debugger).</span>
+ </form>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/resources_management.jsp b/qpid/java/management/client/console/resources_management.jsp
new file mode 100644
index 0000000000..4a6f9efed6
--- /dev/null
+++ b/qpid/java/management/client/console/resources_management.jsp
@@ -0,0 +1,105 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<%@page import="org.apache.qpid.management.web.action.BrokerModel"%>
+<%@page import="java.util.Set"%>
+<%@page import="javax.management.ObjectName"%>
+<%@page import="org.apache.qpid.management.Names"%>
+<%@page import="java.util.List"%>
+
+<%
+ BrokerModel model = (BrokerModel) request.getAttribute("model");
+%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Resources Management"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+
+ <div id="contenttext">
+ <div id="wsdmmenu" align="left">
+ <ul>
+ <% if (model != null) {%>
+ <li><a href="#"><span>${model.id}</span></a></li>
+ <%} %>
+ </ul>
+ </div>
+ <br />
+ <div class="panel" align="justify" style="height:500px; overflow-y:auto;">
+ <span class="bodytext">
+ <table width="100%" border="0" cellpadding="1" cellspacing="2">
+<%
+ if (model != null ){
+ Set<String> categoryNames = model.getCategoryNames();
+ for(String categoryName : categoryNames)
+ {
+ List<ObjectName> categoryObjects = model.getCategory(categoryName);
+%>
+ <tr>
+ <td valign="top" nowrap align="left">
+ <fieldset>
+ <legend><%=categoryName%></legend>
+ <h4 style="color: #006633; font-size: xx-small">
+ <ul>
+ <%
+ for (ObjectName objectName : categoryObjects)
+ {%>
+
+ <li>
+ <a href="<%=request.getContextPath()%>/jmx_perspective?resourceId=<%=objectName%>">
+ <%=objectName.getKeyProperty(Names.OBJECT_ID)%>
+ </a>
+ </li>
+ <%
+ }
+ %>
+ </ul>
+ </fieldset>
+ </td>
+ </tr>
+<%
+ }
+ } else {
+%>
+<table><tr>
+<td nowrap style="font-weight: bold;" >Sorry, but it seems that QMan is not connected with any broker...</td>
+</tr>
+</table>
+<%
+ }
+%>
+ </table>
+ </span>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/tbd.jsp b/qpid/java/management/client/console/tbd.jsp
new file mode 100644
index 0000000000..3c1c87a7b0
--- /dev/null
+++ b/qpid/java/management/client/console/tbd.jsp
@@ -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.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="TBD"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div class="panel" align="justify" style="height:500px; overflow-y:auto;">
+ <span class="bodytext">
+ Sorry, this feature is not yet available!
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/wsdm_operations_perspective.jsp b/qpid/java/management/client/console/wsdm_operations_perspective.jsp
new file mode 100644
index 0000000000..50f67c4492
--- /dev/null
+++ b/qpid/java/management/client/console/wsdm_operations_perspective.jsp
@@ -0,0 +1,174 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<%@page import="org.apache.qpid.management.web.action.BrokerModel"%>
+<%@page import="java.util.Set"%>
+<%@page import="javax.management.ObjectName"%>
+<%@page import="org.apache.qpid.management.Names"%>
+<%@page import="java.util.*"%>
+<%
+ Map<String,String> java2Xml = new HashMap<String,String>();
+java2Xml.put(UUID.class.getName(),"qman:uuid");
+java2Xml.put(Long.class.getName(),"xsd:long");
+java2Xml.put(long.class.getName(),"xsd:long");
+java2Xml.put(Boolean.class.getName(),"xsd:boolean");
+java2Xml.put(boolean.class.getName(),"xsd:boolean");
+java2Xml.put(Double.class.getName(),"xsd:double");
+java2Xml.put(double.class.getName(),"xsd:double");
+java2Xml.put(Float.class.getName(),"xsd:float");
+java2Xml.put(float.class.getName(),"xsd:float");
+java2Xml.put(Integer.class.getName(),"xsd:integer");
+java2Xml.put(int.class.getName(),"xsd:integer");
+java2Xml.put(Short.class.getName(),"xsd:short");
+java2Xml.put(short.class.getName(),"xsd:short");
+java2Xml.put(String.class.getName(),"xsd:string");
+java2Xml.put(URI.class.getName(),"xsd:anyURI");
+java2Xml.put(Date.class.getName(),"xsd:dateTime");
+java2Xml.put(QName.class.getName(),"xsd:QName");
+java2Xml.put(Element.class.getName(),"xsd:element");
+java2Xml.put(byte[].class.getName(),"xsd:base64Binary");
+java2Xml.put(Long[].class.getName(),"qman:arrayOfLong");
+java2Xml.put(long[].class.getName(),"qman:arrayOfLong");
+java2Xml.put(Boolean[].class.getName(),"qman:arrayOfBoolean");
+java2Xml.put(boolean[].class.getName(),"qman:arrayOfBoolean");
+java2Xml.put(Double[].class.getName(),"qman:arrayOfDouble");
+java2Xml.put(double[].class.getName(),"qman:arrayOfDouble");
+java2Xml.put(Float[].class.getName(),"qman:arrayOfFloat");
+java2Xml.put(float[].class.getName(),"qman:arrayOfFloat");
+java2Xml.put(Integer[].class.getName(),"qman:arrayOfInteger");
+java2Xml.put(int[].class.getName(),"qman:arrayOfInteger");
+java2Xml.put(Short[].class.getName(),"qman:arrayOfShort");
+java2Xml.put(short[].class.getName(),"qman:arrayOfShort");
+java2Xml.put(String[].class.getName(),"qman:arrayOfString");
+java2Xml.put(URI[].class.getName(),"qman:arrayOfURI");
+java2Xml.put(Date[].class.getName(),"qman:arrayOfDate");
+java2Xml.put(Map.class.getName(),"qman:map");
+java2Xml.put(HashMap.class.getName(),"qman:map");
+
+pageContext.setAttribute("types",java2Xml);
+%>
+<%@page import="java.net.URI"%>
+<%@page import="javax.xml.namespace.QName"%>
+<%@page import="org.w3c.dom.Element"%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Resource Management - WS-DM Operations Perspective"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div id="wsdmmenu" align="left">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/jmx_perspective?resourceId=${resourceId}"><span>JMX</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?wsresourceId=${resourceId}"><span>WS-DM</span></a></li>
+ </ul>
+ </div>
+ <br />
+ <div class="panel" align="justify">
+ <span class="bodytext">
+ <table width="100%">
+ <tr>
+ <td valign="top" colspan="2">
+ <fieldset>
+ <legend>Resource ID</legend>
+ <ul>
+ <c:forEach var="property" items="${nameAttributes}">
+ <li>
+ <c:out value="${property}"/>
+ </li>
+ </c:forEach>
+ </ul>
+ </fieldset>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <div id="wsdmmenu" align="left" style="font-size: small;">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?resourceId=${resourceId}"><span>Properties</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_operations_perspective?resourceId=${resourceId}""><span>Operations</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_wsdl_perspective?resourceId=${resourceId}""><span>WSDL</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_rmd_perspective?resourceId=${resourceId}""><span>RDM</span></a></li>
+ </ul>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <fieldset>
+ <legend>Attributes</legend>
+ <table width="100%" cellspacing="1">
+ <tr>
+ <th nowrap="nowrap" align="center">Name</th>
+ <th nowrap="nowrap" align="center">Arguments</th>
+ <th nowrap="nowrap" align="center">Faults</th>
+ </tr>
+ <c:forEach var="operation" items="${metadata.operations}" varStatus="rowCounter">
+ <c:choose>
+ <c:when test="${rowCounter.count % 2 == 0}">
+ <c:set var="bgcolor" scope="page" value="EAEAEA"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="bgcolor" scope="page" value="FFFFFF"/>
+ </c:otherwise>
+ </c:choose>
+ <tr>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${operation.name}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}">
+ <ul>
+ <c:forEach var="argument" items="${operation.signature}">
+ <li>
+ <c:out value="${argument.name}"/> (<c:out value="${types[argument.type]}"/>)
+ </li>
+ </c:forEach>
+ </ul>
+ </td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}">
+ <ul>
+ <li>qman:EntityInstanceNotFoundFault</li>
+ <li>qman:OperationInvocationFault</li>
+ <li>qman:QManFault</li>
+ </ul>
+ </td>
+ </tr>
+ </c:forEach>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+ </table>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/wsdm_properties_perspective.jsp b/qpid/java/management/client/console/wsdm_properties_perspective.jsp
new file mode 100644
index 0000000000..7769abc71c
--- /dev/null
+++ b/qpid/java/management/client/console/wsdm_properties_perspective.jsp
@@ -0,0 +1,218 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<%@page import="org.apache.qpid.management.web.action.BrokerModel"%>
+<%@page import="java.util.Set"%>
+<%@page import="javax.management.ObjectName"%>
+<%@page import="org.apache.qpid.management.Names"%>
+<%@page import="java.util.List"%>
+<%@page import="java.util.*"%>
+
+<%
+ Map<String,String> java2Xml = new HashMap<String,String>();
+java2Xml.put(UUID.class.getName(),"qman:uuid");
+java2Xml.put(Long.class.getName(),"xsd:long");
+java2Xml.put(long.class.getName(),"xsd:long");
+java2Xml.put(Boolean.class.getName(),"xsd:boolean");
+java2Xml.put(boolean.class.getName(),"xsd:boolean");
+java2Xml.put(Double.class.getName(),"xsd:double");
+java2Xml.put(double.class.getName(),"xsd:double");
+java2Xml.put(Float.class.getName(),"xsd:float");
+java2Xml.put(float.class.getName(),"xsd:float");
+java2Xml.put(Integer.class.getName(),"xsd:integer");
+java2Xml.put(int.class.getName(),"xsd:integer");
+java2Xml.put(Short.class.getName(),"xsd:short");
+java2Xml.put(short.class.getName(),"xsd:short");
+java2Xml.put(String.class.getName(),"xsd:string");
+java2Xml.put(URI.class.getName(),"xsd:anyURI");
+java2Xml.put(Date.class.getName(),"xsd:dateTime");
+java2Xml.put(QName.class.getName(),"xsd:QName");
+java2Xml.put(Element.class.getName(),"xsd:element");
+java2Xml.put(byte[].class.getName(),"xsd:base64Binary");
+java2Xml.put(Long[].class.getName(),"qman:arrayOfLong");
+java2Xml.put(long[].class.getName(),"qman:arrayOfLong");
+java2Xml.put(Boolean[].class.getName(),"qman:arrayOfBoolean");
+java2Xml.put(boolean[].class.getName(),"qman:arrayOfBoolean");
+java2Xml.put(Double[].class.getName(),"qman:arrayOfDouble");
+java2Xml.put(double[].class.getName(),"qman:arrayOfDouble");
+java2Xml.put(Float[].class.getName(),"qman:arrayOfFloat");
+java2Xml.put(float[].class.getName(),"qman:arrayOfFloat");
+java2Xml.put(Integer[].class.getName(),"qman:arrayOfInteger");
+java2Xml.put(int[].class.getName(),"qman:arrayOfInteger");
+java2Xml.put(Short[].class.getName(),"qman:arrayOfShort");
+java2Xml.put(short[].class.getName(),"qman:arrayOfShort");
+java2Xml.put(String[].class.getName(),"qman:arrayOfString");
+java2Xml.put(URI[].class.getName(),"qman:arrayOfURI");
+java2Xml.put(Date[].class.getName(),"qman:arrayOfDate");
+java2Xml.put(Map.class.getName(),"qman:map");
+java2Xml.put(HashMap.class.getName(),"qman:map");
+
+pageContext.setAttribute("types",java2Xml);
+%>
+<%@page import="java.net.URI"%>
+<%@page import="javax.xml.namespace.QName"%>
+<%@page import="org.w3c.dom.Element"%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Resource Management - WS-DM Properties Perspective"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div id="wsdmmenu" align="left">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/jmx_perspective?resourceId=${resourceId}"><span>JMX</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?resourceId=${resourceId}"><span>WS-DM</span></a></li>
+ </ul>
+ </div>
+ <br />
+ <div class="panel" align="justify">
+ <span class="bodytext">
+ <table width="100%">
+ <tr>
+ <td valign="top" colspan="2">
+ <fieldset>
+ <legend>Resource ID</legend>
+ <ul>
+ <c:forEach var="property" items="${nameAttributes}">
+ <li>
+ <c:out value="${property}"/>
+ </li>
+ </c:forEach>
+ </ul>
+ </fieldset>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <div id="wsdmmenu" align="left" style="font-size: small;">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?resourceId=${resourceId}"><span>Properties</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_operations_perspective?resourceId=${resourceId}""><span>Operations</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_wsdl_perspective?resourceId=${resourceId}""><span>WSDL</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_rmd_perspective?resourceId=${resourceId}""><span>RDM</span></a></li>
+ </ul>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <fieldset>
+ <legend>Attributes</legend>
+ <table width="100%" cellspacing="1">
+ <tr>
+ <th nowrap="nowrap" align="center">Name</th>
+ <th nowrap="nowrap" align="center" >Type</th>
+ <th nowrap="nowrap" align="center">Value</th>
+ <th nowrap="nowrap" align="center">Mutable</th>
+ <th nowrap="nowrap" align="center">Access</th>
+ <th nowrap="nowrap" align="center">Valid Values</th>
+ <th nowrap="nowrap" align="center">Static Values</th>
+ <th nowrap="nowrap" align="center">Initial Values</th>
+ </tr>
+ <c:forEach var="attribute" items="${metadata.attributes}" varStatus="rowCounter">
+ <c:choose>
+ <c:when test="${rowCounter.count % 2 == 0}">
+ <c:set var="bgcolor" scope="page" value="EAEAEA"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="bgcolor" scope="page" value="FFFFFF"/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${attribute.writable}">
+ <c:set var="access" scope="page" value="RW"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="access" scope="page" value="RO"/>
+ </c:otherwise>
+ </c:choose>
+ <tr>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${attribute.name}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${types[attribute.type]}"/></td>
+ <td style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${attributes[attribute.name]}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}">
+ &radic;
+ <%--
+ <c:out value="${attribute.mutable}"/>
+ --%>
+ </td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${access}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}">
+ N.A.
+<%--
+ <ul>
+ <c:forEach var="value" items="${attribute.validValues}">
+ <li>
+ <c:out value="${value}"/>
+ </li>
+ </c:forEach>
+ </ul>
+--%>
+ </td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}">
+ N.A.
+<%--
+ <ul>
+ <c:forEach var="value" items="${attribute.staticValues}">
+ <li>
+ <c:out value="${value}"/>
+ </li>
+ </c:forEach>
+ </ul>
+--%>
+ </td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}">
+ N.A.
+<%--
+ <ul>
+ <c:forEach var="value" items="${attribute.initialValues}">
+ <li>
+ <c:out value="${value}"/>
+ </li>
+ </c:forEach>
+ </ul>
+--%>
+ </td>
+ </tr>
+ </c:forEach>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+ </table>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/wsdm_rmd_perspective.jsp b/qpid/java/management/client/console/wsdm_rmd_perspective.jsp
new file mode 100644
index 0000000000..083732668b
--- /dev/null
+++ b/qpid/java/management/client/console/wsdm_rmd_perspective.jsp
@@ -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.
+
+-->
+
+<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix="c"%>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x"%>
+
+<%@page import="org.apache.qpid.management.web.action.BrokerModel"%>
+<%@page import="java.util.Set"%>
+<%@page import="javax.management.ObjectName"%>
+<%@page import="org.apache.qpid.management.Names"%>
+<%@page import="java.util.*"%>
+<%@page import="java.net.URI"%>
+<%@page import="javax.xml.namespace.QName"%>
+<%@page import="org.w3c.dom.Element"%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Resource Management - WS-DM RMD Perspective"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div id="wsdmmenu" align="left">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/jmx_perspective?resourceId=${resourceId}"><span>JMX</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?wsresourceId=${resourceId}"><span>WS-DM</span></a></li>
+ </ul>
+ </div>
+ <br />
+ <div class="panel" align="justify">
+ <span class="bodytext">
+ <table width="100%">
+ <tr>
+ <td valign="top" colspan="2">
+ <fieldset>
+ <legend>Resource ID</legend>
+ <ul>
+ <c:forEach var="property" items="${nameAttributes}">
+ <li>
+ <c:out value="${property}"/>
+ </li>
+ </c:forEach>
+ </ul>
+ </fieldset>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <div id="wsdmmenu" align="left" style="font-size: small;">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?resourceId=${resourceId}"><span>Properties</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_operations_perspective?resourceId=${resourceId}""><span>Operations</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_wsdl_perspective?resourceId=${resourceId}""><span>WSDL</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_rmd_perspective?resourceId=${resourceId}""><span>RDM</span></a></li>
+ </ul>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <div class="panel" align="left" style="height:500px; width=200px; overflow-y:auto; font-size: smaller; font-weight:bold;">
+ <pre> <c:out value="${rmd}" /> </pre>
+ </div>
+ </td>
+ </tr>
+ </table>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/wsdm_wsdl_perspective.jsp b/qpid/java/management/client/console/wsdm_wsdl_perspective.jsp
new file mode 100644
index 0000000000..0674c51a97
--- /dev/null
+++ b/qpid/java/management/client/console/wsdm_wsdl_perspective.jsp
@@ -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.
+
+-->
+
+<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix="c"%>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x"%>
+
+<%@page import="org.apache.qpid.management.web.action.BrokerModel"%>
+<%@page import="java.util.Set"%>
+<%@page import="javax.management.ObjectName"%>
+<%@page import="org.apache.qpid.management.Names"%>
+<%@page import="java.util.*"%>
+<%@page import="java.net.URI"%>
+<%@page import="javax.xml.namespace.QName"%>
+<%@page import="org.w3c.dom.Element"%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Resource Management - WS-DM WSDL Perspective"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div id="wsdmmenu" align="left">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/jmx_perspective?resourceId=${resourceId}"><span>JMX</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?resourceId=${resourceId}"><span>WS-DM</span></a></li>
+ </ul>
+ </div>
+ <br />
+ <div class="panel" align="justify">
+ <span class="bodytext">
+ <table width="100%">
+ <tr>
+ <td valign="top" colspan="2">
+ <fieldset>
+ <legend>Resource ID</legend>
+ <ul>
+ <c:forEach var="property" items="${nameAttributes}">
+ <li style="color : black;">
+ <c:out value="${property}"/>
+ </li>
+ </c:forEach>
+ </ul>
+ </fieldset>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <div id="wsdmmenu" align="left" style="font-size: small;">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?resourceId=${resourceId}"><span>Properties</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_operations_perspective?resourceId=${resourceId}""><span>Operations</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_wsdl_perspective?resourceId=${resourceId}""><span>WSDL</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_rmd_perspective?resourceId=${resourceId}""><span>RDM</span></a></li>
+ </ul>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <div class="panel" align="left" style="height:500px; width=200px; overflow-y:auto; font-size: smaller; font-weight:bold;">
+ <pre> <c:out value="${wsdl}" /> </pre>
+ </div>
+ </td>
+ </tr>
+ </table>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/doc/man/qman-jmx b/qpid/java/management/client/doc/man/qman-jmx
new file mode 100644
index 0000000000..064c00eae5
--- /dev/null
+++ b/qpid/java/management/client/doc/man/qman-jmx
@@ -0,0 +1,17 @@
+.TH qman-jmx
+.SH NAME
+qman-jmx is a Management bridge that exposes one (or several) Qpid broker domain model as MBeans that are accessible through the Java Management Extensions (JMX). Once you run qman you need to start a JMX Console such as JConsole to browse the MBeans exposed by Q-Man.
+.SH SYNOPSIS
+qman
+.SH DESCRIPTION
+For more information on customizing qman-jmx for your own environment please read http://cwiki.apache.org/confluence/display/qpid/Qman+Tool
+.SH Configuration
+.SS Classpath
+By default qman jars will be loaded from /usr/share/java. If you want to load from an alternative location you could specify it using QPID_LIB_PATH var.
+.SS Config file
+qman can be configured to connect to one or more brokers at startup by adding brokers in
+.I /etc/qman-config.xml
+If you want to load qman with qman-config.xml from a different location, you can specify it using QPID_CONFIG_FILE var.
+.SS log4j configuration
+qman expects qman.log4j file to be in the classpath. By default it will be put in
+.I /usr/share/java
diff --git a/qpid/java/management/client/etc/jetty.xml b/qpid/java/management/client/etc/jetty.xml
new file mode 100644
index 0000000000..975053a518
--- /dev/null
+++ b/qpid/java/management/client/etc/jetty.xml
@@ -0,0 +1,47 @@
+<?xml version="1.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.
+
+-->
+
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
+<Configure id="Server" class="org.mortbay.jetty.Server">
+ <Set name="StopAtShutdown">true</Set>
+ <Set name="Connectors">
+ <Array type="org.mortbay.jetty.Connector">
+ <Item>
+ <New
+ class="org.mortbay.jetty.nio.SelectChannelConnector">
+ <Set name="port">
+ <SystemProperty name="qman.port" default="8080" />
+ </Set>
+ <Set name="host">
+ <SystemProperty name="qman.host" default="localhost" />
+ </Set>
+ </New>
+ </Item>
+ </Array>
+ </Set>
+ <Set name="handler">
+ <New class="org.mortbay.jetty.webapp.WebAppContext">
+ <Set name="contextPath">/qman</Set>
+ <Set name="war"><SystemProperty name="QMAN_HOME" default=".." />/app/qman</Set>
+ </New>
+ </Set>
+</Configure>
diff --git a/qpid/java/management/client/etc/qman-config.xml b/qpid/java/management/client/etc/qman-config.xml
new file mode 100644
index 0000000000..cdc840e967
--- /dev/null
+++ b/qpid/java/management/client/etc/qman-config.xml
@@ -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.
+ -
+ -->
+<configuration>
+
+<!--
+Default configuration for QMan has no broker settings;
+that is, there's no broker configured at startup.
+If you want to connect with a running broker when QMan starts up,
+you can do that uncommenting and editing the template reported below.
+-->
+<!-- <brokers>
+ <broker>
+ <host>localhost</host>
+ <port>5672</port>
+ <virtual-host>test</virtual-host>
+ <user>guest</user>
+ <password>guest</password>
+ <max-pool-capacity>4</max-pool-capacity>
+ <initial-pool-capacity>0</initial-pool-capacity>
+ <max-wait-timeout>-1</max-wait-timeout>
+ </broker>
+ <broker>
+ <host>localhost</host>
+ <port>5672</port>
+ <virtual-host>test</virtual-host>
+ <user>guest</user>
+ <password>guest</password>
+ <max-pool-capacity>4</max-pool-capacity>
+ <initial-pool-capacity>0</initial-pool-capacity>
+ <max-wait-timeout>-1</max-wait-timeout>
+ </broker>
+ </brokers>
+ -->
+ <!-- Internal worked manager configuration-->
+ <work-manager>
+ <!-- The size of the worker thread pool -->
+ <pool-capacity>5</pool-capacity>
+
+ <!-- Maximum size of the worker thread pool -->
+ <max-pool-capacity>15</max-pool-capacity>
+
+ <!--
+ when the current number of threads is greater than
+ the pool-capacity, this is the maximum time that excess threads
+ can be in an idle state (without any task assigned) before terminating.
+ The value is expressed is milliseconds.
+ -->
+ <keep-alive-time>5000</keep-alive-time>
+ </work-manager>
+</configuration>
diff --git a/qpid/java/management/client/etc/qman-config.xsd b/qpid/java/management/client/etc/qman-config.xsd
new file mode 100644
index 0000000000..38282c63d1
--- /dev/null
+++ b/qpid/java/management/client/etc/qman-config.xsd
@@ -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.
+ -
+-->
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <xsd:element name="broker">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="host" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="port" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="virtual-host" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="user" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="password" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="max-pool-capacity" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="initial-pool-capacity" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="max-wait-timeout" minOccurs="1" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="brokers">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="broker" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="configuration">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="brokers" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="host" type="xsd:string"/>
+ <xsd:element name="initial-pool-capacity" type="xsd:integer"/>
+ <xsd:element name="max-pool-capacity" type="xsd:integer"/>
+ <xsd:element name="max-wait-timeout" type="xsd:integer"/>
+ <xsd:element name="password" type="xsd:string"/>
+ <xsd:element name="port" type="xsd:integer"/>
+ <xsd:element name="user" type="xsd:string"/>
+ <xsd:element name="virtual-host"type="xsd:string"/>
+
+</schema> \ No newline at end of file
diff --git a/qpid/java/management/client/etc/qman.log4j b/qpid/java/management/client/etc/qman.log4j
new file mode 100644
index 0000000000..bf6f940a6c
--- /dev/null
+++ b/qpid/java/management/client/etc/qman.log4j
@@ -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.
+#
+log4j.rootLogger=${root.logging.level}
+
+log4j.logger.org.apache.qpid=ERROR, console
+log4j.additivity.org.apache.qpid=false
+
+log4j.logger.org.apache.qpid.management.client=DEBUG, console
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=error
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%t %d %p [%c{4}] %m%n
diff --git a/qpid/java/management/client/src/example/ConnectWithBroker.out.ok b/qpid/java/management/client/src/example/ConnectWithBroker.out.ok
new file mode 100644
index 0000000000..33af477b98
--- /dev/null
+++ b/qpid/java/management/client/src/example/ConnectWithBroker.out.ok
@@ -0,0 +1,81 @@
+ ConnectWithBrokerExample
+-------------------------------------------------------------------
+
+This example shows how to connect QMan with a broker using
+the adapter interface.
+
+Type enter to proceed...
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://amqp.apache.org/qpid/management/qman/Connect</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:48bf9a1b-f814-7391-b5cf-d163de4ac068</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <qman:Connect xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <qman:host>sofia.gazzax.com</qman:host>
+ <qman:port>5672</qman:port>
+ <qman:username>test</qman:username>
+ <qman:password>a.gazzarini</qman:password>
+ <qman:virtualHost>p1ssw9rd</qman:virtualHost>
+ <qman:initialPoolCapacity>1</qman:initialPoolCapacity>
+ <qman:maxPoolCapacity>4</qman:maxPoolCapacity>
+ <qman:maxWaitTimeout>2000</qman:maxWaitTimeout>
+ </qman:Connect>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/fault</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:220bfe54-d5f4-4a04-794c-0f5d99a64567</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:48bf9a1b-f814-7391-b5cf-d163de4ac068</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://romagazzarini:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <soap:Fault>
+ <soap:Code xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <soap:Value>qman:QMan</soap:Value>
+ </soap:Code>
+ <soap:Reason>
+ <soap:Text>Unable to connect with the requested broker. Underlying exception message was null</soap:Text>
+ </soap:Reason>
+ <soap:Detail>
+ <qman:OperationInvocationFault xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrf-bf:Timestamp xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2">2009-02-17T10:37:08+01:00</wsrf-bf:Timestamp>
+ <wsrf-bf:OriginatorReference xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2">
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing"/>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/adapter</wsa:Address>
+ </wsrf-bf:OriginatorReference>
+ <qman:host>sofia.gazzax.com</qman:host>
+ <qman:port>5672</qman:port>
+ <qman:username>test</qman:username>
+ <qman:virtualHost>p1ssw9rd</qman:virtualHost>
+ </qman:OperationInvocationFault>
+ </soap:Detail>
+ </soap:Fault>
+ </soap:Body>
+</soap:Envelope>
+
+-----------------------EXAMPLE FAILURE-----------
+Not well-defined exception was detected while
+running the example.
+org.apache.muse.ws.addressing.soap.SoapFault: Unable to connect with the requested broker. Underlying exception message was null
+ at org.apache.muse.core.AbstractResourceClient.invoke(AbstractResourceClient.java:298)
+ at org.apache.muse.core.AbstractResourceClient.invoke(AbstractResourceClient.java:232)
+ at org.apache.muse.core.AbstractResourceClient.invoke(AbstractResourceClient.java:211)
+ at org.apache.qpid.management.example.ConnectWithBrokerExample.executeExample(ConnectWithBrokerExample.java:146)
+ at org.apache.qpid.management.example.ConnectWithBrokerExample.execute(ConnectWithBrokerExample.java:97)
+ at org.apache.qpid.management.example.ConnectWithBrokerExample.main(ConnectWithBrokerExample.java:201)
+--------------------------------------------------------
diff --git a/qpid/java/management/client/src/example/GetMultipleResourceProperties.out.ok b/qpid/java/management/client/src/example/GetMultipleResourceProperties.out.ok
new file mode 100644
index 0000000000..005841488d
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetMultipleResourceProperties.out.ok
@@ -0,0 +1,262 @@
+ GetMultipleResourcePropertiesExample
+-------------------------------------------------------------------
+
+This example shows how to get properties from a
+WS-Resource using one request.
+First of all a request is send to WS-DM in order to get
+all registered WS-Resources.
+If the returned list is not empty then a GetMetadataRequest
+to the first child.
+The result metadata descriptor contains all property names of
+the target WS-Resource.
+Those names are then used for retrieving the corresponding values
+using the GetMultipleResourceProperties request.
+
+-------------------------------------------------------------------
+
+Type enter to proceed...
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:1a72feb1-7d76-1014-66d7-cd03aeff3525</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:783956b1-4de7-f4b6-5421-536f5f310b9a</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:1a72feb1-7d76-1014-66d7-cd03aeff3525</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-sg:Entry xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">
+ <wsrf-sg:ServiceGroupEntryEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/ServiceGroupEntry</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <muse-wsa:ResourceId xmlns:muse-wsa="http://ws.apache.org/muse/addressing">uuid:b220e2bd-0370-da4e-fc71-5e283954d319</muse-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:ServiceGroupEntryEPR>
+ <wsrf-sg:MemberServiceEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <qman-wsa:ResourceId xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:MemberServiceEPR>
+ <wsrf-sg:Content/>
+ </wsrf-sg:Entry>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:588288c9-8bb7-04e9-e7bf-7be1e2fe41fb</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <qman:GetMetadata xmlns:qman="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <qman:Dialect>http://docs.oasis-open.org/wsrf/rmd-1</qman:Dialect>
+ </qman:GetMetadata>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:77c5520b-d450-5a8a-7e2b-22a1079392f2</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:588288c9-8bb7-04e9-e7bf-7be1e2fe41fb</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsx:Metadata xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <wsx:MetadataSection>
+ <wsrmd:MetadataDescriptor
+ interface="qman:QManWsResourcePortType"
+ name="QManWsResourceMetadata"
+ wsdlLocation="http://docs.oasis-open.org/wsrf/rmd-1 QManWsResource.wsdl"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman" xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1">
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:MgmtPubInterval" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Name" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:TerminationTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable"
+ name="qman:MsgTotalEnqueues" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Arguments" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:VhostRef" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:CurrentTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:ExpireTime" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Durable" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:ConsumerCount" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:Type" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ </wsrmd:MetadataDescriptor>
+ </wsx:MetadataSection>
+ </wsx:Metadata>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:783fc044-58a9-e780-a2ba-5b2ac0454985</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetMultipleResourceProperties xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:MgmtPubInterval</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Name</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:MsgTotalEnqueues</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Arguments</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:VhostRef</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:ExpireTime</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Durable</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:ConsumerCount</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Type</wsrf-rp:ResourceProperty>
+ </wsrf-rp:GetMultipleResourceProperties>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:9a2d76dd-52ba-ac7c-74cf-4acd99708529</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:783fc044-58a9-e780-a2ba-5b2ac0454985</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetMultipleResourcePropertiesResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:MgmtPubInterval xmlns:qman="http://amqp.apache.org/qpid/management/qman">32767</qman:MgmtPubInterval>
+ <qman:Name xmlns:qman="http://amqp.apache.org/qpid/management/qman">Initial Name</qman:Name>
+ <qman:MsgTotalEnqueues xmlns:qman="http://amqp.apache.org/qpid/management/qman">9223372036854775797</qman:MsgTotalEnqueues>
+ <qman:Arguments
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <qman:entry>
+ <qman:key>Key3</qman:key>
+ <qman:value xsi:type="xsd:integer">2147483647</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key4</qman:key>
+ <qman:value xsi:type="xsd:float">3.4028235E38</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key1</qman:key>
+ <qman:value xsi:type="xsd:string">aStringValue</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key2</qman:key>
+ <qman:value xsi:type="xsd:long">-9223372036854775808</qman:value>
+ </qman:entry>
+ </qman:Arguments>
+ <qman:VhostRef xmlns:qman="http://amqp.apache.org/qpid/management/qman">2deef1b3-d2c6-49f3-a8de-51f6a75a1a6b</qman:VhostRef>
+ <qman:ExpireTime xmlns:qman="http://amqp.apache.org/qpid/management/qman">9223372036854775807</qman:ExpireTime>
+ <qman:Durable xmlns:qman="http://amqp.apache.org/qpid/management/qman">true</qman:Durable>
+ <qman:ConsumerCount xmlns:qman="http://amqp.apache.org/qpid/management/qman">-2147483638</qman:ConsumerCount>
+ </wsrf-rp:GetMultipleResourcePropertiesResponse>
+ </soap:Body>
+</soap:Envelope> \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/GetQManResourceMembers.out.ko b/qpid/java/management/client/src/example/GetQManResourceMembers.out.ko
new file mode 100644
index 0000000000..d6b733e430
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetQManResourceMembers.out.ko
@@ -0,0 +1,54 @@
+ GetQManResourceMembersExample Example
+-------------------------------------------------------------------
+
+This example shows the usage of WS-DM
+GetResourcePropertyRequest / Response on a
+Group service.
+The target resource is the WS-DM Adapter itself
+and the requested property is "ws-rp:Entry".
+WS-DM Adapter is a special WS-Resource (is a Group)
+that acts as the main entry point for retrieving
+all other managed resources.
+So clients that want to deal with QMan WS-Resources
+must first get resource identifiers sending
+a GetResourcePropertyRequest to WS-DM Adapter
+with "ws-rp:Entry" as target target property.
+
+-------------------------------------------------------------------
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://192.38.73.2:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:796bab33-ed59-3432-4e2c-1fadde465a25</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+-----------------------EXAMPLE FAILURE----------------------
+org.apache.muse.ws.addressing.soap.SoapFault: No route to host: connect
+ at org.apache.muse.core.AbstractResourceClient.invoke(AbstractResourceClient.java:298)
+ at org.apache.muse.core.AbstractResourceClient.invoke(AbstractResourceClient.java:254)
+ at org.apache.muse.ws.resource.remote.WsResourceClient.getResourceProperty(WsResourceClient.java:138)
+ at org.apache.muse.ws.resource.sg.remote.ServiceGroupClient.getMembers(ServiceGroupClient.java:110)
+ at org.apache.qpid.management.example.GetQManResourceMembersExample.execute(GetQManResourceMembersExample.java:61)
+ at org.apache.qpid.management.example.GetQManResourceMembersExample.main(GetQManResourceMembersExample.java:133)
+
+
+#########################################################################################
+
+WARNING! Unable to run this sample : port number must be a number.
+-------------------------------------------------------------
+Expected command line args for this sample are :
+
+1) host : ip or host name where QMan is running.
+2) port : port number where QMan is running.
+------------------------------------------------------------ \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/GetQManResourceMembers.out.ok b/qpid/java/management/client/src/example/GetQManResourceMembers.out.ok
new file mode 100644
index 0000000000..dd75e1e490
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetQManResourceMembers.out.ok
@@ -0,0 +1,55 @@
+ GetQManResourceMembersExample Example
+-------------------------------------------------------------------
+
+This example shows the usage of WS-DM
+GetResourcePropertyRequest / Response on a
+Group service.
+The target resource is the WS-DM Adapter itself
+and the requested property is "ws-rp:Entry".
+WS-DM Adapter is a special WS-Resource (is a Group)
+that acts as the main entry point for retrieving
+all other managed resources.
+So clients that want to deal with QMan WS-Resources
+must first get resource identifiers sending
+a GetResourcePropertyRequest to WS-DM Adapter
+with "ws-rp:Entry" as target target property.
+
+-------------------------------------------------------------------
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:024c678b-1fab-cb6a-0992-30027817fb92</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:90b0e421-6467-a72e-a8f4-cdedb80460b6</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:024c678b-1fab-cb6a-0992-30027817fb92</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://romagazzarini:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+--------------------------------------------------------------------------
+QMan has at the moment 0 registered resources.
+-------------------------------------------------------------------------- \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/GetResourceMetadataDescriptor.out.ok b/qpid/java/management/client/src/example/GetResourceMetadataDescriptor.out.ok
new file mode 100644
index 0000000000..a259259228
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetResourceMetadataDescriptor.out.ok
@@ -0,0 +1,188 @@
+ GetResourceMetadataDescriptorExample
+-------------------------------------------------------------------
+
+The example shows how to get metadata from a
+WS-Resource.
+A QMan WS-Resource has different kinds of metadata.
+(see below)
+User who wants to receive metadata of a WS-Resource
+must send a GetMetadataRequesta specifying the
+associated dialect.
+Supported metadata that could be requested are :
+
+- WSDL : in this case dialect is "http://schemas.xmlsoap.org/wsdl/";
+- RDM (Resource Metadata Descriptor) : in this case dialect is "http://docs.oasis-open.org/wsrf/rmd-1 ".
+
+Note that this examples focuses on RDM Metadata only;
+another one is dedicated to WSDL.
+-------------------------------------------------------------------
+
+Type enter to proceed...
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:cdcf747a-e5fc-3762-1748-87cc2eefb18b</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:1d0d091b-8867-d765-7cc8-4898851cd783</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:cdcf747a-e5fc-3762-1748-87cc2eefb18b</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-sg:Entry xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">
+ <wsrf-sg:ServiceGroupEntryEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/ServiceGroupEntry</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <muse-wsa:ResourceId xmlns:muse-wsa="http://ws.apache.org/muse/addressing">uuid:3a2ee31e-49ed-e30a-c985-0fe49c182a75</muse-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:ServiceGroupEntryEPR>
+ <wsrf-sg:MemberServiceEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <qman-wsa:ResourceId xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=cbe0cada-e8ee-424c-945b-f6c42df7b011,class=queue,name=1232952196269,objectId=e2857418-b873-47b7-ab30-441ae9376529,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:MemberServiceEPR>
+ <wsrf-sg:Content/>
+ </wsrf-sg:Entry>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:ba2435fc-9172-69d8-f4be-34f7f45b26ff</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=cbe0cada-e8ee-424c-945b-f6c42df7b011,class=queue,name=1232952196269,objectId=e2857418-b873-47b7-ab30-441ae9376529,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <qman:GetMetadata xmlns:qman="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <qman:Dialect>http://docs.oasis-open.org/wsrf/rmd-1</qman:Dialect>
+ </qman:GetMetadata>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:ceb6eb90-4910-01a9-c138-6029e6bb0836</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:ba2435fc-9172-69d8-f4be-34f7f45b26ff</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=cbe0cada-e8ee-424c-945b-f6c42df7b011,class=queue,name=1232952196269,objectId=e2857418-b873-47b7-ab30-441ae9376529,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsx:Metadata xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <wsx:MetadataSection>
+ <wsrmd:MetadataDescriptor
+ interface="qman:QManWsResourcePortType"
+ name="QManWsResourceMetadata"
+ wsdlLocation="http://docs.oasis-open.org/wsrf/rmd-1 QManWsResource.wsdl"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman" xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1">
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:MgmtPubInterval" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Name" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:TerminationTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable"
+ name="qman:MsgTotalEnqueues" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Arguments" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:VhostRef" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:CurrentTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:ExpireTime" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Durable" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:ConsumerCount" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:Type" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ </wsrmd:MetadataDescriptor>
+ </wsx:MetadataSection>
+ </wsx:Metadata>
+ </soap:Body>
+</soap:Envelope> \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/GetResourcePropertyDocument.out.ok b/qpid/java/management/client/src/example/GetResourcePropertyDocument.out.ok
new file mode 100644
index 0000000000..9d6312f2f3
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetResourcePropertyDocument.out.ok
@@ -0,0 +1,138 @@
+ GetResourcePropertyDocument
+-------------------------------------------------------------------
+
+This example shows how to get the whole property
+document from a WS-Resource.
+Resource property document represents a particular
+composed structural view of the resource properties
+of the WS-Resource.
+First of all a request is send to WS-DM in order to get
+all registered WS-Resources.
+the target WS-Resource.
+If the returned list is not empty then a
+GetResourcePropertyDocumentRequest is sent to the first child.
+
+-------------------------------------------------------------------
+
+Type enter to proceed...
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:50aa09f5-44e7-8bd3-7f24-49b8f0b9bf0d</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:f71342ad-2185-fdb3-393a-e9a98305effd</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:50aa09f5-44e7-8bd3-7f24-49b8f0b9bf0d</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-sg:Entry xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">
+ <wsrf-sg:ServiceGroupEntryEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/ServiceGroupEntry</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <muse-wsa:ResourceId xmlns:muse-wsa="http://ws.apache.org/muse/addressing">uuid:b220e2bd-0370-da4e-fc71-5e283954d319</muse-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:ServiceGroupEntryEPR>
+ <wsrf-sg:MemberServiceEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <qman-wsa:ResourceId xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:MemberServiceEPR>
+ <wsrf-sg:Content/>
+ </wsrf-sg:Entry>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:e035946b-c3f5-1b24-e94a-61c674ce07b9</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyDocument xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:dafe12e4-c0a9-f872-cf1e-2a41bc291b2e</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:e035946b-c3f5-1b24-e94a-61c674ce07b9</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyDocumentResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:QManWsResourceProperties xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <qman:MgmtPubInterval>32767</qman:MgmtPubInterval>
+ <wsrf-rp:QueryExpressionDialect>http://www.w3.org/TR/1999/REC-xpath-19991116</wsrf-rp:QueryExpressionDialect>
+ <qman:Name>Initial Name</qman:Name>
+ <wsrf-rl:TerminationTime xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"/>
+ <qman:MsgTotalEnqueues>9223372036854775797</qman:MsgTotalEnqueues>
+ <qman:Arguments xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <qman:entry>
+ <qman:key>Key3</qman:key>
+ <qman:value xsi:type="xsd:integer">2147483647</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key4</qman:key>
+ <qman:value xsi:type="xsd:float">3.4028235E38</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key1</qman:key>
+ <qman:value xsi:type="xsd:string">aStringValue</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key2</qman:key>
+ <qman:value xsi:type="xsd:long">-9223372036854775808</qman:value>
+ </qman:entry>
+ </qman:Arguments>
+ <qman:VhostRef>2deef1b3-d2c6-49f3-a8de-51f6a75a1a6b</qman:VhostRef>
+ <wsrf-rl:CurrentTime xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2">1232956293823</wsrf-rl:CurrentTime>
+ <qman:ExpireTime>9223372036854775807</qman:ExpireTime>
+ <qman:Durable>true</qman:Durable>
+ <qman:ConsumerCount>-2147483638</qman:ConsumerCount>
+ </qman:QManWsResourceProperties>
+ </wsrf-rp:GetResourcePropertyDocumentResponse>
+ </soap:Body>
+</soap:Envelope> \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/GetResourcePropertyRequest.out.ok b/qpid/java/management/client/src/example/GetResourcePropertyRequest.out.ok
new file mode 100644
index 0000000000..4fa0ab3b8d
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetResourcePropertyRequest.out.ok
@@ -0,0 +1,588 @@
+ GetResourcePropertyExample
+-------------------------------------------------------------------
+
+This example shows how to get the property value
+from a WS-Resource.
+First of all a request is send to WS-DM in order to get
+all registered WS-Resources.
+If the returned list is not empty then a GetMetadataRequest
+to the first child.
+The result metadata descriptor contains all properties of
+the target WS-Resource.
+For each of them a GetResourcePropertyRequest is sent
+ in order to get its value.
+
+-------------------------------------------------------------------
+
+Type enter to proceed...
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:e581b9cb-04a9-a87f-7763-dcf227ed7f8b</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:27bab9a7-89aa-16a1-966b-c0aa19d3b352</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:e581b9cb-04a9-a87f-7763-dcf227ed7f8b</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-sg:Entry xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">
+ <wsrf-sg:ServiceGroupEntryEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/ServiceGroupEntry</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <muse-wsa:ResourceId xmlns:muse-wsa="http://ws.apache.org/muse/addressing">uuid:b220e2bd-0370-da4e-fc71-5e283954d319</muse-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:ServiceGroupEntryEPR>
+ <wsrf-sg:MemberServiceEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <qman-wsa:ResourceId xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:MemberServiceEPR>
+ <wsrf-sg:Content/>
+ </wsrf-sg:Entry>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:c5efae22-bc2f-ccdd-477c-621d4e49cd77</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <qman:GetMetadata xmlns:qman="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <qman:Dialect>http://docs.oasis-open.org/wsrf/rmd-1</qman:Dialect>
+ </qman:GetMetadata>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:4d933676-fb60-3fae-d7b9-39324a8661fc</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:c5efae22-bc2f-ccdd-477c-621d4e49cd77</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsx:Metadata xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <wsx:MetadataSection>
+ <wsrmd:MetadataDescriptor
+ interface="qman:QManWsResourcePortType"
+ name="QManWsResourceMetadata"
+ wsdlLocation="http://docs.oasis-open.org/wsrf/rmd-1 QManWsResource.wsdl"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman" xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1">
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:MgmtPubInterval" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Name" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:TerminationTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable"
+ name="qman:MsgTotalEnqueues" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Arguments" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:VhostRef" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:CurrentTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:ExpireTime" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Durable" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:ConsumerCount" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:Type" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ </wsrmd:MetadataDescriptor>
+ </wsx:MetadataSection>
+ </wsx:Metadata>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:83c13239-3e37-853d-776d-3dac2729117b</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:MgmtPubInterval</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0beb3927-6420-9877-f163-4288ea1560da</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:83c13239-3e37-853d-776d-3dac2729117b</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:MgmtPubInterval xmlns:qman="http://amqp.apache.org/qpid/management/qman">32767</qman:MgmtPubInterval>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:30b678da-f1fa-8120-7660-9eb86ebb76b7</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Name</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:8343b104-1a82-212a-c84a-460cbc223327</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:30b678da-f1fa-8120-7660-9eb86ebb76b7</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:Name xmlns:qman="http://amqp.apache.org/qpid/management/qman">Initial Name</qman:Name>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:795eaebd-dd48-75b0-18b3-a7e3c1fd4d5a</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:MsgTotalEnqueues</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:b6b91fd1-762b-3ae4-76c3-fe206c93b76d</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:795eaebd-dd48-75b0-18b3-a7e3c1fd4d5a</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:MsgTotalEnqueues xmlns:qman="http://amqp.apache.org/qpid/management/qman">9223372036854775797</qman:MsgTotalEnqueues>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:f57f0179-a31b-8607-668b-c2602838c363</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Arguments</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:fc07cbe4-a19a-6374-c985-49fa525d3e90</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:f57f0179-a31b-8607-668b-c2602838c363</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:Arguments
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <qman:entry>
+ <qman:key>Key3</qman:key>
+ <qman:value xsi:type="xsd:integer">2147483647</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key4</qman:key>
+ <qman:value xsi:type="xsd:float">3.4028235E38</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key1</qman:key>
+ <qman:value xsi:type="xsd:string">aStringValue</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key2</qman:key>
+ <qman:value xsi:type="xsd:long">-9223372036854775808</qman:value>
+ </qman:entry>
+ </qman:Arguments>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:5d735040-95d1-7c87-7ac9-b4a5700e0ab9</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:VhostRef</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:cdfe639c-357b-d55b-fe7d-4a203d46465c</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:5d735040-95d1-7c87-7ac9-b4a5700e0ab9</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:VhostRef xmlns:qman="http://amqp.apache.org/qpid/management/qman">2deef1b3-d2c6-49f3-a8de-51f6a75a1a6b</qman:VhostRef>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:e3fde856-57f5-a96f-a382-5e0f4206a6fe</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:ExpireTime</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:fa290c54-bac1-62d6-701e-3b8ec2eaf817</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:e3fde856-57f5-a96f-a382-5e0f4206a6fe</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:ExpireTime xmlns:qman="http://amqp.apache.org/qpid/management/qman">9223372036854775807</qman:ExpireTime>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:092dd5d9-c443-428c-813c-13428058b08c</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Durable</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:1053800e-345c-abed-e352-f524c1d24afa</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:092dd5d9-c443-428c-813c-13428058b08c</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:Durable xmlns:qman="http://amqp.apache.org/qpid/management/qman">true</qman:Durable>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:bc291be9-b1d1-f668-f3c5-29647e78d6bf</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:ConsumerCount</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:7467dddf-033e-f540-241f-76ce81c0ebeb</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:bc291be9-b1d1-f668-f3c5-29647e78d6bf</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:ConsumerCount xmlns:qman="http://amqp.apache.org/qpid/management/qman">-2147483638</qman:ConsumerCount>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:92783239-777c-27fa-cec2-ee3afecf5c32</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Type</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:af8168b4-6c13-c736-b521-f2b410541dd0</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:92783239-777c-27fa-cec2-ee3afecf5c32</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"/>
+ </soap:Body>
+</soap:Envelope> \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/GetWsdlMetadata.out.ko.no.resources b/qpid/java/management/client/src/example/GetWsdlMetadata.out.ko.no.resources
new file mode 100644
index 0000000000..6e727261f9
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetWsdlMetadata.out.ko.no.resources
@@ -0,0 +1,58 @@
+ GetWSDLMetadataExample
+-------------------------------------------------------------------
+
+This example shows the usage of WS-DM
+GetResourcePropertyRequest / Response on a
+Group service.
+The target resource is the WS-DM Adapter itself
+and the requested property is "ws-rp:Entry".
+WS-DM Adapter is a special WS-Resource (is a Group)
+that acts as the main entry point for retrieving
+all other managed resources.
+So clients that want to deal with QMan WS-Resources
+must first get resource identifiers sending
+a GetResourcePropertyRequest to WS-DM Adapter
+with "ws-rp:Entry" as target target property.
+
+-------------------------------------------------------------------
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:7f801eff-c528-91e8-33eb-3d1dd164bce7</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:86a34968-38aa-83e8-47dd-8e86ffd8ac06</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:7f801eff-c528-91e8-33eb-3d1dd164bce7</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+----------------------------WARNING---------------------------
+Cannot proceed with the example... it seems
+that there are no managed WS-Resources on QMan.
+Please check QMan in order to see that it is really
+connected with a broker.
+-------------------------------------------------------------------
diff --git a/qpid/java/management/client/src/example/GetWsdlMetadata.out.ok b/qpid/java/management/client/src/example/GetWsdlMetadata.out.ok
new file mode 100644
index 0000000000..16a4c1e07e
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetWsdlMetadata.out.ok
@@ -0,0 +1,1968 @@
+ GetWSDLMetadataExample
+-------------------------------------------------------------------
+
+This example shows the usage of WS-DM
+GetResourcePropertyRequest / Response on a
+Group service.
+The target resource is the WS-DM Adapter itself
+and the requested property is "ws-rp:Entry".
+WS-DM Adapter is a special WS-Resource (is a Group)
+that acts as the main entry point for retrieving
+all other managed resources.
+So clients that want to deal with QMan WS-Resources
+must first get resource identifiers sending
+a GetResourcePropertyRequest to WS-DM Adapter
+with "ws-rp:Entry" as target target property.
+
+-------------------------------------------------------------------
+
+Type enter to proceed.
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:ec4d0c03-3174-e39d-4a36-8f109056865b</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0f47d614-565e-5360-8dcc-ea8e4771e4dd</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:ec4d0c03-3174-e39d-4a36-8f109056865b</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-sg:Entry xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">
+ <wsrf-sg:ServiceGroupEntryEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/ServiceGroupEntry</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <muse-wsa:ResourceId xmlns:muse-wsa="http://ws.apache.org/muse/addressing">uuid:1d01b4ee-7d23-3a30-342e-62fc49984fe6</muse-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:ServiceGroupEntryEPR>
+ <wsrf-sg:MemberServiceEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <qman-wsa:ResourceId xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=d5b32f44-5164-4e59-8f1d-a6f8c0a8a748,class=queue,name=1232872843214,objectId=a3759467-bede-476d-8dde-169f1a652191,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:MemberServiceEPR>
+ <wsrf-sg:Content/>
+ </wsrf-sg:Entry>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0cdb5112-09e0-ac39-06ba-393843f06e42</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=d5b32f44-5164-4e59-8f1d-a6f8c0a8a748,class=queue,name=1232872843214,objectId=a3759467-bede-476d-8dde-169f1a652191,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <qman:GetMetadata xmlns:qman="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <qman:Dialect>http://schemas.xmlsoap.org/wsdl/</qman:Dialect>
+ </qman:GetMetadata>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:980617c8-e3a0-ebf1-8f5a-2b43d3d6d416</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0cdb5112-09e0-ac39-06ba-393843f06e42</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=d5b32f44-5164-4e59-8f1d-a6f8c0a8a748,class=queue,name=1232872843214,objectId=a3759467-bede-476d-8dde-169f1a652191,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsx:Metadata xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <wsx:MetadataSection>
+ <wsdl:definitions name="QManWsResource"
+ targetNamespace="http://amqp.apache.org/qpid/management/qman"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl-soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1"
+ xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <wsdl:types>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://www.w3.org/2005/08/addressing"
+ xmlns:tns="http://www.w3.org/2005/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="EndpointReference"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:element name="Address" type="tns:AttributedURIType"/>
+ <xs:element minOccurs="0"
+ name="ReferenceParameters" type="tns:ReferenceParametersType"/>
+ <xs:element minOccurs="0" ref="tns:Metadata"/>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:complexType mixed="false"
+ name="ReferenceParametersType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0" namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:element name="Metadata"
+ type="tns:MetadataType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="MetadataType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0" namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:element name="MessageID"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="RelatesTo"
+ type="tns:RelatesToType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="RelatesToType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute
+ default="http://www.w3.org/2005/08/addressing/reply"
+ name="RelationshipType"
+ type="tns:RelationshipTypeOpenEnum" use="optional"/>
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:simpleType
+ name="RelationshipTypeOpenEnum" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:union memberTypes="tns:RelationshipType xs:anyURI"/>
+ </xs:simpleType>
+ <xs:simpleType name="RelationshipType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:restriction base="xs:anyURI">
+ <xs:enumeration value="http://www.w3.org/2005/08/addressing/reply"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="ReplyTo"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="From"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="FaultTo"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="To"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Action"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:attribute name="IsReferenceParameter"
+ type="xs:boolean" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:simpleType name="FaultCodesOpenEnumType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:union memberTypes="tns:FaultCodesType xs:QName"/>
+ </xs:simpleType>
+ <xs:simpleType name="FaultCodesType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:restriction base="xs:QName">
+ <xs:enumeration value="tns:InvalidAddressingHeader"/>
+ <xs:enumeration value="tns:InvalidAddress"/>
+ <xs:enumeration value="tns:InvalidEPR"/>
+ <xs:enumeration value="tns:InvalidCardinality"/>
+ <xs:enumeration value="tns:MissingAddressInEPR"/>
+ <xs:enumeration value="tns:DuplicateMessageID"/>
+ <xs:enumeration value="tns:ActionMismatch"/>
+ <xs:enumeration value="tns:MessageAddressingHeaderRequired"/>
+ <xs:enumeration value="tns:DestinationUnreachable"/>
+ <xs:enumeration value="tns:ActionNotSupported"/>
+ <xs:enumeration value="tns:EndpointUnavailable"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="RetryAfter"
+ type="tns:AttributedUnsignedLongType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedUnsignedLongType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:unsignedLong">
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:element name="ProblemHeaderQName"
+ type="tns:AttributedQNameType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedQNameType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:QName">
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:element name="ProblemHeader"
+ type="tns:AttributedAnyType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedAnyType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any maxOccurs="1" minOccurs="1"
+ namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:element name="ProblemIRI"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="ProblemAction"
+ type="tns:ProblemActionType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="ProblemActionType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:element minOccurs="0" ref="tns:Action"/>
+ <xs:element minOccurs="0"
+ name="SoapAction" type="xs:anyURI"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified"
+ targetNamespace="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:tns="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:import
+ namespace="http://www.w3.org/2005/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="GetMetadata" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" ref="tns:Dialect"/>
+ <xs:element minOccurs="0" ref="tns:Identifier"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="Dialect" type="xs:anyURI" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Identifier"
+ type="xs:anyURI" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Metadata" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="tns:MetadataSection"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="MetadataSection" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType>
+ <xs:choice>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ <xs:element ref="tns:MetadataReference"/>
+ <xs:element ref="tns:Location"/>
+ </xs:choice>
+ <xs:attribute name="Dialect"
+ type="xs:anyURI" use="required"/>
+ <xs:attribute name="Identifier" type="xs:anyURI"/>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="MetadataReference"
+ type="wsa:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Location" type="xs:anyURI" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType name="AnyXmlType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##any" processContents="lax"/>
+ </xs:complexType>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:element name="CurrentTime">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:dateTime">
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="TerminationTime" nillable="true">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:dateTime">
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="ScheduledResourceTerminationRP">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" ref="wsrf-rl:CurrentTime"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" ref="wsrf-rl:TerminationTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="Destroy">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="DestroyResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:complexType name="ResourceNotDestroyedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="ResourceNotDestroyedFault" type="wsrf-rl:ResourceNotDestroyedFaultType"/>
+ <xsd:element name="SetTerminationTime">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element
+ name="RequestedTerminationTime"
+ nillable="true" type="xsd:dateTime"/>
+ <xsd:element
+ name="RequestedLifetimeDuration" type="xsd:duration"/>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="SetTerminationTimeResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ name="NewTerminationTime"
+ nillable="true" type="xsd:dateTime"/>
+ <xsd:element name="CurrentTime" type="xsd:dateTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="UnableToSetTerminationTimeFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnableToSetTerminationTimeFault" type="wsrf-rl:UnableToSetTerminationTimeFaultType"/>
+ <xsd:complexType name="TerminationTimeChangeRejectedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="TerminationTimeChangeRejectedFault" type="wsrf-rl:TerminationTimeChangeRejectedFaultType"/>
+ <xsd:element name="TerminationNotification">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="1"
+ name="TerminationTime"
+ nillable="true" type="xsd:dateTime"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="TerminationReason" type="xsd:anyType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:element name="QueryExpressionDialect" type="xsd:anyURI"/>
+ <xsd:element name="QueryExpressionRPDocument">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrf-rp:QueryExpressionDialect"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:attribute name="ResourceProperties" type="xsd:QName"/>
+ <xsd:complexType name="ResourcePropertyValueChangeNotificationType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="OldValues" nillable="true">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" name="NewValues" nillable="true">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element
+ name="ResourcePropertyValueChangeNotification" type="wsrf-rp:ResourcePropertyValueChangeNotificationType"/>
+ <xsd:complexType mixed="true" name="QueryExpressionType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="0" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="Dialect" type="xsd:anyURI"/>
+ </xsd:complexType>
+ <xsd:element name="QueryExpression" type="wsrf-rp:QueryExpressionType"/>
+ <xsd:element name="GetResourcePropertyDocument">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="GetResourcePropertyDocumentResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="GetResourceProperty" type="xsd:QName"/>
+ <xsd:element name="GetResourcePropertyResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="InvalidResourcePropertyQNameFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="InvalidResourcePropertyQNameFault" type="wsrf-rp:InvalidResourcePropertyQNameFaultType"/>
+ <xsd:element name="GetMultipleResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="1"
+ name="ResourceProperty" type="xsd:QName"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="GetMultipleResourcePropertiesResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="PutResourcePropertyDocument">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="PutResourcePropertyDocumentResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="ResourcePropertyChangeFailureType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="CurrentValue">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="RequestedValue">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:attribute name="Restored" type="xsd:boolean"/>
+ </xsd:complexType>
+ <xsd:complexType name="UnableToPutResourcePropertyDocumentFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnableToPutResourcePropertyDocumentFault" type="wsrf-rp:UnableToPutResourcePropertyDocumentFaultType"/>
+ <xsd:complexType name="InsertType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="1" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Insert" type="wsrf-rp:InsertType"/>
+ <xsd:complexType name="UpdateType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="1" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Update" type="wsrf-rp:UpdateType"/>
+ <xsd:complexType name="DeleteType">
+ <xsd:attribute name="ResourceProperty"
+ type="xsd:QName" use="required"/>
+ </xsd:complexType>
+ <xsd:element name="Delete" type="wsrf-rp:DeleteType"/>
+ <xsd:element name="SetResourceProperties">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded" minOccurs="1">
+ <xsd:element ref="wsrf-rp:Insert"/>
+ <xsd:element ref="wsrf-rp:Update"/>
+ <xsd:element ref="wsrf-rp:Delete"/>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="SetResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:complexType name="InvalidModificationFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidModificationFault" type="wsrf-rp:InvalidModificationFaultType"/>
+ <xsd:complexType name="UnableToModifyResourcePropertyFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnableToModifyResourcePropertyFault" type="wsrf-rp:UnableToModifyResourcePropertyFaultType"/>
+ <xsd:complexType name="SetResourcePropertyRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="SetResourcePropertyRequestFailedFault" type="wsrf-rp:SetResourcePropertyRequestFailedFaultType"/>
+ <xsd:complexType name="InsertResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="InsertResourcePropertiesRequestFailedFault" type="wsrf-rp:InsertResourcePropertiesRequestFailedFaultType"/>
+ <xsd:complexType name="UpdateResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UpdateResourcePropertiesRequestFailedFault" type="wsrf-rp:UpdateResourcePropertiesRequestFailedFaultType"/>
+ <xsd:complexType name="DeleteResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="DeleteResourcePropertiesRequestFailedFault" type="wsrf-rp:DeleteResourcePropertiesRequestFailedFaultType"/>
+ <xsd:element name="InsertResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Insert"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="InsertResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="UpdateResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Update"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="UpdateResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="DeleteResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Delete"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="DeleteResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="QueryResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" ref="wsrf-rp:QueryExpression"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="QueryResourcePropertiesResponse">
+ <xsd:complexType>
+ <xsd:complexContent mixed="true">
+ <xsd:restriction base="xsd:anyType">
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="1" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="UnknownQueryExpressionDialectFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnknownQueryExpressionDialectFault" type="wsrf-rp:UnknownQueryExpressionDialectFaultType"/>
+ <xsd:complexType name="InvalidQueryExpressionFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="InvalidQueryExpressionFault" type="wsrf-rp:InvalidQueryExpressionFaultType"/>
+ <xsd:complexType name="QueryEvaluationErrorFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="QueryEvaluationErrorFault" type="wsrf-rp:QueryEvaluationErrorFaultType"/>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:complexType name="ResourceUnknownFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResourceUnknownFault" type="wsrf-r:ResourceUnknownFaultType"/>
+ <xsd:complexType name="ResourceUnavailableFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResourceUnavailableFault" type="wsrf-r:ResourceUnavailableFaultType"/>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rmd-1"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rp-2"/>
+ <xsd:import namespace="http://www.w3.org/2005/08/addressing"/>
+ <xsd:simpleType name="PairsOfURIType">
+ <xsd:list itemType="xsd:anyURI"/>
+ </xsd:simpleType>
+ <xsd:attribute name="Descriptor" type="xsd:QName"/>
+ <xsd:attribute name="DescriptorLocation" type="xsd:anyURI"/>
+ <xsd:complexType mixed="true" name="DocumentationType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0" namespace="##any" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ <xsd:complexType name="DocumentedType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="DefinitionsType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrmd:MetadataDescriptor"/>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute
+ name="targetNamespace"
+ type="xsd:anyURI" use="required"/>
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="Definitions" type="wsrmd:DefinitionsType">
+ <xsd:key name="MetadataDescriptor">
+ <xsd:annotation>
+ <xsd:documentation>
+ To form a QName, the name of any MetadataDescriptor must be
+ unique within a Definitions element.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:selector xpath="wsrmd:MetadataDescriptor"/>
+ <xsd:field xpath="@name"/>
+ </xsd:key>
+ </xsd:element>
+ <xsd:complexType name="MetadataDescriptorType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrmd:Property"/>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="name"
+ type="xsd:NCName" use="required"/>
+ <xsd:attribute name="interface"
+ type="xsd:QName" use="required"/>
+ <xsd:attribute
+ name="wsdlLocation" type="wsrmd:PairsOfURIType"/>
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="MetadataDescriptor" type="wsrmd:MetadataDescriptorType"/>
+ <xsd:complexType name="PropertyType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element
+ maxOccurs="1"
+ minOccurs="0" ref="wsrmd:ValidValues"/>
+ <xsd:element
+ maxOccurs="1"
+ minOccurs="0" ref="wsrmd:ValidValueRange"/>
+ </xsd:choice>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" ref="wsrmd:StaticValues"/>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="name"
+ type="xsd:QName" use="required"/>
+ <xsd:attribute name="mutability" type="wsrmd:MutabilityType"/>
+ <xsd:attribute
+ name="modifiability" type="wsrmd:ModifiabilityType"/>
+ <xsd:attribute default="false"
+ name="subscribability" type="xsd:boolean"/>
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="Property" type="wsrmd:PropertyType"/>
+ <xsd:simpleType name="MutabilityType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="constant"/>
+ <xsd:enumeration value="appendable"/>
+ <xsd:enumeration value="mutable"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="ModifiabilityType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="read-only"/>
+ <xsd:enumeration value="read-write"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:complexType mixed="true" name="ValidValuesType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="ValidValues" type="wsrmd:ValidValuesType"/>
+ <xsd:complexType mixed="true" name="ValidValueRangeType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="lowerBound" type="xsd:anySimpleType"/>
+ <xsd:attribute name="upperBound" type="xsd:anySimpleType"/>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="ValidValueRange" type="wsrmd:ValidValueRangeType"/>
+ <xsd:complexType mixed="true" name="StaticValuesType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="StaticValues" type="wsrmd:StaticValuesType"/>
+ <xsd:complexType mixed="true" name="InitialValuesType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="InitialValues" type="wsrmd:InitialValuesType"/>
+ <xsd:complexType name="MetadataDescriptorReferenceType">
+ <xsd:complexContent>
+ <xsd:extension base="wsa:EndpointReferenceType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="MetadataDescriptorReference" type="wsrmd:MetadataDescriptorReferenceType"/>
+ <xsd:element name="MetadataResourceRP" type="wsrmd:DefinitionsType"/>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://amqp.apache.org/qpid/management/qman">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rl-2"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rp-2"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:element name="QManWsResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rl:CurrentTime"/>
+ <xsd:element ref="wsrf-rl:TerminationTime"/>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrf-rp:QueryExpressionDialect"/>
+ <xsd:element ref="qman:Name"/>
+ <xsd:element ref="qman:Type"/>
+ <xsd:element ref="qman:Arguments"/>
+ <xsd:element ref="qman:VhostRef"/>
+ <xsd:element ref="qman:Durable"/>
+ <xsd:element ref="qman:MsgTotalEnqueues"/>
+ <xsd:element ref="qman:ConsumerCount"/>
+ <xsd:element ref="qman:ExpireTime"/>
+ <xsd:element ref="qman:MgmtPubInterval"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="QManFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="MethodInvocationFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="EntityInstanceNotFoundFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="MalformedEntityNameFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="NoSuchAttributeFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="result">
+ <xsd:sequence>
+ <xsd:element name="statusCode" type="xsd:long"/>
+ <xsd:element name="statusText" type="xsd:string"/>
+ <xsd:complexType name="outputParameters">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" name="entry">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:name
+ name="key" type="xsd:string"/>
+ <xsd:element
+ name="value" type="xsd:anyType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:complexType>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Name" type="xsd:string"/>
+ <xsd:element name="Type" type="xsd:string"/>
+ <xsd:complexType name="map">
+ <xsd:sequence>
+ <xsd:element maxOccurs="unbounded"
+ minOccurs="0" name="entry">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="key" type="xsd:string"/>
+ <xsd:element
+ name="value" type="xsd:anyType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Arguments" type="qman:map"/>
+ <xsd:complexType name="uuid">
+ <xsd:sequence>
+ <xsd:element name="uuid" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="VhostRef" type="qman:uuid"/>
+ <xsd:element name="Durable" type="xsd:boolean"/>
+ <xsd:element name="MsgTotalEnqueues" type="xsd:long"/>
+ <xsd:element name="ConsumerCount" type="xsd:integer"/>
+ <xsd:element name="ExpireTime" type="xsd:dateTime"/>
+ <xsd:element name="MgmtPubInterval" type="xsd:short"/>
+ <xsd:element
+ name="echoWithSimpleTypesRequest" type="qman:echoWithSimpleTypesRequest"/>
+ <xsd:element
+ name="echoWithSimpleTypesResponse" type="qman:echoWithSimpleTypesResponse"/>
+ <xsd:complexType name="echoWithSimpleTypesRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="xsd:long"/>
+ <xsd:element name="p2" type="xsd:boolean"/>
+ <xsd:element name="p3" type="xsd:double"/>
+ <xsd:element name="p4" type="xsd:float"/>
+ <xsd:element name="p5" type="xsd:integer"/>
+ <xsd:element name="p6" type="xsd:short"/>
+ <xsd:element name="p7" type="xsd:string"/>
+ <xsd:element name="p8" type="xsd:anyURI"/>
+ <xsd:element name="p9" type="xsd:dateTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithSimpleTypesResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithArraysRequest" type="qman:echoWithArraysRequest"/>
+ <xsd:element name="echoWithArraysResponse" type="qman:echoWithArraysResponse"/>
+ <xsd:complexType name="arrayOfLong">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:long"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfBoolean">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:boolean"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfDouble">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:double"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfFloat">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:float"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfInteger">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:integer"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfShort">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:short"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfString">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfURI">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:anyURI"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfDate">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:dateTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithArraysRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:arrayOfLong"/>
+ <xsd:element name="p2" type="qman:arrayOfBoolean"/>
+ <xsd:element name="p3" type="qman:arrayOfDouble"/>
+ <xsd:element name="p4" type="qman:arrayOfFloat"/>
+ <xsd:element name="p5" type="qman:arrayOfInteger"/>
+ <xsd:element name="p6" type="qman:arrayOfShort"/>
+ <xsd:element name="p7" type="qman:arrayOfString"/>
+ <xsd:element name="p8" type="qman:arrayOfURI"/>
+ <xsd:element name="p9" type="qman:arrayOfDate"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithArraysResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element
+ name="echoWithSimpleTypeArraysRequest" type="qman:echoWithSimpleTypeArraysRequest"/>
+ <xsd:element
+ name="echoWithSimpleTypeArraysResponse" type="qman:echoWithSimpleTypeArraysResponse"/>
+ <xsd:complexType name="arrayOfLong">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:long"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfBoolean">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:boolean"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfDouble">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:double"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfFloat">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:float"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfInt">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:integer"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfShort">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:short"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithSimpleTypeArraysRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:arrayOfLong"/>
+ <xsd:element name="p2" type="qman:arrayOfBoolean"/>
+ <xsd:element name="p3" type="qman:arrayOfDouble"/>
+ <xsd:element name="p4" type="qman:arrayOfFloat"/>
+ <xsd:element name="p5" type="qman:arrayOfInt"/>
+ <xsd:element name="p6" type="qman:arrayOfShort"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithSimpleTypeArraysResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithByteArrayRequest" type="qman:echoWithByteArrayRequest"/>
+ <xsd:element
+ name="echoWithByteArrayResponse" type="qman:echoWithByteArrayResponse"/>
+ <xsd:complexType name="arrayOfByte">
+ <xsd:sequence>
+ <xsd:element name="entry" type=""/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithByteArrayRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:arrayOfByte"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithByteArrayResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element
+ name="voidWithoutArgumentsRequest" type="qman:voidWithoutArgumentsRequest"/>
+ <xsd:element
+ name="voidWithoutArgumentsResponse" type="qman:voidWithoutArgumentsResponse"/>
+ <xsd:complexType name="voidWithoutArgumentsRequest">
+ <xsd:sequence/>
+ </xsd:complexType>
+ <xsd:complexType name="voidWithoutArgumentsResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="throwsExceptionRequest" type="qman:throwsExceptionRequest"/>
+ <xsd:element name="throwsExceptionResponse" type="qman:throwsExceptionResponse"/>
+ <xsd:complexType name="throwsExceptionRequest">
+ <xsd:sequence/>
+ </xsd:complexType>
+ <xsd:complexType name="throwsExceptionResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithUUIDRequest" type="qman:echoWithUUIDRequest"/>
+ <xsd:element name="echoWithUUIDResponse" type="qman:echoWithUUIDResponse"/>
+ <xsd:complexType name="echoWithUUIDRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:uuid"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithUUIDResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithMapRequest" type="qman:echoWithMapRequest"/>
+ <xsd:element name="echoWithMapResponse" type="qman:echoWithMapResponse"/>
+ <xsd:complexType name="echoWithMapRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:map"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithMapResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <xsd:import namespace="http://www.w3.org/2005/08/addressing"/>
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace">
+ <xsd:annotation>
+ <xsd:documentation>
+ Get access to the xml: attribute groups for xml:lang as declared on 'schema'
+ and 'documentation' below
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:import>
+ <xsd:element name="BaseFault" type="wsrf-bf:BaseFaultType"/>
+ <xsd:complexType name="BaseFaultType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" name="Timestamp" type="xsd:dateTime"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="Originator" type="wsa:EndpointReferenceType"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="ErrorCode">
+ <xsd:complexType>
+ <xsd:complexContent mixed="true">
+ <xsd:extension base="xsd:anyType">
+ <xsd:attribute
+ name="dialect"
+ type="xsd:anyURI" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="unbounded"
+ minOccurs="0" name="Description">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute
+ ref="xml:lang" use="optional"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="FaultCause">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1"
+ minOccurs="1"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ </xsd:schema>
+ <xs:schema
+ targetNamespace="http://www.w3.org/XML/1998/namespace"
+ xml:lang="en" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:attribute name="lang" type="xs:language"/>
+ <xs:attribute default="preserve" name="space">
+ <xs:simpleType>
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="base" type="xs:anyURI"/>
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ </xs:attributeGroup>
+ </xs:schema>
+ </wsdl:types>
+ <wsdl:message name="GetMetadataMsg">
+ <wsdl:part element="wsx:GetMetadata" name="GetMetadataMsg"/>
+ </wsdl:message>
+ <wsdl:message name="GetMetadataResponseMsg">
+ <wsdl:part element="wsx:Metadata" name="GetMetadataResponseMsg"/>
+ </wsdl:message>
+ <wsdl:message name="DestroyRequest">
+ <wsdl:part element="wsrf-rl:Destroy" name="DestroyRequest"/>
+ </wsdl:message>
+ <wsdl:message name="DestroyResponse">
+ <wsdl:part element="wsrf-rl:DestroyResponse" name="DestroyResponse"/>
+ </wsdl:message>
+ <wsdl:message name="ResourceNotDestroyedFault">
+ <wsdl:part
+ element="wsrf-rl:ResourceNotDestroyedFault" name="ResourceNotDestroyedFault"/>
+ </wsdl:message>
+ <wsdl:message name="ResourceUnknownFault">
+ <wsdl:part element="wsrf-r:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ </wsdl:message>
+ <wsdl:message name="ResourceUnavailableFault">
+ <wsdl:part
+ element="wsrf-r:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ </wsdl:message>
+ <wsdl:message name="SetTerminationTimeRequest">
+ <wsdl:part element="wsrf-rl:SetTerminationTime" name="SetTerminationTimeRequest"/>
+ </wsdl:message>
+ <wsdl:message name="SetTerminationTimeResponse">
+ <wsdl:part
+ element="wsrf-rl:SetTerminationTimeResponse" name="SetTerminationTimeResponse"/>
+ </wsdl:message>
+ <wsdl:message name="UnableToSetTerminationTimeFault">
+ <wsdl:part
+ element="wsrf-rl:UnableToSetTerminationTimeFault" name="UnableToSetTerminationTimeFault"/>
+ </wsdl:message>
+ <wsdl:message name="TerminationTimeChangeRejectedFault">
+ <wsdl:part
+ element="wsrf-rl:TerminationTimeChangeRejectedFault" name="TerminationTimeChangeRejectedFault"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentRequest">
+ <wsdl:part
+ element="wsrf-rp:GetResourcePropertyDocument" name="GetResourcePropertyDocumentRequest"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentResponse">
+ <wsdl:part
+ element="wsrf-rp:GetResourcePropertyDocumentResponse" name="GetResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyRequest">
+ <wsdl:part element="wsrf-rp:GetResourceProperty" name="GetResourcePropertyRequest"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyResponse">
+ <wsdl:part
+ element="wsrf-rp:GetResourcePropertyResponse" name="GetResourcePropertyResponse"/>
+ </wsdl:message>
+ <wsdl:message name="InvalidResourcePropertyQNameFault">
+ <wsdl:part
+ element="wsrf-rp:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesRequest">
+ <wsdl:part
+ element="wsrf-rp:GetMultipleResourceProperties" name="GetMultipleResourcePropertiesRequest"/>
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesResponse">
+ <wsdl:part
+ element="wsrf-rp:GetMultipleResourcePropertiesResponse" name="GetMultipleResourcePropertiesResponse"/>
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesRequest">
+ <wsdl:part
+ element="wsrf-rp:QueryResourceProperties" name="QueryResourcePropertiesRequest"/>
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesResponse">
+ <wsdl:part
+ element="wsrf-rp:QueryResourcePropertiesResponse" name="QueryResourcePropertiesResponse"/>
+ </wsdl:message>
+ <wsdl:message name="UnknownQueryExpressionDialectFault">
+ <wsdl:part
+ element="wsrf-rp:UnknownQueryExpressionDialectFault" name="UnknownQueryExpressionDialectFault"/>
+ </wsdl:message>
+ <wsdl:message name="InvalidQueryExpressionFault">
+ <wsdl:part
+ element="wsrf-rp:InvalidQueryExpressionFault" name="InvalidQueryExpressionFault"/>
+ </wsdl:message>
+ <wsdl:message name="QueryEvaluationErrorFault">
+ <wsdl:part
+ element="wsrf-rp:QueryEvaluationErrorFault" name="QueryEvaluationErrorFault"/>
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertiesRequest">
+ <wsdl:part
+ element="wsrf-rp:SetResourceProperties" name="SetResourcePropertiesRequest"/>
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertiesResponse">
+ <wsdl:part
+ element="wsrf-rp:SetResourcePropertiesResponse" name="SetResourcePropertiesResponse"/>
+ </wsdl:message>
+ <wsdl:message name="InvalidModificationFault">
+ <wsdl:part
+ element="wsrf-rp:InvalidModificationFault" name="InvalidModificationFault"/>
+ </wsdl:message>
+ <wsdl:message name="UnableToModifyResourcePropertyFault">
+ <wsdl:part
+ element="wsrf-rp:UnableToModifyResourcePropertyFault" name="UnableToModifyResourcePropertyFault"/>
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertyRequestFailedFault">
+ <wsdl:part
+ element="wsrf-rp:SetResourcePropertyRequestFailedFault" name="SetResourcePropertyRequestFailedFault"/>
+ </wsdl:message>
+ <wsdl:portType name="QManWsResourcePortType"
+ wsrf-rp:ResourceProperties="qman:QManWsResourceProperties"
+ wsrmd:Descriptor="QManWsResourceMetadata" wsrmd:DescriptorLocation="QManWsResource.rmd">
+ <wsdl:operation name="GetMetadata">
+ <wsdl:input message="qman:GetMetadataMsg"
+ name="GetMetadataMsg" wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata"/>
+ <wsdl:output
+ message="qman:GetMetadataResponseMsg"
+ name="GetMetadataResponseMsg" wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="Destroy">
+ <wsdl:input message="qman:DestroyRequest"
+ name="DestroyRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination/DestroyRequest"/>
+ <wsdl:output message="qman:DestroyResponse"
+ name="DestroyResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination/DestroyResponse"/>
+ <wsdl:fault
+ message="qman:ResourceNotDestroyedFault" name="ResourceNotDestroyedFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="SetTerminationTime">
+ <wsdl:input
+ message="qman:SetTerminationTimeRequest"
+ name="SetTerminationTimeRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination/SetTerminationTimeRequest"/>
+ <wsdl:output
+ message="qman:SetTerminationTimeResponse"
+ name="SetTerminationTimeResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination/SetTerminationTimeResponse"/>
+ <wsdl:fault
+ message="qman:UnableToSetTerminationTimeFault" name="UnableToSetTerminationTimeFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:TerminationTimeChangeRejectedFault" name="TerminationTimeChangeRejectedFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:input
+ message="qman:GetResourcePropertyDocumentRequest"
+ name="GetResourcePropertyDocumentRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"/>
+ <wsdl:output
+ message="qman:GetResourcePropertyDocumentResponse"
+ name="GetResourcePropertyDocumentResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:input
+ message="qman:GetResourcePropertyRequest"
+ name="GetResourcePropertyRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"/>
+ <wsdl:output
+ message="qman:GetResourcePropertyResponse"
+ name="GetResourcePropertyResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:input
+ message="qman:GetMultipleResourcePropertiesRequest"
+ name="GetMultipleResourcePropertiesRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"/>
+ <wsdl:output
+ message="qman:GetMultipleResourcePropertiesResponse"
+ name="GetMultipleResourcePropertiesResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl:input
+ message="qman:QueryResourcePropertiesRequest"
+ name="QueryResourcePropertiesRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesRequest"/>
+ <wsdl:output
+ message="qman:QueryResourcePropertiesResponse"
+ name="QueryResourcePropertiesResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:UnknownQueryExpressionDialectFault" name="UnknownQueryExpressionDialectFault"/>
+ <wsdl:fault
+ message="qman:InvalidQueryExpressionFault" name="InvalidQueryExpressionFault"/>
+ <wsdl:fault
+ message="qman:QueryEvaluationErrorFault" name="QueryEvaluationErrorFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="SetResourceProperties">
+ <wsdl:input
+ message="qman:SetResourcePropertiesRequest"
+ name="SetResourcePropertiesRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesRequest"/>
+ <wsdl:output
+ message="qman:SetResourcePropertiesResponse"
+ name="SetResourcePropertiesResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:InvalidModificationFault" name="InvalidModificationFault"/>
+ <wsdl:fault
+ message="qman:UnableToModifyResourcePropertyFault" name="UnableToModifyResourcePropertyFault"/>
+ <wsdl:fault
+ message="qman:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ <wsdl:fault
+ message="qman:SetResourcePropertyRequestFailedFault" name="SetResourcePropertyRequestFailedFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypes">
+ <wsdl:input
+ message="qman:echoWithSimpleTypesRequestMessage"
+ name="echoWithSimpleTypesRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypes"/>
+ <wsdl:output
+ message="qman:echoWithSimpleTypesResponseMessage"
+ name="echoWithSimpleTypesResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypesResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithArrays">
+ <wsdl:input
+ message="qman:echoWithArraysRequestMessage"
+ name="echoWithArraysRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithArrays"/>
+ <wsdl:output
+ message="qman:echoWithArraysResponseMessage"
+ name="echoWithArraysResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithArraysResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypeArrays">
+ <wsdl:input
+ message="qman:echoWithSimpleTypeArraysRequestMessage"
+ name="echoWithSimpleTypeArraysRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypeArrays"/>
+ <wsdl:output
+ message="qman:echoWithSimpleTypeArraysResponseMessage"
+ name="echoWithSimpleTypeArraysResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypeArraysResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithByteArray">
+ <wsdl:input
+ message="qman:echoWithByteArrayRequestMessage"
+ name="echoWithByteArrayRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithByteArray"/>
+ <wsdl:output
+ message="qman:echoWithByteArrayResponseMessage"
+ name="echoWithByteArrayResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithByteArrayResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="voidWithoutArguments">
+ <wsdl:input
+ message="qman:voidWithoutArgumentsRequestMessage"
+ name="voidWithoutArgumentsRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/voidWithoutArguments"/>
+ <wsdl:output
+ message="qman:voidWithoutArgumentsResponseMessage"
+ name="voidWithoutArgumentsResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/voidWithoutArgumentsResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="throwsException">
+ <wsdl:input
+ message="qman:throwsExceptionRequestMessage"
+ name="throwsExceptionRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/throwsException"/>
+ <wsdl:output
+ message="qman:throwsExceptionResponseMessage"
+ name="throwsExceptionResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/throwsExceptionResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithUUID">
+ <wsdl:input
+ message="qman:echoWithUUIDRequestMessage"
+ name="echoWithUUIDRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithUUID"/>
+ <wsdl:output
+ message="qman:echoWithUUIDResponseMessage"
+ name="echoWithUUIDResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithUUIDResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithMap">
+ <wsdl:input
+ message="qman:echoWithMapRequestMessage"
+ name="echoWithMapRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithMap"/>
+ <wsdl:output
+ message="qman:echoWithMapResponseMessage"
+ name="echoWithMapResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithMapResponse"/>
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="QManWsResourceBinding" type="qman:QManWsResourcePortType">
+ <wsdl-soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="GetMetadata"/>
+ <wsdl:input>
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="Destroy">
+ <wsdl-soap:operation soapAction="Destroy"/>
+ <wsdl:input name="DestroyRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="DestroyResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceNotDestroyedFault">
+ <wsdl-soap:fault
+ name="ResourceNotDestroyedFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="SetTerminationTime">
+ <wsdl-soap:operation soapAction="SetTerminationTime"/>
+ <wsdl:input name="SetTerminationTimeRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="SetTerminationTimeResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="UnableToSetTerminationTimeFault">
+ <wsdl-soap:fault
+ name="UnableToSetTerminationTimeFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="TerminationTimeChangeRejectedFault">
+ <wsdl-soap:fault
+ name="TerminationTimeChangeRejectedFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl-soap:operation soapAction="GetResourcePropertyDocument"/>
+ <wsdl:input name="GetResourcePropertyDocumentRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetResourcePropertyDocumentResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl-soap:operation soapAction="GetResourceProperty"/>
+ <wsdl:input name="GetResourcePropertyRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetResourcePropertyResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ name="InvalidResourcePropertyQNameFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl-soap:operation soapAction="GetMultipleResourceProperties"/>
+ <wsdl:input name="GetMultipleResourcePropertiesRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetMultipleResourcePropertiesResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ name="InvalidResourcePropertyQNameFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl-soap:operation soapAction="QueryResourceProperties"/>
+ <wsdl:input name="QueryResourcePropertiesRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="QueryResourcePropertiesResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault">
+ <wsdl-soap:fault
+ name="UnknownQueryExpressionDialectFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidQueryExpressionFault">
+ <wsdl-soap:fault
+ name="InvalidQueryExpressionFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="QueryEvaluationErrorFault">
+ <wsdl-soap:fault
+ name="QueryEvaluationErrorFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="SetResourceProperties">
+ <wsdl-soap:operation soapAction="http://oasis.org/SetResourceProperties"/>
+ <wsdl:input name="SetResourcePropertiesRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="SetResourcePropertiesResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidModificationFault">
+ <wsdl-soap:fault
+ name="InvalidModificationFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnableToModifyResourcePropertyFault">
+ <wsdl-soap:fault
+ name="UnableToModifyResourcePropertyFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ name="InvalidResourcePropertyQNameFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="SetResourcePropertyRequestFailedFault">
+ <wsdl-soap:fault
+ name="SetResourcePropertyRequestFailedFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="http://ws.apache.org/muse/test/wsrf/GetMetadata"/>
+ <wsdl:input name="GetMetadataMsg">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetMetadataResponseMsg">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypes">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypes"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithArrays">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithArrays"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypeArrays">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypeArrays"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithByteArray">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithByteArray"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="voidWithoutArguments">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/voidWithoutArguments"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="throwsException">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/throwsException"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithUUID">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithUUID"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithMap">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithMap"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="QManWsResourceService">
+ <wsdl:port binding="qman:QManWsResourceBinding" name="QManWsResourcePort">
+ <wsdl-soap:address location="http://romagazzarini:8080/qman/services/QManWsResource"/>
+ </wsdl:port>
+ </wsdl:service>
+ <message name="echoWithSimpleTypesRequestMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypesRequest" name="echoWithSimpleTypesRequest"/>
+ </message>
+ <wsdl:message name="echoWithSimpleTypesResponseMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypesResponse" name="echoWithSimpleTypesResponse"/>
+ </wsdl:message>
+ <message name="echoWithArraysRequestMessage">
+ <wsdl:part element="qman:echoWithArraysRequest" name="echoWithArraysRequest"/>
+ </message>
+ <wsdl:message name="echoWithArraysResponseMessage">
+ <wsdl:part element="qman:echoWithArraysResponse" name="echoWithArraysResponse"/>
+ </wsdl:message>
+ <message name="echoWithSimpleTypeArraysRequestMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypeArraysRequest" name="echoWithSimpleTypeArraysRequest"/>
+ </message>
+ <wsdl:message name="echoWithSimpleTypeArraysResponseMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypeArraysResponse" name="echoWithSimpleTypeArraysResponse"/>
+ </wsdl:message>
+ <message name="echoWithByteArrayRequestMessage">
+ <wsdl:part
+ element="qman:echoWithByteArrayRequest" name="echoWithByteArrayRequest"/>
+ </message>
+ <wsdl:message name="echoWithByteArrayResponseMessage">
+ <wsdl:part
+ element="qman:echoWithByteArrayResponse" name="echoWithByteArrayResponse"/>
+ </wsdl:message>
+ <message name="voidWithoutArgumentsRequestMessage">
+ <wsdl:part
+ element="qman:voidWithoutArgumentsRequest" name="voidWithoutArgumentsRequest"/>
+ </message>
+ <wsdl:message name="voidWithoutArgumentsResponseMessage">
+ <wsdl:part
+ element="qman:voidWithoutArgumentsResponse" name="voidWithoutArgumentsResponse"/>
+ </wsdl:message>
+ <message name="throwsExceptionRequestMessage">
+ <wsdl:part element="qman:throwsExceptionRequest" name="throwsExceptionRequest"/>
+ </message>
+ <wsdl:message name="throwsExceptionResponseMessage">
+ <wsdl:part
+ element="qman:throwsExceptionResponse" name="throwsExceptionResponse"/>
+ </wsdl:message>
+ <message name="echoWithUUIDRequestMessage">
+ <wsdl:part element="qman:echoWithUUIDRequest" name="echoWithUUIDRequest"/>
+ </message>
+ <wsdl:message name="echoWithUUIDResponseMessage">
+ <wsdl:part element="qman:echoWithUUIDResponse" name="echoWithUUIDResponse"/>
+ </wsdl:message>
+ <message name="echoWithMapRequestMessage">
+ <wsdl:part element="qman:echoWithMapRequest" name="echoWithMapRequest"/>
+ </message>
+ <wsdl:message name="echoWithMapResponseMessage">
+ <wsdl:part element="qman:echoWithMapResponse" name="echoWithMapResponse"/>
+ </wsdl:message>
+ </wsdl:definitions>
+ </wsx:MetadataSection>
+ </wsx:Metadata>
+ </soap:Body>
+</soap:Envelope> \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/PauseAndResumeSubscription.out.ok b/qpid/java/management/client/src/example/PauseAndResumeSubscription.out.ok
new file mode 100644
index 0000000000..8a98e1d0b7
--- /dev/null
+++ b/qpid/java/management/client/src/example/PauseAndResumeSubscription.out.ok
@@ -0,0 +1,133 @@
+This example is demonstrating a WS-Notification scenario
+when (for simplicity) QMan is at the same time consumer
+and producer.
+
+Specifically the example shows how a requestor can create,
+pause and resume a subscription.
+Type enter to proceed...
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:485cc87c-660e-de43-e8fa-4ad5fffa95a6</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsnt:Subscribe xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2">
+ <wsnt:ConsumerReference>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/consumer</wsa:Address>
+ </wsnt:ConsumerReference>
+ </wsnt:Subscribe>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0ee610d1-e211-95c6-a498-e1084a610c44</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:485cc87c-660e-de43-e8fa-4ad5fffa95a6</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://romagazzarini:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsnt:SubscribeResponse xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2">
+ <wsnt:SubscriptionReference>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <qman-wsa:ResourceId xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsnt:SubscriptionReference>
+ <wsnt:CurrentTime>2009-02-27T13:51:56+01:00</wsnt:CurrentTime>
+ </wsnt:SubscribeResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/PauseSubscriptionRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:35cc80af-84ac-2456-3e1f-edc2a7f60970</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsnt:PauseSubscription xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/PauseSubscriptionResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:bb53d38a-428c-3d90-cc45-29d5cb27a8df</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:35cc80af-84ac-2456-3e1f-edc2a7f60970</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <muse-op:PauseSubscriptionResponse xmlns:muse-op="http://docs.oasis-open.org/wsn/b-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/ResumeSubscriptionRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:bfb48615-905a-e472-a9ca-5483fa592f60</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsnt:ResumeSubscription xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/ResumeSubscriptionResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:aab4cf18-3cc0-30c4-7036-009e26bb3213</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:bfb48615-905a-e472-a9ca-5483fa592f60</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <muse-op:ResumeSubscriptionResponse xmlns:muse-op="http://docs.oasis-open.org/wsn/b-2"/>
+ </soap:Body>
+</soap:Envelope>
+
diff --git a/qpid/java/management/client/src/example/README.txt b/qpid/java/management/client/src/example/README.txt
new file mode 100644
index 0000000000..5365a416e5
--- /dev/null
+++ b/qpid/java/management/client/src/example/README.txt
@@ -0,0 +1,69 @@
+*** QMan WS-DM examples ***
+
+1) DESCRIPTION
+This set of examples shows QMan WS-DM interface capabilities.
+Each example is articulated in the following way.
+First the name of the example class with a brief description about that is printed out. For example :
+
+ GetWSDLMetadataExample
+-------------------------------------------------------------------
+
+This example shows the usage of WS-DM
+GetResourcePropertyRequest / Response on a
+Group service.
+The target resource is the WS-DM Adapter itself
+and the requested property is "ws-rp:Entry".
+WS-DM Adapter is a special WS-Resource (is a Group)
+that acts as the main entry point for retrieving
+all other managed resources.
+So clients that want to deal with QMan WS-Resources
+must first get resource identifiers sending
+a GetResourcePropertyRequest to WS-DM Adapter
+with "ws-rp:Entry" as target target property.
+
+-------------------------------------------------------------------
+
+Type enter to proceed.
+
+When you're ready type enter to proceed. Now the example runs and all the exchanged
+SOAP messages are printed out on the screen.
+If you want, we shipped (under sample_messages folder) several files containing those messages.
+
+A general note concerning examples...they are all written using java language so what you see is the
+"java" usage of WS-DM client API.
+The most important thing that you should keep in mind is that what is expected (on QMan side) is a SOAP WS-DM
+compliant message so on top of that you don't need to use those java API but feel free to produce those messages
+in your preferred way (by hand or using another programming language).
+
+Another thing : the examples contain a lot of code duplication because each of them is took as independent as possible.
+The general idea is that you open an example source file and in the executeExample(...) method you should have a quick
+idea of how things are working.
+Also, as mentioned before, we provided, under the sample_messages folder, the messages that are part of each example conversation.
+Remember : these messages are important, not the way / language you use to produce them.
+
+2) HOW TO RUN
+
+2.1) Java
+You need JDK 1.5 or higher in order to run and / or compile the examples.
+
+2.2) Dependencies
+You need to set / update the CLASSPATH environment variable with libraries found under $QMAN_HOME/app/qman/WEB-INF/lib.
+After that you should be able to run one the shipped examples:
+
+> java org.apache.qpid.management.example.GetMultipleResourcePropertiesExample <qman_host> <qman_port>
+> java org.apache.qpid.management.example.GetQManResourceMembersExample <qman_host> <qman_port>
+> java org.apache.qpid.management.example.GetResourceMetadataDescriptorExample <qman_host> <qman_port>
+> java org.apache.qpid.management.example.GetResourcePropertyDocumentExample <qman_host> <qman_port>
+> java org.apache.qpid.management.example.GetResourcePropertyExample <qman_host> <qman_port>
+> java org.apache.qpid.management.example.GetWSDLMetadataExample <qman_host> <qman_port>
+> java org.apache.qpid.management.example.SetResourcePropertyExample <qman_host> <qman_port>
+
+Where
+<qman_host> is the host (ip or hostname) where QMan is running;
+<qman_port> is the port number where QMan is running;
+
+2.3) Qpid
+You must have a running C++ broker with management enabled.
+
+2.4) QMan
+You must have QMan WS-DM up, running and connected with the broker above. \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/SetResourcePropertiesRequest.out.ok b/qpid/java/management/client/src/example/SetResourcePropertiesRequest.out.ok
new file mode 100644
index 0000000000..1f346afa4e
--- /dev/null
+++ b/qpid/java/management/client/src/example/SetResourcePropertiesRequest.out.ok
@@ -0,0 +1,2316 @@
+ SetResourcePropertyExample
+-------------------------------------------------------------------
+
+This example shows how to change the state of a WS-Resource.
+That means a SetResourcePropertyRequest is sent to that
+WS-Resource.
+First of all a request is send to WS-DM in order to get all
+registered WS-Resources.
+If the returned list is not empty then two GetMetadataRequests
+(one for WSDL and one for RDM) are sent to the first child.
+The result metadata descriptors are used for determine :
+
+1) WS-Resource property names;
+2) Modifiability (read-only, read-write
+3) Datatype;
+-------------------------------------------------------------------
+
+So a SetResourcePropertyRequest can be sent in order
+to change the WS-Resource state.
+The example is looking for a property that has one of the
+following datatype :
+
+1) String (xsd:string)
+2) Long (xsd:long)
+3) Integer (xsd:integer or xsd:int)
+4) Double (xsd:double)
+5) Float (xsd:float)
+6) Short (xsd:short)
+
+After the update / insert request has been sent, a
+GetResourcePropertiesRequest is made again
+in order to see if the state has changed correctly.
+
+Type enter to proceed...
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:d026718c-2724-d3bf-fd5b-3c6bf4cd5a8c</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <qman:GetMetadata xmlns:qman="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <qman:Dialect>http://docs.oasis-open.org/wsrf/rmd-1</qman:Dialect>
+ </qman:GetMetadata>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:dba8d7ab-83a6-16e1-03cc-48edc672a325</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:d026718c-2724-d3bf-fd5b-3c6bf4cd5a8c</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsx:Metadata xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <wsx:MetadataSection>
+ <wsrmd:MetadataDescriptor
+ interface="qman:QManWsResourcePortType"
+ name="QManWsResourceMetadata"
+ wsdlLocation="http://docs.oasis-open.org/wsrf/rmd-1 QManWsResource.wsdl"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman" xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1">
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:MgmtPubInterval" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Name" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:TerminationTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable"
+ name="qman:MsgTotalEnqueues" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Arguments" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:VhostRef" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:CurrentTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:ExpireTime" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Durable" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:ConsumerCount" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:Type" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ </wsrmd:MetadataDescriptor>
+ </wsx:MetadataSection>
+ </wsx:Metadata>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:11581af1-04af-05cd-7215-103cad6a316c</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <qman:GetMetadata xmlns:qman="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <qman:Dialect>http://schemas.xmlsoap.org/wsdl/</qman:Dialect>
+ </qman:GetMetadata>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:785964d4-9a81-784f-d68a-60de63223094</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:11581af1-04af-05cd-7215-103cad6a316c</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsx:Metadata xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <wsx:MetadataSection>
+ <wsdl:definitions name="QManWsResource"
+ targetNamespace="http://amqp.apache.org/qpid/management/qman"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl-soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1"
+ xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <wsdl:types>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://www.w3.org/2005/08/addressing"
+ xmlns:tns="http://www.w3.org/2005/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="EndpointReference"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:element name="Address" type="tns:AttributedURIType"/>
+ <xs:element minOccurs="0"
+ name="ReferenceParameters" type="tns:ReferenceParametersType"/>
+ <xs:element minOccurs="0" ref="tns:Metadata"/>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:complexType mixed="false"
+ name="ReferenceParametersType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0" namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:element name="Metadata"
+ type="tns:MetadataType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="MetadataType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0" namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:element name="MessageID"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="RelatesTo"
+ type="tns:RelatesToType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="RelatesToType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute
+ default="http://www.w3.org/2005/08/addressing/reply"
+ name="RelationshipType"
+ type="tns:RelationshipTypeOpenEnum" use="optional"/>
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:simpleType
+ name="RelationshipTypeOpenEnum" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:union memberTypes="tns:RelationshipType xs:anyURI"/>
+ </xs:simpleType>
+ <xs:simpleType name="RelationshipType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:restriction base="xs:anyURI">
+ <xs:enumeration value="http://www.w3.org/2005/08/addressing/reply"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="ReplyTo"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="From"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="FaultTo"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="To"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Action"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:attribute name="IsReferenceParameter"
+ type="xs:boolean" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:simpleType name="FaultCodesOpenEnumType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:union memberTypes="tns:FaultCodesType xs:QName"/>
+ </xs:simpleType>
+ <xs:simpleType name="FaultCodesType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:restriction base="xs:QName">
+ <xs:enumeration value="tns:InvalidAddressingHeader"/>
+ <xs:enumeration value="tns:InvalidAddress"/>
+ <xs:enumeration value="tns:InvalidEPR"/>
+ <xs:enumeration value="tns:InvalidCardinality"/>
+ <xs:enumeration value="tns:MissingAddressInEPR"/>
+ <xs:enumeration value="tns:DuplicateMessageID"/>
+ <xs:enumeration value="tns:ActionMismatch"/>
+ <xs:enumeration value="tns:MessageAddressingHeaderRequired"/>
+ <xs:enumeration value="tns:DestinationUnreachable"/>
+ <xs:enumeration value="tns:ActionNotSupported"/>
+ <xs:enumeration value="tns:EndpointUnavailable"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="RetryAfter"
+ type="tns:AttributedUnsignedLongType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedUnsignedLongType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:unsignedLong">
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:element name="ProblemHeaderQName"
+ type="tns:AttributedQNameType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedQNameType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:QName">
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:element name="ProblemHeader"
+ type="tns:AttributedAnyType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedAnyType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any maxOccurs="1" minOccurs="1"
+ namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:element name="ProblemIRI"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="ProblemAction"
+ type="tns:ProblemActionType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="ProblemActionType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:element minOccurs="0" ref="tns:Action"/>
+ <xs:element minOccurs="0"
+ name="SoapAction" type="xs:anyURI"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified"
+ targetNamespace="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:tns="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:import
+ namespace="http://www.w3.org/2005/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="GetMetadata" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" ref="tns:Dialect"/>
+ <xs:element minOccurs="0" ref="tns:Identifier"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="Dialect" type="xs:anyURI" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Identifier"
+ type="xs:anyURI" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Metadata" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="tns:MetadataSection"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="MetadataSection" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType>
+ <xs:choice>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ <xs:element ref="tns:MetadataReference"/>
+ <xs:element ref="tns:Location"/>
+ </xs:choice>
+ <xs:attribute name="Dialect"
+ type="xs:anyURI" use="required"/>
+ <xs:attribute name="Identifier" type="xs:anyURI"/>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="MetadataReference"
+ type="wsa:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Location" type="xs:anyURI" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType name="AnyXmlType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##any" processContents="lax"/>
+ </xs:complexType>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:element name="CurrentTime">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:dateTime">
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="TerminationTime" nillable="true">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:dateTime">
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="ScheduledResourceTerminationRP">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" ref="wsrf-rl:CurrentTime"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" ref="wsrf-rl:TerminationTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="Destroy">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="DestroyResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:complexType name="ResourceNotDestroyedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="ResourceNotDestroyedFault" type="wsrf-rl:ResourceNotDestroyedFaultType"/>
+ <xsd:element name="SetTerminationTime">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element
+ name="RequestedTerminationTime"
+ nillable="true" type="xsd:dateTime"/>
+ <xsd:element
+ name="RequestedLifetimeDuration" type="xsd:duration"/>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="SetTerminationTimeResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ name="NewTerminationTime"
+ nillable="true" type="xsd:dateTime"/>
+ <xsd:element name="CurrentTime" type="xsd:dateTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="UnableToSetTerminationTimeFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnableToSetTerminationTimeFault" type="wsrf-rl:UnableToSetTerminationTimeFaultType"/>
+ <xsd:complexType name="TerminationTimeChangeRejectedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="TerminationTimeChangeRejectedFault" type="wsrf-rl:TerminationTimeChangeRejectedFaultType"/>
+ <xsd:element name="TerminationNotification">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="1"
+ name="TerminationTime"
+ nillable="true" type="xsd:dateTime"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="TerminationReason" type="xsd:anyType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:element name="QueryExpressionDialect" type="xsd:anyURI"/>
+ <xsd:element name="QueryExpressionRPDocument">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrf-rp:QueryExpressionDialect"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:attribute name="ResourceProperties" type="xsd:QName"/>
+ <xsd:complexType name="ResourcePropertyValueChangeNotificationType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="OldValues" nillable="true">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" name="NewValues" nillable="true">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element
+ name="ResourcePropertyValueChangeNotification" type="wsrf-rp:ResourcePropertyValueChangeNotificationType"/>
+ <xsd:complexType mixed="true" name="QueryExpressionType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="0" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="Dialect" type="xsd:anyURI"/>
+ </xsd:complexType>
+ <xsd:element name="QueryExpression" type="wsrf-rp:QueryExpressionType"/>
+ <xsd:element name="GetResourcePropertyDocument">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="GetResourcePropertyDocumentResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="GetResourceProperty" type="xsd:QName"/>
+ <xsd:element name="GetResourcePropertyResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="InvalidResourcePropertyQNameFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="InvalidResourcePropertyQNameFault" type="wsrf-rp:InvalidResourcePropertyQNameFaultType"/>
+ <xsd:element name="GetMultipleResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="1"
+ name="ResourceProperty" type="xsd:QName"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="GetMultipleResourcePropertiesResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="PutResourcePropertyDocument">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="PutResourcePropertyDocumentResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="ResourcePropertyChangeFailureType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="CurrentValue">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="RequestedValue">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:attribute name="Restored" type="xsd:boolean"/>
+ </xsd:complexType>
+ <xsd:complexType name="UnableToPutResourcePropertyDocumentFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnableToPutResourcePropertyDocumentFault" type="wsrf-rp:UnableToPutResourcePropertyDocumentFaultType"/>
+ <xsd:complexType name="InsertType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="1" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Insert" type="wsrf-rp:InsertType"/>
+ <xsd:complexType name="UpdateType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="1" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Update" type="wsrf-rp:UpdateType"/>
+ <xsd:complexType name="DeleteType">
+ <xsd:attribute name="ResourceProperty"
+ type="xsd:QName" use="required"/>
+ </xsd:complexType>
+ <xsd:element name="Delete" type="wsrf-rp:DeleteType"/>
+ <xsd:element name="SetResourceProperties">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded" minOccurs="1">
+ <xsd:element ref="wsrf-rp:Insert"/>
+ <xsd:element ref="wsrf-rp:Update"/>
+ <xsd:element ref="wsrf-rp:Delete"/>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="SetResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:complexType name="InvalidModificationFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidModificationFault" type="wsrf-rp:InvalidModificationFaultType"/>
+ <xsd:complexType name="UnableToModifyResourcePropertyFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnableToModifyResourcePropertyFault" type="wsrf-rp:UnableToModifyResourcePropertyFaultType"/>
+ <xsd:complexType name="SetResourcePropertyRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="SetResourcePropertyRequestFailedFault" type="wsrf-rp:SetResourcePropertyRequestFailedFaultType"/>
+ <xsd:complexType name="InsertResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="InsertResourcePropertiesRequestFailedFault" type="wsrf-rp:InsertResourcePropertiesRequestFailedFaultType"/>
+ <xsd:complexType name="UpdateResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UpdateResourcePropertiesRequestFailedFault" type="wsrf-rp:UpdateResourcePropertiesRequestFailedFaultType"/>
+ <xsd:complexType name="DeleteResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="DeleteResourcePropertiesRequestFailedFault" type="wsrf-rp:DeleteResourcePropertiesRequestFailedFaultType"/>
+ <xsd:element name="InsertResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Insert"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="InsertResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="UpdateResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Update"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="UpdateResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="DeleteResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Delete"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="DeleteResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="QueryResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" ref="wsrf-rp:QueryExpression"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="QueryResourcePropertiesResponse">
+ <xsd:complexType>
+ <xsd:complexContent mixed="true">
+ <xsd:restriction base="xsd:anyType">
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="1" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="UnknownQueryExpressionDialectFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnknownQueryExpressionDialectFault" type="wsrf-rp:UnknownQueryExpressionDialectFaultType"/>
+ <xsd:complexType name="InvalidQueryExpressionFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="InvalidQueryExpressionFault" type="wsrf-rp:InvalidQueryExpressionFaultType"/>
+ <xsd:complexType name="QueryEvaluationErrorFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="QueryEvaluationErrorFault" type="wsrf-rp:QueryEvaluationErrorFaultType"/>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:complexType name="ResourceUnknownFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResourceUnknownFault" type="wsrf-r:ResourceUnknownFaultType"/>
+ <xsd:complexType name="ResourceUnavailableFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResourceUnavailableFault" type="wsrf-r:ResourceUnavailableFaultType"/>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rmd-1"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rp-2"/>
+ <xsd:import namespace="http://www.w3.org/2005/08/addressing"/>
+ <xsd:simpleType name="PairsOfURIType">
+ <xsd:list itemType="xsd:anyURI"/>
+ </xsd:simpleType>
+ <xsd:attribute name="Descriptor" type="xsd:QName"/>
+ <xsd:attribute name="DescriptorLocation" type="xsd:anyURI"/>
+ <xsd:complexType mixed="true" name="DocumentationType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0" namespace="##any" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ <xsd:complexType name="DocumentedType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="DefinitionsType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrmd:MetadataDescriptor"/>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute
+ name="targetNamespace"
+ type="xsd:anyURI" use="required"/>
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="Definitions" type="wsrmd:DefinitionsType">
+ <xsd:key name="MetadataDescriptor">
+ <xsd:annotation>
+ <xsd:documentation>
+ To form a QName, the name of any MetadataDescriptor must be
+ unique within a Definitions element.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:selector xpath="wsrmd:MetadataDescriptor"/>
+ <xsd:field xpath="@name"/>
+ </xsd:key>
+ </xsd:element>
+ <xsd:complexType name="MetadataDescriptorType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrmd:Property"/>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="name"
+ type="xsd:NCName" use="required"/>
+ <xsd:attribute name="interface"
+ type="xsd:QName" use="required"/>
+ <xsd:attribute
+ name="wsdlLocation" type="wsrmd:PairsOfURIType"/>
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="MetadataDescriptor" type="wsrmd:MetadataDescriptorType"/>
+ <xsd:complexType name="PropertyType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element
+ maxOccurs="1"
+ minOccurs="0" ref="wsrmd:ValidValues"/>
+ <xsd:element
+ maxOccurs="1"
+ minOccurs="0" ref="wsrmd:ValidValueRange"/>
+ </xsd:choice>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" ref="wsrmd:StaticValues"/>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="name"
+ type="xsd:QName" use="required"/>
+ <xsd:attribute name="mutability" type="wsrmd:MutabilityType"/>
+ <xsd:attribute
+ name="modifiability" type="wsrmd:ModifiabilityType"/>
+ <xsd:attribute default="false"
+ name="subscribability" type="xsd:boolean"/>
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="Property" type="wsrmd:PropertyType"/>
+ <xsd:simpleType name="MutabilityType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="constant"/>
+ <xsd:enumeration value="appendable"/>
+ <xsd:enumeration value="mutable"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="ModifiabilityType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="read-only"/>
+ <xsd:enumeration value="read-write"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:complexType mixed="true" name="ValidValuesType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="ValidValues" type="wsrmd:ValidValuesType"/>
+ <xsd:complexType mixed="true" name="ValidValueRangeType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="lowerBound" type="xsd:anySimpleType"/>
+ <xsd:attribute name="upperBound" type="xsd:anySimpleType"/>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="ValidValueRange" type="wsrmd:ValidValueRangeType"/>
+ <xsd:complexType mixed="true" name="StaticValuesType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="StaticValues" type="wsrmd:StaticValuesType"/>
+ <xsd:complexType mixed="true" name="InitialValuesType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="InitialValues" type="wsrmd:InitialValuesType"/>
+ <xsd:complexType name="MetadataDescriptorReferenceType">
+ <xsd:complexContent>
+ <xsd:extension base="wsa:EndpointReferenceType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="MetadataDescriptorReference" type="wsrmd:MetadataDescriptorReferenceType"/>
+ <xsd:element name="MetadataResourceRP" type="wsrmd:DefinitionsType"/>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://amqp.apache.org/qpid/management/qman">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rl-2"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rp-2"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:element name="QManWsResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rl:CurrentTime"/>
+ <xsd:element ref="wsrf-rl:TerminationTime"/>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrf-rp:QueryExpressionDialect"/>
+ <xsd:element ref="qman:Name"/>
+ <xsd:element ref="qman:Type"/>
+ <xsd:element ref="qman:Arguments"/>
+ <xsd:element ref="qman:VhostRef"/>
+ <xsd:element ref="qman:Durable"/>
+ <xsd:element ref="qman:MsgTotalEnqueues"/>
+ <xsd:element ref="qman:ConsumerCount"/>
+ <xsd:element ref="qman:ExpireTime"/>
+ <xsd:element ref="qman:MgmtPubInterval"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="QManFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="MethodInvocationFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="EntityInstanceNotFoundFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="MalformedEntityNameFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="NoSuchAttributeFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="result">
+ <xsd:sequence>
+ <xsd:element name="statusCode" type="xsd:long"/>
+ <xsd:element name="statusText" type="xsd:string"/>
+ <xsd:complexType name="outputParameters">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" name="entry">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:name
+ name="key" type="xsd:string"/>
+ <xsd:element
+ name="value" type="xsd:anyType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:complexType>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Name" type="xsd:string"/>
+ <xsd:element name="Type" type="xsd:string"/>
+ <xsd:complexType name="map">
+ <xsd:sequence>
+ <xsd:element maxOccurs="unbounded"
+ minOccurs="0" name="entry">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="key" type="xsd:string"/>
+ <xsd:element
+ name="value" type="xsd:anyType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Arguments" type="qman:map"/>
+ <xsd:complexType name="uuid">
+ <xsd:sequence>
+ <xsd:element name="uuid" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="VhostRef" type="qman:uuid"/>
+ <xsd:element name="Durable" type="xsd:boolean"/>
+ <xsd:element name="MsgTotalEnqueues" type="xsd:long"/>
+ <xsd:element name="ConsumerCount" type="xsd:integer"/>
+ <xsd:element name="ExpireTime" type="xsd:dateTime"/>
+ <xsd:element name="MgmtPubInterval" type="xsd:short"/>
+ <xsd:element
+ name="echoWithSimpleTypesRequest" type="qman:echoWithSimpleTypesRequest"/>
+ <xsd:element
+ name="echoWithSimpleTypesResponse" type="qman:echoWithSimpleTypesResponse"/>
+ <xsd:complexType name="echoWithSimpleTypesRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="xsd:long"/>
+ <xsd:element name="p2" type="xsd:boolean"/>
+ <xsd:element name="p3" type="xsd:double"/>
+ <xsd:element name="p4" type="xsd:float"/>
+ <xsd:element name="p5" type="xsd:integer"/>
+ <xsd:element name="p6" type="xsd:short"/>
+ <xsd:element name="p7" type="xsd:string"/>
+ <xsd:element name="p8" type="xsd:anyURI"/>
+ <xsd:element name="p9" type="xsd:dateTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithSimpleTypesResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithArraysRequest" type="qman:echoWithArraysRequest"/>
+ <xsd:element name="echoWithArraysResponse" type="qman:echoWithArraysResponse"/>
+ <xsd:complexType name="arrayOfLong">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:long"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfBoolean">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:boolean"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfDouble">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:double"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfFloat">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:float"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfInteger">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:integer"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfShort">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:short"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfString">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfURI">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:anyURI"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfDate">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:dateTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithArraysRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:arrayOfLong"/>
+ <xsd:element name="p2" type="qman:arrayOfBoolean"/>
+ <xsd:element name="p3" type="qman:arrayOfDouble"/>
+ <xsd:element name="p4" type="qman:arrayOfFloat"/>
+ <xsd:element name="p5" type="qman:arrayOfInteger"/>
+ <xsd:element name="p6" type="qman:arrayOfShort"/>
+ <xsd:element name="p7" type="qman:arrayOfString"/>
+ <xsd:element name="p8" type="qman:arrayOfURI"/>
+ <xsd:element name="p9" type="qman:arrayOfDate"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithArraysResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element
+ name="echoWithSimpleTypeArraysRequest" type="qman:echoWithSimpleTypeArraysRequest"/>
+ <xsd:element
+ name="echoWithSimpleTypeArraysResponse" type="qman:echoWithSimpleTypeArraysResponse"/>
+ <xsd:complexType name="arrayOfLong">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:long"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfBoolean">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:boolean"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfDouble">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:double"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfFloat">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:float"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfInt">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:integer"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfShort">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:short"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithSimpleTypeArraysRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:arrayOfLong"/>
+ <xsd:element name="p2" type="qman:arrayOfBoolean"/>
+ <xsd:element name="p3" type="qman:arrayOfDouble"/>
+ <xsd:element name="p4" type="qman:arrayOfFloat"/>
+ <xsd:element name="p5" type="qman:arrayOfInt"/>
+ <xsd:element name="p6" type="qman:arrayOfShort"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithSimpleTypeArraysResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithByteArrayRequest" type="qman:echoWithByteArrayRequest"/>
+ <xsd:element
+ name="echoWithByteArrayResponse" type="qman:echoWithByteArrayResponse"/>
+ <xsd:complexType name="arrayOfByte">
+ <xsd:sequence>
+ <xsd:element name="entry" type=""/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithByteArrayRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:arrayOfByte"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithByteArrayResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element
+ name="voidWithoutArgumentsRequest" type="qman:voidWithoutArgumentsRequest"/>
+ <xsd:element
+ name="voidWithoutArgumentsResponse" type="qman:voidWithoutArgumentsResponse"/>
+ <xsd:complexType name="voidWithoutArgumentsRequest">
+ <xsd:sequence/>
+ </xsd:complexType>
+ <xsd:complexType name="voidWithoutArgumentsResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="throwsExceptionRequest" type="qman:throwsExceptionRequest"/>
+ <xsd:element name="throwsExceptionResponse" type="qman:throwsExceptionResponse"/>
+ <xsd:complexType name="throwsExceptionRequest">
+ <xsd:sequence/>
+ </xsd:complexType>
+ <xsd:complexType name="throwsExceptionResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithUUIDRequest" type="qman:echoWithUUIDRequest"/>
+ <xsd:element name="echoWithUUIDResponse" type="qman:echoWithUUIDResponse"/>
+ <xsd:complexType name="echoWithUUIDRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:uuid"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithUUIDResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithMapRequest" type="qman:echoWithMapRequest"/>
+ <xsd:element name="echoWithMapResponse" type="qman:echoWithMapResponse"/>
+ <xsd:complexType name="echoWithMapRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:map"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithMapResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <xsd:import namespace="http://www.w3.org/2005/08/addressing"/>
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace">
+ <xsd:annotation>
+ <xsd:documentation>
+ Get access to the xml: attribute groups for xml:lang as declared on 'schema'
+ and 'documentation' below
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:import>
+ <xsd:element name="BaseFault" type="wsrf-bf:BaseFaultType"/>
+ <xsd:complexType name="BaseFaultType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" name="Timestamp" type="xsd:dateTime"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="Originator" type="wsa:EndpointReferenceType"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="ErrorCode">
+ <xsd:complexType>
+ <xsd:complexContent mixed="true">
+ <xsd:extension base="xsd:anyType">
+ <xsd:attribute
+ name="dialect"
+ type="xsd:anyURI" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="unbounded"
+ minOccurs="0" name="Description">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute
+ ref="xml:lang" use="optional"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="FaultCause">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1"
+ minOccurs="1"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ </xsd:schema>
+ <xs:schema
+ targetNamespace="http://www.w3.org/XML/1998/namespace"
+ xml:lang="en" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:attribute name="lang" type="xs:language"/>
+ <xs:attribute default="preserve" name="space">
+ <xs:simpleType>
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="base" type="xs:anyURI"/>
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ </xs:attributeGroup>
+ </xs:schema>
+ </wsdl:types>
+ <wsdl:message name="GetMetadataMsg">
+ <wsdl:part element="wsx:GetMetadata" name="GetMetadataMsg"/>
+ </wsdl:message>
+ <wsdl:message name="GetMetadataResponseMsg">
+ <wsdl:part element="wsx:Metadata" name="GetMetadataResponseMsg"/>
+ </wsdl:message>
+ <wsdl:message name="DestroyRequest">
+ <wsdl:part element="wsrf-rl:Destroy" name="DestroyRequest"/>
+ </wsdl:message>
+ <wsdl:message name="DestroyResponse">
+ <wsdl:part element="wsrf-rl:DestroyResponse" name="DestroyResponse"/>
+ </wsdl:message>
+ <wsdl:message name="ResourceNotDestroyedFault">
+ <wsdl:part
+ element="wsrf-rl:ResourceNotDestroyedFault" name="ResourceNotDestroyedFault"/>
+ </wsdl:message>
+ <wsdl:message name="ResourceUnknownFault">
+ <wsdl:part element="wsrf-r:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ </wsdl:message>
+ <wsdl:message name="ResourceUnavailableFault">
+ <wsdl:part
+ element="wsrf-r:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ </wsdl:message>
+ <wsdl:message name="SetTerminationTimeRequest">
+ <wsdl:part element="wsrf-rl:SetTerminationTime" name="SetTerminationTimeRequest"/>
+ </wsdl:message>
+ <wsdl:message name="SetTerminationTimeResponse">
+ <wsdl:part
+ element="wsrf-rl:SetTerminationTimeResponse" name="SetTerminationTimeResponse"/>
+ </wsdl:message>
+ <wsdl:message name="UnableToSetTerminationTimeFault">
+ <wsdl:part
+ element="wsrf-rl:UnableToSetTerminationTimeFault" name="UnableToSetTerminationTimeFault"/>
+ </wsdl:message>
+ <wsdl:message name="TerminationTimeChangeRejectedFault">
+ <wsdl:part
+ element="wsrf-rl:TerminationTimeChangeRejectedFault" name="TerminationTimeChangeRejectedFault"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentRequest">
+ <wsdl:part
+ element="wsrf-rp:GetResourcePropertyDocument" name="GetResourcePropertyDocumentRequest"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentResponse">
+ <wsdl:part
+ element="wsrf-rp:GetResourcePropertyDocumentResponse" name="GetResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyRequest">
+ <wsdl:part element="wsrf-rp:GetResourceProperty" name="GetResourcePropertyRequest"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyResponse">
+ <wsdl:part
+ element="wsrf-rp:GetResourcePropertyResponse" name="GetResourcePropertyResponse"/>
+ </wsdl:message>
+ <wsdl:message name="InvalidResourcePropertyQNameFault">
+ <wsdl:part
+ element="wsrf-rp:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesRequest">
+ <wsdl:part
+ element="wsrf-rp:GetMultipleResourceProperties" name="GetMultipleResourcePropertiesRequest"/>
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesResponse">
+ <wsdl:part
+ element="wsrf-rp:GetMultipleResourcePropertiesResponse" name="GetMultipleResourcePropertiesResponse"/>
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesRequest">
+ <wsdl:part
+ element="wsrf-rp:QueryResourceProperties" name="QueryResourcePropertiesRequest"/>
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesResponse">
+ <wsdl:part
+ element="wsrf-rp:QueryResourcePropertiesResponse" name="QueryResourcePropertiesResponse"/>
+ </wsdl:message>
+ <wsdl:message name="UnknownQueryExpressionDialectFault">
+ <wsdl:part
+ element="wsrf-rp:UnknownQueryExpressionDialectFault" name="UnknownQueryExpressionDialectFault"/>
+ </wsdl:message>
+ <wsdl:message name="InvalidQueryExpressionFault">
+ <wsdl:part
+ element="wsrf-rp:InvalidQueryExpressionFault" name="InvalidQueryExpressionFault"/>
+ </wsdl:message>
+ <wsdl:message name="QueryEvaluationErrorFault">
+ <wsdl:part
+ element="wsrf-rp:QueryEvaluationErrorFault" name="QueryEvaluationErrorFault"/>
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertiesRequest">
+ <wsdl:part
+ element="wsrf-rp:SetResourceProperties" name="SetResourcePropertiesRequest"/>
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertiesResponse">
+ <wsdl:part
+ element="wsrf-rp:SetResourcePropertiesResponse" name="SetResourcePropertiesResponse"/>
+ </wsdl:message>
+ <wsdl:message name="InvalidModificationFault">
+ <wsdl:part
+ element="wsrf-rp:InvalidModificationFault" name="InvalidModificationFault"/>
+ </wsdl:message>
+ <wsdl:message name="UnableToModifyResourcePropertyFault">
+ <wsdl:part
+ element="wsrf-rp:UnableToModifyResourcePropertyFault" name="UnableToModifyResourcePropertyFault"/>
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertyRequestFailedFault">
+ <wsdl:part
+ element="wsrf-rp:SetResourcePropertyRequestFailedFault" name="SetResourcePropertyRequestFailedFault"/>
+ </wsdl:message>
+ <wsdl:portType name="QManWsResourcePortType"
+ wsrf-rp:ResourceProperties="qman:QManWsResourceProperties"
+ wsrmd:Descriptor="QManWsResourceMetadata" wsrmd:DescriptorLocation="QManWsResource.rmd">
+ <wsdl:operation name="GetMetadata">
+ <wsdl:input message="qman:GetMetadataMsg"
+ name="GetMetadataMsg" wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata"/>
+ <wsdl:output
+ message="qman:GetMetadataResponseMsg"
+ name="GetMetadataResponseMsg" wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="Destroy">
+ <wsdl:input message="qman:DestroyRequest"
+ name="DestroyRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination/DestroyRequest"/>
+ <wsdl:output message="qman:DestroyResponse"
+ name="DestroyResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination/DestroyResponse"/>
+ <wsdl:fault
+ message="qman:ResourceNotDestroyedFault" name="ResourceNotDestroyedFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="SetTerminationTime">
+ <wsdl:input
+ message="qman:SetTerminationTimeRequest"
+ name="SetTerminationTimeRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination/SetTerminationTimeRequest"/>
+ <wsdl:output
+ message="qman:SetTerminationTimeResponse"
+ name="SetTerminationTimeResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination/SetTerminationTimeResponse"/>
+ <wsdl:fault
+ message="qman:UnableToSetTerminationTimeFault" name="UnableToSetTerminationTimeFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:TerminationTimeChangeRejectedFault" name="TerminationTimeChangeRejectedFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:input
+ message="qman:GetResourcePropertyDocumentRequest"
+ name="GetResourcePropertyDocumentRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"/>
+ <wsdl:output
+ message="qman:GetResourcePropertyDocumentResponse"
+ name="GetResourcePropertyDocumentResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:input
+ message="qman:GetResourcePropertyRequest"
+ name="GetResourcePropertyRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"/>
+ <wsdl:output
+ message="qman:GetResourcePropertyResponse"
+ name="GetResourcePropertyResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:input
+ message="qman:GetMultipleResourcePropertiesRequest"
+ name="GetMultipleResourcePropertiesRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"/>
+ <wsdl:output
+ message="qman:GetMultipleResourcePropertiesResponse"
+ name="GetMultipleResourcePropertiesResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl:input
+ message="qman:QueryResourcePropertiesRequest"
+ name="QueryResourcePropertiesRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesRequest"/>
+ <wsdl:output
+ message="qman:QueryResourcePropertiesResponse"
+ name="QueryResourcePropertiesResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:UnknownQueryExpressionDialectFault" name="UnknownQueryExpressionDialectFault"/>
+ <wsdl:fault
+ message="qman:InvalidQueryExpressionFault" name="InvalidQueryExpressionFault"/>
+ <wsdl:fault
+ message="qman:QueryEvaluationErrorFault" name="QueryEvaluationErrorFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="SetResourceProperties">
+ <wsdl:input
+ message="qman:SetResourcePropertiesRequest"
+ name="SetResourcePropertiesRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesRequest"/>
+ <wsdl:output
+ message="qman:SetResourcePropertiesResponse"
+ name="SetResourcePropertiesResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:InvalidModificationFault" name="InvalidModificationFault"/>
+ <wsdl:fault
+ message="qman:UnableToModifyResourcePropertyFault" name="UnableToModifyResourcePropertyFault"/>
+ <wsdl:fault
+ message="qman:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ <wsdl:fault
+ message="qman:SetResourcePropertyRequestFailedFault" name="SetResourcePropertyRequestFailedFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypes">
+ <wsdl:input
+ message="qman:echoWithSimpleTypesRequestMessage"
+ name="echoWithSimpleTypesRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypes"/>
+ <wsdl:output
+ message="qman:echoWithSimpleTypesResponseMessage"
+ name="echoWithSimpleTypesResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypesResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithArrays">
+ <wsdl:input
+ message="qman:echoWithArraysRequestMessage"
+ name="echoWithArraysRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithArrays"/>
+ <wsdl:output
+ message="qman:echoWithArraysResponseMessage"
+ name="echoWithArraysResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithArraysResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypeArrays">
+ <wsdl:input
+ message="qman:echoWithSimpleTypeArraysRequestMessage"
+ name="echoWithSimpleTypeArraysRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypeArrays"/>
+ <wsdl:output
+ message="qman:echoWithSimpleTypeArraysResponseMessage"
+ name="echoWithSimpleTypeArraysResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypeArraysResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithByteArray">
+ <wsdl:input
+ message="qman:echoWithByteArrayRequestMessage"
+ name="echoWithByteArrayRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithByteArray"/>
+ <wsdl:output
+ message="qman:echoWithByteArrayResponseMessage"
+ name="echoWithByteArrayResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithByteArrayResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="voidWithoutArguments">
+ <wsdl:input
+ message="qman:voidWithoutArgumentsRequestMessage"
+ name="voidWithoutArgumentsRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/voidWithoutArguments"/>
+ <wsdl:output
+ message="qman:voidWithoutArgumentsResponseMessage"
+ name="voidWithoutArgumentsResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/voidWithoutArgumentsResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="throwsException">
+ <wsdl:input
+ message="qman:throwsExceptionRequestMessage"
+ name="throwsExceptionRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/throwsException"/>
+ <wsdl:output
+ message="qman:throwsExceptionResponseMessage"
+ name="throwsExceptionResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/throwsExceptionResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithUUID">
+ <wsdl:input
+ message="qman:echoWithUUIDRequestMessage"
+ name="echoWithUUIDRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithUUID"/>
+ <wsdl:output
+ message="qman:echoWithUUIDResponseMessage"
+ name="echoWithUUIDResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithUUIDResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithMap">
+ <wsdl:input
+ message="qman:echoWithMapRequestMessage"
+ name="echoWithMapRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithMap"/>
+ <wsdl:output
+ message="qman:echoWithMapResponseMessage"
+ name="echoWithMapResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithMapResponse"/>
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="QManWsResourceBinding" type="qman:QManWsResourcePortType">
+ <wsdl-soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="GetMetadata"/>
+ <wsdl:input>
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="Destroy">
+ <wsdl-soap:operation soapAction="Destroy"/>
+ <wsdl:input name="DestroyRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="DestroyResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceNotDestroyedFault">
+ <wsdl-soap:fault
+ name="ResourceNotDestroyedFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="SetTerminationTime">
+ <wsdl-soap:operation soapAction="SetTerminationTime"/>
+ <wsdl:input name="SetTerminationTimeRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="SetTerminationTimeResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="UnableToSetTerminationTimeFault">
+ <wsdl-soap:fault
+ name="UnableToSetTerminationTimeFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="TerminationTimeChangeRejectedFault">
+ <wsdl-soap:fault
+ name="TerminationTimeChangeRejectedFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl-soap:operation soapAction="GetResourcePropertyDocument"/>
+ <wsdl:input name="GetResourcePropertyDocumentRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetResourcePropertyDocumentResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl-soap:operation soapAction="GetResourceProperty"/>
+ <wsdl:input name="GetResourcePropertyRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetResourcePropertyResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ name="InvalidResourcePropertyQNameFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl-soap:operation soapAction="GetMultipleResourceProperties"/>
+ <wsdl:input name="GetMultipleResourcePropertiesRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetMultipleResourcePropertiesResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ name="InvalidResourcePropertyQNameFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl-soap:operation soapAction="QueryResourceProperties"/>
+ <wsdl:input name="QueryResourcePropertiesRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="QueryResourcePropertiesResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault">
+ <wsdl-soap:fault
+ name="UnknownQueryExpressionDialectFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidQueryExpressionFault">
+ <wsdl-soap:fault
+ name="InvalidQueryExpressionFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="QueryEvaluationErrorFault">
+ <wsdl-soap:fault
+ name="QueryEvaluationErrorFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="SetResourceProperties">
+ <wsdl-soap:operation soapAction="http://oasis.org/SetResourceProperties"/>
+ <wsdl:input name="SetResourcePropertiesRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="SetResourcePropertiesResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidModificationFault">
+ <wsdl-soap:fault
+ name="InvalidModificationFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnableToModifyResourcePropertyFault">
+ <wsdl-soap:fault
+ name="UnableToModifyResourcePropertyFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ name="InvalidResourcePropertyQNameFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="SetResourcePropertyRequestFailedFault">
+ <wsdl-soap:fault
+ name="SetResourcePropertyRequestFailedFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="http://ws.apache.org/muse/test/wsrf/GetMetadata"/>
+ <wsdl:input name="GetMetadataMsg">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetMetadataResponseMsg">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypes">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypes"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithArrays">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithArrays"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypeArrays">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypeArrays"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithByteArray">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithByteArray"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="voidWithoutArguments">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/voidWithoutArguments"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="throwsException">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/throwsException"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithUUID">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithUUID"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithMap">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithMap"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="QManWsResourceService">
+ <wsdl:port binding="qman:QManWsResourceBinding" name="QManWsResourcePort">
+ <wsdl-soap:address location="http://romagazzarini:8080/qman/services/QManWsResource"/>
+ </wsdl:port>
+ </wsdl:service>
+ <message name="echoWithSimpleTypesRequestMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypesRequest" name="echoWithSimpleTypesRequest"/>
+ </message>
+ <wsdl:message name="echoWithSimpleTypesResponseMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypesResponse" name="echoWithSimpleTypesResponse"/>
+ </wsdl:message>
+ <message name="echoWithArraysRequestMessage">
+ <wsdl:part element="qman:echoWithArraysRequest" name="echoWithArraysRequest"/>
+ </message>
+ <wsdl:message name="echoWithArraysResponseMessage">
+ <wsdl:part element="qman:echoWithArraysResponse" name="echoWithArraysResponse"/>
+ </wsdl:message>
+ <message name="echoWithSimpleTypeArraysRequestMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypeArraysRequest" name="echoWithSimpleTypeArraysRequest"/>
+ </message>
+ <wsdl:message name="echoWithSimpleTypeArraysResponseMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypeArraysResponse" name="echoWithSimpleTypeArraysResponse"/>
+ </wsdl:message>
+ <message name="echoWithByteArrayRequestMessage">
+ <wsdl:part
+ element="qman:echoWithByteArrayRequest" name="echoWithByteArrayRequest"/>
+ </message>
+ <wsdl:message name="echoWithByteArrayResponseMessage">
+ <wsdl:part
+ element="qman:echoWithByteArrayResponse" name="echoWithByteArrayResponse"/>
+ </wsdl:message>
+ <message name="voidWithoutArgumentsRequestMessage">
+ <wsdl:part
+ element="qman:voidWithoutArgumentsRequest" name="voidWithoutArgumentsRequest"/>
+ </message>
+ <wsdl:message name="voidWithoutArgumentsResponseMessage">
+ <wsdl:part
+ element="qman:voidWithoutArgumentsResponse" name="voidWithoutArgumentsResponse"/>
+ </wsdl:message>
+ <message name="throwsExceptionRequestMessage">
+ <wsdl:part element="qman:throwsExceptionRequest" name="throwsExceptionRequest"/>
+ </message>
+ <wsdl:message name="throwsExceptionResponseMessage">
+ <wsdl:part
+ element="qman:throwsExceptionResponse" name="throwsExceptionResponse"/>
+ </wsdl:message>
+ <message name="echoWithUUIDRequestMessage">
+ <wsdl:part element="qman:echoWithUUIDRequest" name="echoWithUUIDRequest"/>
+ </message>
+ <wsdl:message name="echoWithUUIDResponseMessage">
+ <wsdl:part element="qman:echoWithUUIDResponse" name="echoWithUUIDResponse"/>
+ </wsdl:message>
+ <message name="echoWithMapRequestMessage">
+ <wsdl:part element="qman:echoWithMapRequest" name="echoWithMapRequest"/>
+ </message>
+ <wsdl:message name="echoWithMapResponseMessage">
+ <wsdl:part element="qman:echoWithMapResponse" name="echoWithMapResponse"/>
+ </wsdl:message>
+ </wsdl:definitions>
+ </wsx:MetadataSection>
+ </wsx:Metadata>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:103f564f-7008-8456-042f-095a092444f9</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:MgmtPubInterval</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:b78625a8-af2f-b542-8001-d7e81d3de1c9</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:103f564f-7008-8456-042f-095a092444f9</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:MgmtPubInterval xmlns:qman="http://amqp.apache.org/qpid/management/qman">32767</qman:MgmtPubInterval>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0b80a9ca-9e02-1d6b-c0e0-8ceb8560ee6e</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:SetResourceProperties xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-rp:Update>
+ <qman:MgmtPubInterval xmlns:qman="http://amqp.apache.org/qpid/management/qman">12</qman:MgmtPubInterval>
+ </wsrf-rp:Update>
+ </wsrf-rp:SetResourceProperties>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:ae67ff51-e1c1-f2c3-5243-d54905f3907b</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0b80a9ca-9e02-1d6b-c0e0-8ceb8560ee6e</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:SetResourcePropertiesResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0dca61e4-072f-3091-0f38-9a967f14666a</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:MgmtPubInterval</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:84399474-c5b1-8738-f410-fd86face1599</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0dca61e4-072f-3091-0f38-9a967f14666a</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:MgmtPubInterval xmlns:qman="http://amqp.apache.org/qpid/management/qman">12</qman:MgmtPubInterval>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+----------------------------------------------------------------------------------
+Resource has been correctly updated.
+----------------------------------------------------------------------------------
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:8be37e48-b3a5-0e4a-aea3-eda3aad58418</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Type</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:b92c8851-d071-204f-6506-3706694cf32e</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:8be37e48-b3a5-0e4a-aea3-eda3aad58418</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:7917abf6-5c85-7e25-4515-b7f60cd32c39</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:SetResourceProperties xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-rp:Insert>
+ <qman:Type xmlns:qman="http://amqp.apache.org/qpid/management/qman">This is a string.</qman:Type>
+ </wsrf-rp:Insert>
+ </wsrf-rp:SetResourceProperties>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0b895a1f-39e5-8739-d9d7-390c5f2eb445</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:7917abf6-5c85-7e25-4515-b7f60cd32c39</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:SetResourcePropertiesResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:930f39a4-0114-03bd-9921-105579fb4213</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Type</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:3d3f04ab-3171-da69-08b5-2e74927ee981</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:930f39a4-0114-03bd-9921-105579fb4213</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:Type xmlns:qman="http://amqp.apache.org/qpid/management/qman">This is a string.</qman:Type>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+----------------------------------------------------------------------------------
+Resource has been correctly updated.
+----------------------------------------------------------------------------------
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/AbstractQManExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/AbstractQManExample.java
new file mode 100644
index 0000000000..ffa96635a8
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/AbstractQManExample.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.management.example;
+
+import java.io.IOException;
+import java.net.URI;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+
+/**
+ * Common interface for all QMan related examples.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class AbstractQManExample
+{
+ final static String LINE_SEPARATOR = System.getProperty("line.separator","\n");
+ protected final static String PREFIX = "qman";
+
+ /**
+ * Prints out the expected command line of this sample and after that exits.
+ */
+ static void printUsageAndExit(String reason)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append("WARNING! Unable to run this sample : ")
+ .append(reason)
+ .append(LINE_SEPARATOR)
+ .append("-------------------------------------------------------------")
+ .append(LINE_SEPARATOR)
+ .append("Expected command line args for this sample are :")
+ .append(LINE_SEPARATOR)
+ .append(LINE_SEPARATOR)
+ .append("1) host : ip or host name where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("2) port : port number where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("------------------------------------------------------------");
+ System.out.println(builder);
+ System.exit(1);
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ abstract void printOutExampleDescription();
+
+ /**
+ * Executes this example.
+ * Note that this is just a template method used to avoid code duplication
+ * (printOutExampleDescription() line) so in order to see how the example
+ * works you should have a look at the concrete implementation of
+ * executeExample(String host, int port).
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ */
+ void execute(String [] arguments)
+ {
+ if (arguments.length != 2){
+ printUsageAndExit("invalid command line was given.");
+ }
+
+ try
+ {
+ // 1) Parses command line arguments...
+ String host = arguments[0];
+ int port = Integer.parseInt(arguments[1]);
+
+ printOutExampleDescription();
+
+ waitForUserInput("Type enter to proceed...");
+
+ executeExample(host, port);
+
+ } catch(NumberFormatException exception)
+ {
+ printUsageAndExit("port number must be a number.");
+ } catch(Exception exception)
+ {
+ System.out.println("-----------------------EXAMPLE FAILURE-----------");
+ System.out.println("Not well-defined exception was detected while");
+ System.out.println("running the example.");
+ exception.printStackTrace(System.out);
+ System.out.println("--------------------------------------------------------");
+ }
+ }
+
+ protected void waitForUserInput(String message) throws IOException {
+ System.out.println(message);
+ System.in.read();
+ }
+
+ /**
+ * Each concrete implementor must define here how the example works.
+ * So, on top of that, user who wants to see how to use a specific feature
+ * should have a look at the concrete implementation of this method..
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception{};
+
+ /**
+ * Returns the endpoint reference of the adapter service.
+ *
+ * @param host ip or host name where the service is running.
+ * @param port the port number of the server where the service is running.
+ * @return the endpoint reference of the adapter service.
+ */
+ EndpointReference getAdapterEndpointReference(String host, int port)
+ {
+ URI address = URI.create(
+ "http://"+
+ host+
+ ":"+
+ port+
+ "/qman/services/adapter");
+ return new EndpointReference(address);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConnectWithBrokerExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConnectWithBrokerExample.java
new file mode 100644
index 0000000000..153f0f66d5
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConnectWithBrokerExample.java
@@ -0,0 +1,240 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.example;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+
+/**
+ * This example shows how to connect QMan with a broker using the adapter interface.
+ * As you can see the interface is very simple and requests you the following parameters :
+ *
+ * <ul>
+ * <li>hostname : the host (hostname or ip) where the broker is running;</li>
+ * <li>port : the port number of the running broker;</li>
+ * <li>virtual host : the name of the virtual host;</li>
+ * <li>username : the username that will be used for estabilshing connection.</li>
+ * <li>password : the password that will be used for estabilshing connection.</li>
+ * <li>initial pool capacity : the initial size of broker connection pool. </li>
+ * <li>maximum pool capacity : the max allowed size of broker connection pool.</li>
+ * <li>maximum wait timeout : the max wait timeout for retrieving connections.</li>
+ * </ul>
+ *
+ * @author Andrea Gazzarini
+ */
+public class ConnectWithBrokerExample extends AbstractQManExample
+{
+
+ /**
+ * Executes the connect example.
+ * Although not specified explicitly, the input array MUST contains in the following order :
+ *
+ * <ul>
+ * <li>host : the hostname where QMan is running;</li>
+ * <li>port : the port number where QMan is running;</li>
+ * <li>qpid host : the host name where QPid is running;</li>
+ * <li>qpid port : the port number where Qpid is running;</li>
+ * <li>virtual host : the virtual host name;</li>
+ * <li>username : the username that will be used for estabilshing connection.</li>
+ * <li>password : the password that will be used for estabilshing connection.</li>
+ * <li>initial pool capacity : the initial size of broker connection pool. </li>
+ * <li>maximum pool capacity : the max allowed size of broker connection pool.</li>
+ * <li>maximum wait timeout : the max wait timeout for retrieving connections.</li>
+ * </ul>
+ *
+ * Note that this example differs from the others (and therefore is overriding the execute() method) because
+ * in this case we are not using the "standard" WSRF interface but instead an additional custom
+ * "operation" on a WS-Resource.
+ *
+ * @param arguments the commadn line arguments.
+ */
+ void execute(String [] arguments)
+ {
+ if (arguments.length != 10){
+ printUsageAndExit("invalid command line was given.");
+ }
+
+ try
+ {
+ // 1) Parses command line arguments...
+ String host = arguments[0];
+ int port = Integer.parseInt(arguments[1]);
+ String qpidHost = arguments[2];
+ int qpidPort = Integer.parseInt(arguments[3]);
+ String virtualHost = arguments[4];
+ String username = arguments[5];
+ String password = arguments[6];
+ int initPoolCapacity = Integer.parseInt(arguments[7]);
+ int maxPoolCapacity = Integer.parseInt(arguments[8]);
+ long maxWaitTimeout = Long.parseLong(arguments[9]);
+
+ printOutExampleDescription();
+
+ waitForUserInput("Type enter to proceed...");
+
+ executeExample(
+ host,
+ port,
+ qpidHost,
+ qpidPort,
+ virtualHost,
+ username,
+ password,
+ initPoolCapacity,
+ maxPoolCapacity,
+ maxWaitTimeout);
+
+ } catch(NumberFormatException exception)
+ {
+ printUsageAndExit("Unable to run the example. Please ensure that all numeric values are correctly supplied.");
+ } catch(Exception exception)
+ {
+ System.out.println("-----------------------EXAMPLE FAILURE-----------");
+ System.out.println("Not well-defined exception was detected while");
+ System.out.println("running the example.");
+ exception.printStackTrace(System.out);
+ System.out.println("--------------------------------------------------------");
+ }
+ }
+
+ /**
+ * Connects QMan with a broker.
+ *
+ *@param host the hostname where QMan is running;
+ *@param port the port number where QMan is running;
+ *@param qpidHost the host name where QPid is running;
+ *@param qpidPort the port number where Qpid is running;
+ *@param virtualHost the virtual host name;
+ *@param username the username that will be used for estabilshing connection.
+ *@param password the password that will be used for estabilshing connection.
+ *@param initPoolCapacity the initial size of broker connection pool.
+ *@param maxPoolCapacity the max allowed size of broker connection pool.
+ *@param maxWaitTimeout the max wait timeout for retrieving connections.
+ *
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port, String qpidHost, int qpidPort, String virtualHost, String username, String password, int initPoolCapacity, int maxPoolCapacity, long maxWaitTimeout) throws Exception
+ {
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference adapterEndpointReference = getAdapterEndpointReference(host, port);
+ WsResourceClient adapterClient = new WsResourceClient(adapterEndpointReference);
+ adapterClient.setTrace(true);
+
+ // 2) Creates the Adapter service client...
+ adapterClient.invoke(
+ getProxyHandler(),
+ new Object[]{
+ qpidHost,
+ qpidPort,
+ username,
+ password,
+ virtualHost,
+ initPoolCapacity,
+ maxPoolCapacity,
+ maxWaitTimeout});
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("This example shows how to connect QMan with a broker using");
+ System.out.println("the adapter interface.");
+ System.out.println();
+ }
+
+ /**
+ * A proxy handler is a module needed in order to make a capability
+ * service invocation.
+ * It contains logic to serialize and deserialize request, response, input and
+ * output parameters during a web service invocation.
+ *
+ * @return a proxy handler.
+ */
+ private ProxyHandler getProxyHandler()
+ {
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction("http://amqp.apache.org/qpid/management/qman/Connect");
+ handler.setRequestName(new QName("http://amqp.apache.org/qpid/management/qman", "Connect", PREFIX));
+ handler.setRequestParameterNames(new QName[]{
+ new QName("http://amqp.apache.org/qpid/management/qman", "host", PREFIX),
+ new QName("http://amqp.apache.org/qpid/management/qman", "port", PREFIX),
+ new QName("http://amqp.apache.org/qpid/management/qman", "username", PREFIX),
+ new QName("http://amqp.apache.org/qpid/management/qman", "password", PREFIX),
+ new QName("http://amqp.apache.org/qpid/management/qman", "virtualHost", PREFIX),
+ new QName("http://amqp.apache.org/qpid/management/qman", "initialPoolCapacity", PREFIX),
+ new QName("http://amqp.apache.org/qpid/management/qman", "maxPoolCapacity", PREFIX),
+ new QName("http://amqp.apache.org/qpid/management/qman", "maxWaitTimeout", PREFIX)});
+ handler.setResponseName(new QName("http://amqp.apache.org/qpid/management/qman", "ConnectResponse", PREFIX));
+ handler.setReturnType(null);
+ return handler;
+ }
+
+ public static void main(String[] arguments)
+ {
+ new ConnectWithBrokerExample().execute(arguments);
+ }
+
+ static void printUsageAndExit(String reason)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append("WARNING! Unable to run this sample : ")
+ .append(reason)
+ .append(LINE_SEPARATOR)
+ .append("-------------------------------------------------------------")
+ .append(LINE_SEPARATOR)
+ .append("Expected command line args for this sample are :")
+ .append(LINE_SEPARATOR)
+ .append(LINE_SEPARATOR)
+ .append("1) host : ip or host name where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("2) port : port number where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("3) qpid host : port number where Qpid is running.")
+ .append(LINE_SEPARATOR)
+ .append("4) qpid port : port number where Qpid is running.")
+ .append(LINE_SEPARATOR)
+ .append("5) virtual host : virtual host name.")
+ .append(LINE_SEPARATOR)
+ .append("6) username : port number where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("7) password : port number where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("8) initial pool capacity : port number where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("9) max pool capacity : port number where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("10) max wait timeout : port number where QMan is running.")
+ .append(LINE_SEPARATOR)
+
+ .append("------------------------------------------------------------");
+ System.out.println(builder);
+ System.exit(1);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java
new file mode 100644
index 0000000000..42587d78ff
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java
@@ -0,0 +1,293 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.example;
+
+import java.net.URI;
+import java.util.Date;
+
+import org.apache.muse.util.xml.XPathUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.notification.impl.FilterCollection;
+import org.apache.muse.ws.notification.impl.MessagePatternFilter;
+import org.apache.muse.ws.notification.impl.ProducerPropertiesFilter;
+import org.apache.muse.ws.notification.impl.TopicFilter;
+import org.apache.muse.ws.notification.remote.NotificationProducerClient;
+import org.apache.qpid.management.Names;
+
+/**
+ * This example is demonstrating a WS-Notification scenario
+ * when (for simplicity) QMan is at the same time consumer
+ * and producer.
+ *
+ * Basically we have (on producer side) two topics : one for
+ * lifecycle events of object instance (objects created & removed)
+ * and another one for lifecycle of event (events created).
+ *
+ * On consumer side there are many options that you can use in
+ * order to made a sunscription :
+ *
+ * <ul>
+ * <li>you could be an observer of all messages (all topics);</li>
+ * <li>you could be an observer of one specific topic;</li>
+ * <li>
+ * you could be an observer of all messages that match
+ * a condition expressed in XPath;
+ * </li>
+ * </ul>
+ *
+ * All those options are provided with or withour a termination time.
+ * A subscription with a termination time will have a predefined expiry
+ * date while if there's no termination the subscription will never expire.
+ *
+ * @author Andrea Gazzarini
+ *
+ */
+public class ConsumerAndProducerExample extends AbstractQManExample
+{
+ @Override
+ void executeExample(String host, int port) throws Exception
+ {
+ // This is QMan...
+ URI producerURI = URI.create("http://"+host+":"+port+"/qman/services/adapter");
+
+ // ...and this is QMan too! Note that it has an hidden consumer capability that is used in
+ // order to run successfully this example...
+ URI consumerURI = URI.create("http://"+host+":"+port+"/qman/services/consumer");
+
+ EndpointReference producerEPR = new EndpointReference(producerURI);
+ EndpointReference consumerEPR = new EndpointReference(consumerURI);
+
+ // Example 1 : all messages on all topics without termination time.
+ subscribeAllMessagesWithoutTerminationTime(producerEPR,consumerEPR);
+
+ // Example 2 : all messages on all topics with termination time.
+ subscribeAllMessagesWithTerminationTime(producerEPR,consumerEPR);
+
+ // Example 3: Topic filter without termination time.
+ topicSubscriptionWithoutTerminationTime(producerEPR,consumerEPR);
+
+ // Example 4: Topic filter with termination time.
+ topicSubscriptionWithTerminationTime(producerEPR,consumerEPR);
+
+ // Example 5: a MessageFilter is installed in order to listen only for connection events
+ // (connections created or removed). The subscription never expire.
+ allMessagesWithMessageFilterWithoutTerminationTime(producerEPR,consumerEPR);
+
+ // Example 6: a MessageFilter is installed in order to listen only for connection events
+ // (connections created or removed). The subscription will expire in 10 seconds.
+ allMessagesWithMessageFilterAndTerminationTime(producerEPR,consumerEPR);
+
+ // Example 7 : a subscription with more than one filter.
+ complexSubscription(producerEPR, consumerEPR);
+ }
+
+ /**
+ * Makes a subscription on all topics / all messages without an expiry date.
+ *
+ * @param producer the producer endpoint reference.
+ * @param consumer the consumer endpoint reference .
+ * @throws SoapFault when the subscription cannot be made.
+ */
+ private void subscribeAllMessagesWithoutTerminationTime(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ null, // Filter, if null that means "all messages"
+ null); // Termination Time : if null the subscription will never expire.
+ }
+
+ /**
+ * Makes a subscription on all topics / all messages with 10 seconds as termination time.
+ * The subscription will expire after 10 seconds.
+ *
+ * @param producer the producer endpoint reference.
+ * @param consumer the consumer endpoint reference .
+ * @throws SoapFault when the subscription cannot be made.
+ */
+ private void subscribeAllMessagesWithTerminationTime(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ null, // Filter, if null that means "all messages"
+ new Date(System.currentTimeMillis() + 10000)); // Termination Time
+ }
+
+ /**
+ * Makes a subscription on a specifc topic without an expiry date.
+ * Only messages published on the given topic will be delivered to the given consumer.
+ *
+ * @param producer the producer endpoint reference.
+ * @param consumer the consumer endpoint reference .
+ * @throws SoapFault when the subscription cannot be made.
+ */
+ private void topicSubscriptionWithoutTerminationTime(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ TopicFilter filter = new TopicFilter(Names.EVENTS_LIFECYLE_TOPIC_NAME);
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ filter, // Topic Filter
+ null); // Termination Time : if null the subscription will never expire.
+ }
+
+ /**
+ * Makes a subscription on a specifc topic with an expiry date.
+ * Only messages published on the given topic will be delivered to the given consumer.
+ * The subscription will end after 10 seconds
+ *
+ * @param producer the producer endpoint reference.
+ * @param consumer the consumer endpoint reference .
+ * @throws SoapFault when the subscription cannot be made.
+ */
+ private void topicSubscriptionWithTerminationTime(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ TopicFilter filter = new TopicFilter(Names.EVENTS_LIFECYLE_TOPIC_NAME);
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ filter, // Topic Filter
+ new Date(System.currentTimeMillis() + 10000)); // Termination Time
+ }
+
+ /**
+ * Makes a subscription on all topics with a message filter without an expiry date.
+ *
+ * @param producer the producer endpoint reference.
+ * @param consumer the consumer endpoint reference .
+ * @throws SoapFault when the subscription cannot be made.
+ */
+ private void allMessagesWithMessageFilterWithoutTerminationTime(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ // Applying this filter will result in a subscription that wll be notified only when a "connection"
+ // object is created or removed
+ MessagePatternFilter filter= new MessagePatternFilter(
+ "/wsnt:NotificationMessage/wsnt:Message/qman:LifeCycleEvent/qman:Resource/qman:Name/text()='connection'", // expression (XPath)
+ XPathUtils.NAMESPACE_URI); // Dialect : the only supported dialect is XPath 1.0
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ filter, // Message Filter
+ null); // Termination Time : if null the subscription will never expire.
+ }
+
+ /**
+ * Makes a subscription on all topics with a message filter and an expiry date.
+ *
+ * @param producer the producer endpoint reference.
+ * @param consumer the consumer endpoint reference .
+ * @throws SoapFault when the subscription cannot be made.
+ */
+ private void allMessagesWithMessageFilterAndTerminationTime(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ // Applying this filter will result in a subscription that wll be notified only when a "connection"
+ // object is created or removed
+ MessagePatternFilter filter= new MessagePatternFilter(
+ "/wsnt:NotificationMessage/wsnt:Message/qman:LifeCycleEvent/qman:Resource/qman:Name/text()='connection'", // expression (XPath)
+ XPathUtils.NAMESPACE_URI); // Dialect : the only supported dialect is XPath 1.0
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ filter, // Message Filter
+ new Date(System.currentTimeMillis() + 10000)); // Termination Time
+ }
+
+ /**
+ * Makes a subscription on a specifc topic with an expiry date.
+ * Only messages published on the given topic will be delivered to the given consumer.
+ * The subscription will end after 10 seconds
+ *
+ * @param producer the producer endpoint reference.
+ * @param consumer the consumer endpoint reference .
+ * @throws SoapFault when the subscription cannot be made.
+ */
+ private void complexSubscription(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ FilterCollection filter = new FilterCollection();
+
+ TopicFilter topicFilter = new TopicFilter(Names.EVENTS_LIFECYLE_TOPIC_NAME);
+ MessagePatternFilter messageFilter= new MessagePatternFilter(
+ "/wsnt:NotificationMessage/wsnt:Message/qman:LifeCycleEvent/qman:Resource/qman:Name/text()='connection'", // expression (XPath)
+ XPathUtils.NAMESPACE_URI); // Dialect : the only supported dialect is XPath 1.0
+
+ ProducerPropertiesFilter producerFilter = new ProducerPropertiesFilter(
+ "boolean(/*/MgtPubInterval > 100 and /*/MsgTotalEnqueues > 56272)",
+ XPathUtils.NAMESPACE_URI);
+
+ filter.addFilter(topicFilter);
+ filter.addFilter(messageFilter);
+ filter.addFilter(producerFilter);
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ filter, // Topic Filter
+ new Date(System.currentTimeMillis() + 10000)); // Termination Time
+ }
+
+ @Override
+ void printOutExampleDescription()
+ {
+ System.out.println("This example is demonstrating a WS-Notification scenario ");
+ System.out.println("when (for simplicity) QMan is at the same time consumer ");
+ System.out.println("and producer.");
+ System.out.println();
+ System.out.println("Basically we have (on producer side) two topics : one for");
+ System.out.println("lifecycle events of object instance (objects created & removed) ");
+ System.out.println("and another one for lifecycle of event (events created).");
+ System.out.println();
+ System.out.println("On consumer side there are many options that you can use in");
+ System.out.println("order to made a sunscription :");
+ System.out.println();
+ System.out.println("- you could be an observer of all messages (all topics);");
+ System.out.println("- you could be an observer of one specific topic;");
+ System.out.println("- you could be an observer of all messages that match a condition expressed in XPath;");
+ System.out.println();
+ System.out.println("All those options are provided with or withour a termination time.");
+ System.out.println("A subscription with a termination time will have a predefined expiry");
+ System.out.println("date while if there's no termination the subscription will never expire.");
+ }
+
+ public static void main(String[] args)
+ {
+ new ConsumerAndProducerExample().execute(new String[]{"localhost","8080"});
+ }
+}
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetMultipleResourcePropertiesExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetMultipleResourcePropertiesExample.java
new file mode 100644
index 0000000000..413222a79d
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetMultipleResourcePropertiesExample.java
@@ -0,0 +1,179 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.example;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.w3c.dom.Element;
+
+/**
+ * This example shows how to get properties from a WS-Resource using one request.
+ * First of all a request is send to WS-DM in order to get all registered WS-Resources.
+ * If the returned list is not empty then a GetMetadataRequest is sent to the
+ * first child.
+ * The result metadata descriptor contains all properties names of the target WS-Resource.
+ * Those names are then used for retrieving the corresponding values.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetMultipleResourcePropertiesExample extends AbstractQManExample
+{
+
+ /**
+ * First of all a request is send to WS-DM in order to get all registered WS-Resources.
+ * If the returned list is not empty then a GetMetadataRequest is sent to the
+ * first child.
+ * The result metadata descriptor contains all properties names of the target WS-Resource.
+ * Those names are then used for retrieving the corresponding values.
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception
+ {
+
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference adapterEndpointReference = getAdapterEndpointReference(host, port);
+
+ // 2) Creates the Adapter service client...
+ ServiceGroupClient adapterClient = new ServiceGroupClient(adapterEndpointReference);
+ adapterClient.setTrace(true);
+
+ // 3) Retrieves the all registered members (QMan WS-Resources)
+ WsResourceClient [] resources = adapterClient.getMembers();
+
+ // Sanity check : we cannot proceed if there are no WS-Resources.
+ if (resources.length == 0)
+ {
+ System.out.println("----------------------------WARNING---------------------------");
+ System.out.println("Cannot proceed with the example... it seems");
+ System.out.println("that there are no managed WS-Resources on QMan.");
+ System.out.println("Please check QMan in order to see that it is really");
+ System.out.println("connected with a broker.");
+ System.out.println("-------------------------------------------------------------------");
+ System.exit(0);
+ }
+
+ // 4) Creates a proxy handler for service invocation.
+ ProxyHandler metadataProxyHandler = createProxyHandler();
+
+ // 5) ..and invokes the GetMetadata on the first member.
+ WsResourceClient wsResourceClient = resources[0];
+ wsResourceClient.setTrace(true);
+
+ // Dialect is RDM for this example
+ String dialect = "http://docs.oasis-open.org/wsrf/rmd-1";
+ Object [] inputParameters = {dialect};
+
+ // RDM is the first element of the returned array.
+ // The first element is a wsx:Metadata containing all resource properties.
+ Element [] metadata = (Element[]) wsResourceClient.invoke(metadataProxyHandler, inputParameters);
+ Element resourceMetadataDescriptor = metadata[0];
+
+ // 6) using XPath navigates xml in order to get the list of all properties.
+ Element [] properties = XmlUtils.findInSubTree(
+ resourceMetadataDescriptor,
+ new QName("http://docs.oasis-open.org/wsrf/rmd-1","Property","wsrmd"));
+ List<QName> names = new ArrayList<QName>();
+
+ for (Element property : properties)
+ {
+
+ String attributeName = property.getAttribute("name"); // = qman:<Attribute Name>
+
+ // For this example we are only interested on qman namespace related properties...
+ if (attributeName.startsWith("qman"))
+ {
+ String attributeNameWithoutPrefix = attributeName.replaceFirst("qman:", ""); // = <Attribute Name>
+
+ names.add(new QName(
+ "http://amqp.apache.org/qpid/management/qman",
+ attributeNameWithoutPrefix,
+ "qman"));
+ }
+ }
+
+ QName [] qnames = names.toArray(new QName[names.size()]);
+
+ // 7) Send a GetMultipleResourcePropertiesRequest.
+ // We do nothing with the returned value(s) because it / they
+ // has / have already printed out (wsResourceClient.setTrace(true))
+ @SuppressWarnings("unused")
+ Element [] values = wsResourceClient.getMultipleResourceProperties(qnames);
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("This example shows how to get properties from a");
+ System.out.println("WS-Resource using one request. ");
+ System.out.println("First of all a request is send to WS-DM in order to get");
+ System.out.println("all registered WS-Resources.");
+ System.out.println("If the returned list is not empty then a GetMetadataRequest");
+ System.out.println("to the first child.");
+ System.out.println("The result metadata descriptor contains all property names of");
+ System.out.println("the target WS-Resource.");
+ System.out.println("Those names are then used for retrieving the corresponding values");
+ System.out.println("using the GetMultipleResourceProperties request.");
+ System.out.println();
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ }
+
+ /**
+ * A proxy handler is a module needed in order to make a capability
+ * service invocation.
+ * It contains logic to serialize and deserialize request, response, input and
+ * output parameters during a web service invocation.
+ *
+ * @return a proxy handler.
+ */
+ private ProxyHandler createProxyHandler()
+ {
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ handler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", PREFIX));
+ handler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", PREFIX)});
+ handler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", PREFIX));
+ handler.setReturnType(Element[].class);
+ return handler;
+ }
+
+ public static void main(String[] arguments)
+ {
+ new GetMultipleResourcePropertiesExample().execute(arguments);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetQManResourceMembersExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetQManResourceMembersExample.java
new file mode 100644
index 0000000000..f74a44ab57
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetQManResourceMembersExample.java
@@ -0,0 +1,93 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.example;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+
+/**
+ * An example demonstrating the usage of GetResourcePropertyRequest/Response on
+ * the WS-DM Adapter.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetQManResourceMembersExample extends AbstractQManExample
+{
+ /**
+ * Looks for memebers of QMan group requesting ws-rp:Entry property to
+ * WS-DM Adapter resource service.
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception
+ {
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference serviceEndpointReference = getAdapterEndpointReference(host, port);
+
+ // 2) Creates the Service client...
+ ServiceGroupClient adapterClient = new ServiceGroupClient(serviceEndpointReference);
+ adapterClient.setTrace(true);
+
+ // 3) Invokes the service.
+ WsResourceClient [] resources = adapterClient.getMembers();
+
+ String result = (resources.length != 0)
+ ? ("QMan has at the moment "+resources.length+" registered resources.")
+ : "It seems that there are no managed resource on QMan side...";
+
+ System.out.println("--------------------------------------------------------------------------");
+ System.out.println(result);
+ System.out.println("--------------------------------------------------------------------------");
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("This example shows the usage of WS-DM ");
+ System.out.println("GetResourcePropertyRequest / Response on a ");
+ System.out.println("Group service.");
+ System.out.println("The target resource is the WS-DM Adapter itself ");
+ System.out.println("and the requested property is \"wsrf-sg:Entry\".");
+ System.out.println("WS-DM Adapter is a special WS-Resource (is a Group)");
+ System.out.println("that acts as the main entry point for retrieving");
+ System.out.println("all other managed resources.");
+ System.out.println("So clients that want to deal with QMan WS-Resources");
+ System.out.println("must first get resource identifiers sending");
+ System.out.println("a GetResourcePropertyRequest to WS-DM Adapter ");
+ System.out.println("with \"wsrf-sg:Entry\" as target target property.");
+ System.out.println();
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ }
+
+ public static void main(String[] arguments)
+ {
+ new GetQManResourceMembersExample().execute(arguments);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourceMetadataDescriptorExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourceMetadataDescriptorExample.java
new file mode 100644
index 0000000000..84befc01e4
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourceMetadataDescriptorExample.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.management.example;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.w3c.dom.Element;
+
+/**
+ * This example shows how to get metadata from a WS-Resource.
+ * The service supports different kinds of metadata.
+ * User who wants to receive metadata of a WS-Resource must
+ * send a GetMetadataRequesta specifying the requested dialect.
+ *
+ * Supported metadata that could be requested are
+ *
+ * <ul>
+ * <li>
+ * WSDL : requested using "http://schemas.xmlsoap.org/wsdl/" as dialect..
+ * <li>
+ * <li>
+ * RDM (Resource Metadata Descriptor) : requested using "http://docs.oasis-open.org/wsrf/rmd-1 "as dialect.
+ * </li>
+ * </ul>
+ *
+ * Note that this example focuses on RDM Metadata only; another example is dedicated to WSDL.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetResourceMetadataDescriptorExample extends AbstractQManExample
+{
+
+ /**
+ * First, sends a request to WS-DM Adapter in order to get the list of managed resources.
+ * If the list is not empty, then takes the first member and sends it a GetMetadataRequest
+ * in order to get its RDM.
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception
+ {
+
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference adapterEndpointReference = getAdapterEndpointReference(host, port);
+
+ // 2) Creates the Adapter service client...
+ ServiceGroupClient adapterClient = new ServiceGroupClient(adapterEndpointReference);
+ adapterClient.setTrace(true);
+
+ // 3) Retrieves the all registered members (QMan WS-Resources)
+ WsResourceClient [] resources = adapterClient.getMembers();
+
+ // Sanity check : we cannot proceed if there are no WS-Resources.
+ if (resources.length == 0)
+ {
+ System.out.println("----------------------------WARNING---------------------------");
+ System.out.println("Cannot proceed with the example... it seems");
+ System.out.println("that there are no managed WS-Resources on QMan.");
+ System.out.println("Please check QMan in order to see that it is really");
+ System.out.println("connected with a broker.");
+ System.out.println("-------------------------------------------------------------------");
+ System.exit(0);
+ }
+
+ // 4) Creates a proxy handler for service invocation.
+ ProxyHandler metadataProxyHandler = createProxyHandler();
+
+ // 5) ..and invokes the GetMetadata on the first member.
+ WsResourceClient firstMember = resources[0];
+ firstMember.setTrace(true);
+
+ // Dialect is RDM for this example
+ String dialect = "http://docs.oasis-open.org/wsrf/rmd-1";
+ Object [] inputParameters = {dialect};
+
+ // WSDL is the first element of the returned array. We don't need to print out it here
+ // because at this point it should have been already printed out (line 96 : firstMember.setTrace(true))
+ @SuppressWarnings("unused")
+ Element [] metadata = (Element[]) firstMember.invoke(metadataProxyHandler, inputParameters);
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("The example shows how to get metadata from a");
+ System.out.println("WS-Resource.");
+ System.out.println("A QMan WS-Resource has different kinds of metadata.");
+ System.out.println("(see below)");
+ System.out.println("User who wants to receive metadata of a WS-Resource");
+ System.out.println("must send a GetMetadataRequesta specifying the");
+ System.out.println("associated dialect.");
+ System.out.println("Supported metadata that could be requested are : ");
+ System.out.println();
+ System.out.println("- WSDL : in this case dialect is \"http://schemas.xmlsoap.org/wsdl/\";");
+ System.out.println("- RDM (Resource Metadata Descriptor) : in this case dialect is \"http://docs.oasis-open.org/wsrf/rmd-1 \".");
+ System.out.println();
+ System.out.println("Note that this examples focuses on RDM Metadata only;");
+ System.out.println("another one is dedicated to WSDL.");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ }
+
+ /**
+ * A proxy handler is a module needed in order to make a capability
+ * service invocation.
+ * It contains logic to serialize and deserialize request, response, input and
+ * output parameters during a web service invocation.
+ *
+ * @return a proxy handler.
+ */
+ private ProxyHandler createProxyHandler()
+ {
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ handler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", PREFIX));
+ handler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", PREFIX)});
+ handler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", PREFIX));
+ handler.setReturnType(Element[].class);
+ return handler;
+ }
+
+ public static void main(String[] arguments)
+ {
+ new GetResourceMetadataDescriptorExample().execute(arguments);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyDocumentExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyDocumentExample.java
new file mode 100644
index 0000000000..56ce81358d
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyDocumentExample.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.management.example;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.w3c.dom.Element;
+
+/**
+ * This example shows how to get the whole property document from a WS-Resource.
+ * Resource property document represents a particular composed structural view of
+ * the resource properties of the WS-Resource.
+ * Let's say that It is a way to get all-in-once the state of the WS-Resource.
+ *
+ * First of all a request is send to WS-DM in order to get all registered WS-Resources.
+ * If the returned list is not empty then a GetResourcePropertyDocumentRequest is
+ * sent to the first child.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetResourcePropertyDocumentExample extends AbstractQManExample
+{
+
+ /**
+ * First of all a request is send to WS-DM in order to get all registered WS-Resources.
+ * If the returned list is not empty then a GetResourcePropertyDocumentRequest is
+ * sent to the first child.
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception
+ {
+
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference adapterEndpointReference = getAdapterEndpointReference(host, port);
+
+ // 2) Creates the Adapter service client...
+ ServiceGroupClient adapterClient = new ServiceGroupClient(adapterEndpointReference);
+ adapterClient.setTrace(true);
+
+ // 3) Retrieves the all registered members (QMan WS-Resources)
+ WsResourceClient [] resources = adapterClient.getMembers();
+
+ // Sanity check : we cannot proceed if there are no WS-Resources.
+ if (resources.length == 0)
+ {
+ System.out.println("----------------------------WARNING---------------------------");
+ System.out.println("Cannot proceed with the example... it seems");
+ System.out.println("that there are no managed WS-Resources on QMan.");
+ System.out.println("Please check QMan in order to see that it is really");
+ System.out.println("connected with a broker.");
+ System.out.println("-------------------------------------------------------------------");
+ System.exit(0);
+ }
+
+ // 4) ..and invokes the GetMetadata on the first member.
+ WsResourceClient wsResourceClient = resources[0];
+ wsResourceClient.setTrace(true);
+
+ @SuppressWarnings("unused")
+ Element resourcePropertyDocument = wsResourceClient.getResourcePropertyDocument();
+ }
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("This example shows how to get the whole property");
+ System.out.println("document from a WS-Resource.");
+ System.out.println("Resource property document represents a particular ");
+ System.out.println("composed structural view of the resource properties");
+ System.out.println("of the WS-Resource.");
+ System.out.println("First of all a request is send to WS-DM in order to get");
+ System.out.println("all registered WS-Resources.");
+ System.out.println("the target WS-Resource.");
+ System.out.println("If the returned list is not empty then a");
+ System.out.println("GetResourcePropertyDocumentRequest is sent to the first child.");
+ System.out.println();
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ }
+
+ public static void main(String[] arguments)
+ {
+ new GetResourcePropertyDocumentExample().execute(arguments);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyExample.java
new file mode 100644
index 0000000000..28ed1c7925
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyExample.java
@@ -0,0 +1,172 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.example;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.w3c.dom.Element;
+
+/**
+ * This example shows how to get the property value from a WS-Resource.
+ * First of all a request is send to WS-DM in order to get all registered WS-Resources.
+ * If the returned list is not empty then a GetMetadataRequest is sent to the
+ * first child.
+ * The result metadata descriptor contains all properties of the target WS-Resource.
+ * For each of them a GetResourcePropertyRequest is sent in order to get its value.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetResourcePropertyExample extends AbstractQManExample
+{
+
+ /**
+ * First, sends a request to WS-DM Adapter in order to get the list of managed resources.
+ * If the list is not empty, then takes the first member and sends it a GetMetadataRequest
+ * in order to get its WSDL.
+ * After that, for each property contained in ResourceMetadataDescriptorm (RDM) a
+ * GetResourcePropertyRequest is sent in order to get its value.
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception
+ {
+
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference adapterEndpointReference = getAdapterEndpointReference(host, port);
+
+ // 2) Creates the Adapter service client...
+ ServiceGroupClient adapterClient = new ServiceGroupClient(adapterEndpointReference);
+ adapterClient.setTrace(true);
+
+ // 3) Retrieves the all registered members (QMan WS-Resources)
+ WsResourceClient [] resources = adapterClient.getMembers();
+
+ // Sanity check : we cannot proceed if there are no WS-Resources.
+ if (resources.length == 0)
+ {
+ System.out.println("----------------------------WARNING---------------------------");
+ System.out.println("Cannot proceed with the example... it seems");
+ System.out.println("that there are no managed WS-Resources on QMan.");
+ System.out.println("Please check QMan in order to see that it is really");
+ System.out.println("connected with a broker.");
+ System.out.println("-------------------------------------------------------------------");
+ System.exit(0);
+ }
+
+ // 4) Creates a proxy handler for service invocation.
+ ProxyHandler metadataProxyHandler = createProxyHandler();
+
+ // 5) ..and invokes the GetMetadata on the first member.
+ WsResourceClient wsResourceClient = resources[0];
+ wsResourceClient.setTrace(true);
+
+ // Dialect is RDM for this example
+ String dialect = "http://docs.oasis-open.org/wsrf/rmd-1";
+ Object [] inputParameters = {dialect};
+
+ // RDM is the first element of the returned array.
+ // The first element is a wsx:Metadata containing all resource properties.
+ Element [] metadata = (Element[]) wsResourceClient.invoke(metadataProxyHandler, inputParameters);
+ Element resourceMetadataDescriptor = metadata[0];
+
+ // 6) using XPath navigates xml in order to get the list of all properties.
+ Element [] properties = XmlUtils.findInSubTree(
+ resourceMetadataDescriptor,
+ new QName("http://docs.oasis-open.org/wsrf/rmd-1","Property","wsrmd"));
+
+ for (Element property : properties)
+ {
+
+ String attributeName = property.getAttribute("name"); // = qman:<Attribute Name>
+
+ // For this example we are only interested on qman namespace related properties...
+ if (attributeName.startsWith("qman"))
+ {
+ String attributeNameWithoutPrefix = attributeName.replaceFirst("qman:", ""); // = <Attribute Name>
+
+ // 7) Send a GetResourcePropertyRequest for the given attribute.
+ // We do nothing with the returned value(s) because it / they
+ // has / have already printed out (wsResourceClient.setTrace(true))
+ @SuppressWarnings("unused")
+ Element [] values = wsResourceClient.getResourceProperty(
+ new QName(
+ "http://amqp.apache.org/qpid/management/qman",
+ attributeNameWithoutPrefix,
+ "qman"));
+ }
+ }
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("This example shows how to get the property value");
+ System.out.println("from a WS-Resource.");
+ System.out.println("First of all a request is send to WS-DM in order to get");
+ System.out.println("all registered WS-Resources.");
+ System.out.println("If the returned list is not empty then a GetMetadataRequest");
+ System.out.println("to the first child.");
+ System.out.println("The result metadata descriptor contains all properties of");
+ System.out.println("the target WS-Resource.");
+ System.out.println("For each of them a GetResourcePropertyRequest is sent");
+ System.out.println(" in order to get its value.");
+ System.out.println();
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ }
+
+ /**
+ * A proxy handler is a module needed in order to make a capability
+ * service invocation.
+ * It contains logic to serialize and deserialize request, response, input and
+ * output parameters during a web service invocation.
+ *
+ * @return a proxy handler.
+ */
+ private ProxyHandler createProxyHandler()
+ {
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ handler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", PREFIX));
+ handler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", PREFIX)});
+ handler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", PREFIX));
+ handler.setReturnType(Element[].class);
+ return handler;
+ }
+
+ public static void main(String[] arguments)
+ {
+ new GetResourcePropertyExample().execute(arguments);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetWSDLMetadataExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetWSDLMetadataExample.java
new file mode 100644
index 0000000000..ecda6e8fb1
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetWSDLMetadataExample.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.management.example;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.w3c.dom.Element;
+
+/**
+ * This example shows how to get metadata from a WS-Resource.
+ * The service supports different kinds of metadata.
+ * User who wants to receive metadata of a WS-Resource must
+ * send a GetMetadataRequesta specifying the requested dialect.
+ *
+ * Supported metadata that could be requested are
+ *
+ * <ul>
+ * <li>
+ * WSDL : requested using "http://schemas.xmlsoap.org/wsdl/" as dialect..
+ * <li>
+ * <li>
+ * RDM (Resource Metadata Descriptor) : requested using "http://docs.oasis-open.org/wsrf/rmd-1 "as dialect.
+ * </li>
+ * </ul>
+ *
+ * Note that this example focuses on WSDL Metadata only; another example is dedicated to RDM.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetWSDLMetadataExample extends AbstractQManExample
+{
+
+ /**
+ * First, sends a request to WS-DM Adapter in order to get the list of managed resources.
+ * If the list is not empty, then takes the first member and sends it a GetMetadataRequest
+ * in order to get its WSDL.
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception
+ {
+
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference adapterEndpointReference = getAdapterEndpointReference(host, port);
+
+ // 2) Creates the Adapter service client...
+ ServiceGroupClient adapterClient = new ServiceGroupClient(adapterEndpointReference);
+ adapterClient.setTrace(true);
+
+ // 3) Retrieves the all registered members (QMan WS-Resources)
+ WsResourceClient [] resources = adapterClient.getMembers();
+
+ // Sanity check : we cannot proceed if there are no WS-Resources.
+ if (resources.length == 0)
+ {
+ System.out.println("----------------------------WARNING---------------------------");
+ System.out.println("Cannot proceed with the example... it seems");
+ System.out.println("that there are no managed WS-Resources on QMan.");
+ System.out.println("Please check QMan in order to see that it is really");
+ System.out.println("connected with a broker.");
+ System.out.println("-------------------------------------------------------------------");
+ System.exit(0);
+ }
+
+ // 4) Creates a proxy handler for service invocation.
+ ProxyHandler metadataProxyHandler = createProxyHandler();
+
+ // 5) ..and invokes the GetMetadata on the first member.
+ WsResourceClient firstMember = resources[0];
+ firstMember.setTrace(true);
+
+ // Dialect is WSDL for this example
+ String dialect = "http://schemas.xmlsoap.org/wsdl/";
+ Object [] inputParameters = {dialect};
+
+ // WSDL is the first element of the returned array. We don't need to print out it here
+ // because at this point it should have been already printed out (line 96 : firstMember.setTrace(true))
+ @SuppressWarnings("unused")
+ Element [] metadata = (Element[]) firstMember.invoke(metadataProxyHandler, inputParameters);
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("The example shows how to get metadata from a");
+ System.out.println("WS-Resource.");
+ System.out.println("A QMan WS-Resource has different kinds of metadata.");
+ System.out.println("(see below)");
+ System.out.println("User who wants to receive metadata of a WS-Resource");
+ System.out.println("must send a GetMetadataRequesta specifying the");
+ System.out.println("associated dialect.");
+ System.out.println("Supported metadata that could be requested are : ");
+ System.out.println();
+ System.out.println("- WSDL : in this case dialect is \"http://schemas.xmlsoap.org/wsdl/\";");
+ System.out.println("- RDM (Resource Metadata Descriptor) : in this case dialect is \"http://docs.oasis-open.org/wsrf/rmd-1 \".");
+ System.out.println();
+ System.out.println("Note that this examples focuses on WSDL Metadata only;");
+ System.out.println("another one is dedicated to RDM.");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ }
+
+ /**
+ * A proxy handler is a module needed in order to make a capability
+ * service invocation.
+ * It contains logic to serialize and deserialize request, response, input and
+ * output parameters during a web service invocation.
+ *
+ * @return a proxy handler.
+ */
+ private ProxyHandler createProxyHandler()
+ {
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ handler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", PREFIX));
+ handler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", PREFIX)});
+ handler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", PREFIX));
+ handler.setReturnType(Element[].class);
+ return handler;
+ }
+
+ public static void main(String[] arguments)
+ {
+ new GetWSDLMetadataExample().execute(arguments);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/PausableSubscriptionExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/PausableSubscriptionExample.java
new file mode 100644
index 0000000000..01a27a16f9
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/PausableSubscriptionExample.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.management.example;
+
+import java.net.URI;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.notification.remote.NotificationProducerClient;
+import org.apache.muse.ws.notification.remote.SubscriptionClient;
+
+/**
+ * This example is demonstrating a WS-Notification scenario
+ * when (for simplicity) QMan is at the same time consumer
+ * and producer.
+ *
+ * Specifically the example shows how a requestor can create, pause and resume
+ * a subscription.
+ *
+ * @author Andrea Gazzarini
+ *
+ */
+public class PausableSubscriptionExample extends AbstractQManExample
+{
+ @Override
+ void executeExample(String host, int port) throws Exception
+ {
+ // This is QMan...
+ URI producerURI = URI.create("http://"+host+":"+port+"/qman/services/adapter");
+
+ // ...and this is QMan too! Note that it has an hidden consumer capability that is used in
+ // order to run successfully this example...
+ URI consumerURI = URI.create("http://"+host+":"+port+"/qman/services/consumer");
+
+ EndpointReference producerEPR = new EndpointReference(producerURI);
+ EndpointReference consumerEPR = new EndpointReference(consumerURI);
+
+ NotificationProducerClient producerClient = new NotificationProducerClient(producerEPR);
+ producerClient.setTrace(true);
+
+ // 1) Creates a subscription and gets the corresponding reference.
+ SubscriptionClient subscriptionClient = producerClient.subscribe(
+ consumerEPR, // Consumer Endpoint reference
+ null, // Filter, if null that means "all messages"
+ null); // Termination Time : if null the subscription will never expire.
+ subscriptionClient.setTrace(true);
+
+
+ // 2) Pauses the subscription.
+ subscriptionClient.pauseSubscription();
+
+ // 3) Resumes the subscription.
+ subscriptionClient.resumeSubscription();
+ }
+
+ @Override
+ void printOutExampleDescription()
+ {
+ System.out.println("This example is demonstrating a WS-Notification scenario ");
+ System.out.println("when (for simplicity) QMan is at the same time consumer ");
+ System.out.println("and producer.");
+ System.out.println();
+ System.out.println("Specifically the example shows how a requestor can create,");
+ System.out.println("pause and resume a subscription.");
+ }
+
+ public static void main(String[] args)
+ {
+ new PausableSubscriptionExample().execute(new String[]{"romagazzarini","8080"});
+ }
+}
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/SetResourcePropertyExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/SetResourcePropertyExample.java
new file mode 100644
index 0000000000..8aed3101ff
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/SetResourcePropertyExample.java
@@ -0,0 +1,306 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.example;
+
+import java.lang.reflect.Array;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.w3c.dom.Element;
+
+/**
+ * This example shows how to change the state of a WS-Resource. That means
+ * a SetResourcePropertyRequest is sent to that WS-Resource.
+ * First of all a request is send to WS-DM in order to get all registered WS-Resources.
+ * If the returned list is not empty then two GetMetadataRequests are sent to the
+ * first child (one for WSDL and one for RDM).
+ * The result metadata descriptors are the used to determine :
+ *
+ * <br> What are names of WS-Resouce properties
+ * <br> Their modifiability (read-only or read-write)
+ * <br> Their type
+ *
+ * So a SetResourcePropertyRequest can be sent in order to change the WS-Resource state.
+ * The example is looking for a property that has one of the following datatype :
+ *
+ * <ul>
+ * <li>String</li>
+ * <li>Long</li>
+ * <li>Integer</li>
+ * <li>Short</li>
+ * <li>Double</li>
+ * <li>Float</li>
+ * </ul>
+ *
+ * After the update / insert request has been sent, a GetResourcePropertiesRequest is made
+ * again in order to see if the state has changed correctly.
+ *
+ * @author Andrea Gazzarini
+ */
+public class SetResourcePropertyExample extends AbstractQManExample
+{
+ /**
+ * First of all a request is send to WS-DM in order to get all registered WS-Resources.
+ * If the returned list is not empty then two GetMetadataRequests are sent to the
+ * first child (one for WSDL and one for RDM).
+ * The result metadata descriptors are the used to determine :
+ *
+ * <br> What are names of WS-Resouce properties
+ * <br> Their modifiability (read-only or read-write)
+ * <br> Their type
+ *
+ * So a SetResourcePropertyRequest can be sent in order to change the WS-Resource state.
+ * The example is looking for a property that has one of the following datatype :
+ *
+ * <ul>
+ * <li>String</li>
+ * <li>Long</li>
+ * <li>Integer</li>
+ * <li>Short</li>
+ * <li>Double</li>
+ * <li>Float</li>
+ * </ul>
+ *
+ * After the update / insert request has been sent, a GetResourcePropertiesRequest is made
+ * again in order to see if the state has changed correctly.
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception
+ {
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference adapterEndpointReference = getAdapterEndpointReference(host, port);
+
+ // 2) Creates the Adapter service client...
+ ServiceGroupClient adapterClient = new ServiceGroupClient(adapterEndpointReference);
+ adapterClient.setTrace(false);
+
+ // 3) Retrieves the all registered members (QMan WS-Resources)
+ WsResourceClient [] resources = adapterClient.getMembers();
+
+ // Sanity check : we cannot proceed if there are no WS-Resources.
+ if (resources.length == 0)
+ {
+ System.out.println("----------------------------WARNING---------------------------");
+ System.out.println("Cannot proceed with the example... it seems");
+ System.out.println("that there are no managed WS-Resources on QMan.");
+ System.out.println("Please check QMan in order to see that it is really");
+ System.out.println("connected with a broker.");
+ System.out.println("-------------------------------------------------------------------");
+ System.exit(0);
+ }
+
+ // 4) Creates a proxy handler for service invocation.
+ ProxyHandler metadataProxyHandler = createProxyHandler();
+
+ // 5) ..and invokes the GetMetadata on the first member.
+ WsResourceClient wsResourceClient = resources[0];
+ wsResourceClient.setTrace(true);
+
+ // Resource Metadata Descriptor
+ String dialect = "http://docs.oasis-open.org/wsrf/rmd-1";
+ Object [] inputParameters = {dialect};
+
+ // RDM is the first element of the returned array.
+ // The first element is a wsx:Metadata containing all resource properties.
+ Element [] metadata = (Element[]) wsResourceClient.invoke(metadataProxyHandler, inputParameters);
+ Element resourceMetadataDescriptor = metadata[0];
+
+ // 6) Now we need WSDL in order to catch datatypes
+ dialect = "http://schemas.xmlsoap.org/wsdl/";
+ inputParameters = new Object[]{dialect};
+ metadata = (Element[]) wsResourceClient.invoke(metadataProxyHandler, inputParameters);
+ Element wsdl = metadata[0];
+
+ //7) Defines sample values used for update property.
+ Map<String, Object> sampleValues = new HashMap<String, Object>();
+ sampleValues.put("xsd:string","This is a string.");
+ sampleValues.put("xsd:integer",new Integer(12345));
+ sampleValues.put("xsd:int",new Integer(54321));
+ sampleValues.put("xsd:long",new Integer(12345));
+ sampleValues.put("xsd:double",new Double(12345.6d));
+ sampleValues.put("xsd:float",new Float(123.4f));
+ sampleValues.put("xsd:short",new Short((short)12));
+
+ // 8) using XPath navigates xml in order to get the list of all properties.
+ Element [] properties = XmlUtils.findInSubTree(
+ resourceMetadataDescriptor,
+ new QName("http://docs.oasis-open.org/wsrf/rmd-1","Property","wsrmd"));
+
+ Element [] wsdlElements = XmlUtils.findInSubTree(
+ wsdl,
+ new QName("http://www.w3.org/2001/XMLSchema","element","xsd"));
+
+ // Did we find at least one writable property?
+ boolean atLeastOnePropertyHasBeenFound = false;
+
+ for (Element property : properties)
+ {
+ // Sanity check : if the property is read-only then proceed with next
+ // property.
+ if (!"read-write".equals(property.getAttribute("modifiability")))
+ {
+ continue;
+ }
+
+ String attributeName = property.getAttribute("name"); // = qman:<Attribute Name>
+
+ // For this example we are only interested on qman namespace related properties...
+ if (attributeName.startsWith("qman"))
+ {
+ String attributeNameWithoutPrefix = attributeName.replaceFirst("qman:", ""); // = <Attribute Name>
+
+ for (Element wsdlElement : wsdlElements)
+ {
+ String name = wsdlElement.getAttribute("name");
+ String type = wsdlElement.getAttribute("type");
+ if ((name != null) && (attributeNameWithoutPrefix.equals(name)) && (type != null))
+ {
+ Object newValue = sampleValues.get(type);
+ if (newValue != null)
+ {
+ atLeastOnePropertyHasBeenFound = true;
+
+ inputParameters = new Object[] {newValue};
+
+ // 9) Makes a GetResourcePropertiesRequest in order to get the current value.
+ QName propertyQName = new QName(
+ "http://amqp.apache.org/qpid/management/qman",
+ name,
+ "qman");
+
+ // The returned value is really an array because property shoudl be a multi-value property.
+ // So in order to get its value we need to extract the first value.
+ Object currentValue = wsResourceClient.getPropertyAsObject(propertyQName,newValue.getClass());
+
+ // 10a) If the property is not set (value is null) then an "Insert" request must be sent.
+ if (currentValue == null || Array.getLength(currentValue) == 0)
+ {
+ wsResourceClient.insertResourceProperty(propertyQName,inputParameters);
+ }
+ // 10b) If the property is not null then an "Update" request must be sent.
+ else
+ {
+ wsResourceClient.updateResourceProperty(propertyQName,inputParameters);
+ }
+
+ // 11) Let's query again the resource using GetResourceProperties in order to ensure the
+ // previous property has been properly updated.
+ currentValue = wsResourceClient.getPropertyAsObject(propertyQName,newValue.getClass());
+
+ String resultMessage = (newValue.equals(Array.get(currentValue, 0)))
+ ? "Resource has been correctly updated."
+ : "Something was wrong : resource seems not to be properly updated.";
+
+ System.out.println("----------------------------------------------------------------------------------");
+ System.out.println(resultMessage);
+ System.out.println("----------------------------------------------------------------------------------");
+
+ // Let's stop...one property is enough for this example :)
+ break;
+ }
+ }
+ }
+ if (!atLeastOnePropertyHasBeenFound)
+ {
+ System.out.println("----------------------------------------------------------------------------------");
+ System.out.println("WARNING : This example wasn't able to run because no writable ");
+ System.out.println("property has been found on the target WS-Resource.");
+ System.out.println("----------------------------------------------------------------------------------");
+ }
+ }
+ }
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("This example shows how to change the state of a WS-Resource.");
+ System.out.println("That means a SetResourcePropertyRequest is sent to that");
+ System.out.println("WS-Resource.");
+ System.out.println("First of all a request is send to WS-DM in order to get all");
+ System.out.println("registered WS-Resources.");
+ System.out.println("If the returned list is not empty then two GetMetadataRequests");
+ System.out.println("(one for WSDL and one for RDM) are sent to the first child.");
+ System.out.println("The result metadata descriptors are used for determine :");
+ System.out.println();
+ System.out.println("1) WS-Resource property names;");
+ System.out.println("2) Modifiability (read-only, read-write");
+ System.out.println("3) Datatype;");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("So a SetResourcePropertyRequest can be sent in order");
+ System.out.println("to change the WS-Resource state.");
+ System.out.println("The example is looking for a property that has one of the");
+ System.out.println("following datatype :");
+ System.out.println();
+ System.out.println("1) String (xsd:string)");
+ System.out.println("2) Long (xsd:long)");
+ System.out.println("3) Integer (xsd:integer or xsd:int)");
+ System.out.println("4) Double (xsd:double)");
+ System.out.println("5) Float (xsd:float)");
+ System.out.println("6) Short (xsd:short)");
+ System.out.println();
+ System.out.println("After the update / insert request has been sent, a ");
+ System.out.println("GetResourcePropertiesRequest is made again");
+ System.out.println("in order to see if the state has changed correctly.");
+ System.out.println();
+ }
+
+ /**
+ * A proxy handler is a module needed in order to make a capability
+ * service invocation.
+ * It contains logic to serialize and deserialize request, response, input and
+ * output parameters during a web service invocation.
+ *
+ * @return a proxy handler.
+ */
+ private ProxyHandler createProxyHandler()
+ {
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ handler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", PREFIX));
+ handler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", PREFIX)});
+ handler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", PREFIX));
+ handler.setReturnType(Element[].class);
+ return handler;
+ }
+
+ public static void main(String[] arguments)
+ {
+ new SetResourcePropertyExample().execute(arguments);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/muse.xml b/qpid/java/management/client/src/main/java/muse.xml
new file mode 100644
index 0000000000..29a1c02e0c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/muse.xml
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<muse xmlns="http://ws.apache.org/muse/descriptor"
+ xmlns:wsrf-sgw="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://ws.apache.org/muse/descriptor muse-descriptor.xsd">
+ <custom-serializer>
+ <java-serializable-type>java.lang.Object</java-serializable-type>
+ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.ObjectSerializer</java-serializer-class>
+ </custom-serializer>
+ <custom-serializer>
+ <java-serializable-type>java.util.Map</java-serializable-type>
+ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.MapSerializer</java-serializer-class>
+ </custom-serializer>
+ <custom-serializer>
+ <java-serializable-type>java.util.HashMap</java-serializable-type>
+ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.MapSerializer</java-serializer-class>
+ </custom-serializer>
+ <custom-serializer>
+ <java-serializable-type>java.util.UUID</java-serializable-type>
+ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.UUIDSerializer</java-serializer-class>
+ </custom-serializer>
+ <custom-serializer>
+ <java-serializable-type>org.apache.qpid.management.wsdm.capabilities.Result</java-serializable-type>
+ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.InvocationResultSerializer</java-serializer-class>
+ </custom-serializer>
+ <custom-serializer>
+ <java-serializable-type>java.util.Date</java-serializable-type>
+ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.DateSerializer</java-serializer-class>
+ </custom-serializer>
+ <router>
+ <java-router-class>org.apache.muse.ws.resource.impl.WsResourceRouter</java-router-class>
+ <logging>
+ <log-file>log/muse.log</log-file>
+ <log-level>SEVERE</log-level>
+ </logging>
+ <persistence>
+ <java-persistence-class>org.apache.muse.core.routing.RouterFilePersistence</java-persistence-class>
+ <persistence-location>router-entries</persistence-location>
+ </persistence>
+ </router>
+ <resource-type use-router-persistence="true">
+ <context-path>consumer</context-path>
+ <wsdl>
+ <wsdl-file>wsdl/WS-BaseNotification-1_3.wsdl</wsdl-file>
+ <wsdl-port-type xmlns:wsntw="http://docs.oasis-open.org/wsn/bw-2">wsntw:NotificationConsumer</wsdl-port-type>
+ </wsdl>
+ <java-id-factory-class>org.apache.qpid.management.wsdm.common.QManResourceIdFactory</java-id-factory-class>
+ <java-resource-class>org.apache.muse.core.SimpleResource</java-resource-class>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer</capability-uri>
+ <java-capability-class>org.apache.muse.ws.notification.impl.SimpleNotificationConsumer</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://amqp.apache.org/qpid/management/qman/consumer</capability-uri>
+ <java-capability-class>org.apache.qpid.management.wsdm.capabilities.ConsumerCapability</java-capability-class>
+ </capability>
+ </resource-type>
+ <resource-type>
+ <context-path>SubscriptionManager</context-path>
+ <wsdl>
+ <wsdl-file>wsdl/WS-BaseNotification-1_3.wsdl</wsdl-file>
+ <wsdl-port-type xmlns:wsntw="http://docs.oasis-open.org/wsn/bw-2">wsntw:SubscriptionManager</wsdl-port-type>
+ </wsdl>
+ <java-id-factory-class>org.apache.qpid.management.wsdm.common.QManResourceIdFactory</java-id-factory-class>
+ <java-resource-class>org.apache.muse.ws.resource.impl.SimpleWsResource</java-resource-class>
+ <capability>
+ <capability-uri>http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</capability-uri>
+ <java-capability-class>org.apache.muse.ws.metadata.impl.SimpleMetadataExchange</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Get</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.get.impl.SimpleGetCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager</capability-uri>
+ <java-capability-class>org.apache.muse.ws.notification.impl.SimpleSubscriptionManager</java-capability-class>
+ <init-param>
+ <param-name>trace-notifications</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.lifetime.impl.SimpleImmediateTermination</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.lifetime.impl.SimpleScheduledTermination</java-capability-class>
+ </capability>
+ <init-param>
+ <param-name>validate-wsrp-schema</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ </resource-type>
+ <resource-type use-router-persistence="true">
+ <context-path>adapter</context-path>
+ <wsdl>
+ <wsdl-file>wsdl/QManAdapter.wsdl</wsdl-file>
+ <wsdl-port-type xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:QManAdapterPortType</wsdl-port-type>
+ </wsdl>
+ <java-id-factory-class>org.apache.qpid.management.wsdm.common.QManResourceIdFactory</java-id-factory-class>
+ <java-resource-class>org.apache.muse.ws.resource.impl.SimpleWsResource</java-resource-class>
+ <capability>
+ <capability-uri >http://amqp.apache.org/qpid/management/qman</capability-uri>
+ <java-capability-class>org.apache.qpid.management.wsdm.capabilities.QManAdapterCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</capability-uri>
+ <java-capability-class>org.apache.muse.ws.metadata.impl.SimpleMetadataExchange</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Get</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.get.impl.SimpleGetCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Query</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.query.impl.SimpleQueryCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/sgw-2/ServiceGroup</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.sg.impl.SimpleServiceGroup</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsn/bw-2/NotificationProducer</capability-uri>
+ <java-capability-class>org.apache.muse.ws.notification.impl.SimpleNotificationProducer</java-capability-class>
+ </capability>
+ <init-param>
+ <param-name>validate-wsrp-schema</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ </resource-type>
+ <resource-type>
+ <context-path>QManWsResource</context-path>
+ <wsdl>
+ <!-- Note that this is not a complete WSDL. It is just a base template where resource specific capabilities wll be added. -->
+ <wsdl-file>wsdl/QManWsResource.wsdl</wsdl-file>
+ <wsdl-port-type xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:QManWsResourcePortType</wsdl-port-type>
+ </wsdl>
+ <java-id-factory-class>org.apache.qpid.management.wsdm.common.ObjectNameIdFactory</java-id-factory-class>
+ <java-resource-class>org.apache.qpid.management.wsdm.muse.resources.QManWsResource</java-resource-class>
+ <capability>
+ <capability-uri>http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</capability-uri>
+ <java-capability-class>org.apache.qpid.management.wsdm.capabilities.QManMetadataExchangeCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Get</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.get.impl.SimpleGetCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Query</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.query.impl.SimpleQueryCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Set</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.set.impl.SimpleSetCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Put</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.set.impl.SimpleSetCapability</java-capability-class>
+ </capability>
+ </resource-type>
+ <resource-type>
+ <context-path>ServiceGroupEntry</context-path>
+ <wsdl>
+ <wsdl-file>/wsdl/WS-ServiceGroupEntry-1_2.wsdl</wsdl-file>
+ <wsdl-port-type>wsrf-sgw:ServiceGroupEntryPortType</wsdl-port-type>
+ </wsdl>
+ <java-id-factory-class>org.apache.qpid.management.wsdm.common.QManResourceIdFactory</java-id-factory-class>
+ <java-resource-class>org.apache.muse.ws.resource.impl.SimpleWsResource</java-resource-class>
+ <capability>
+ <capability-uri>http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</capability-uri>
+ <java-capability-class>org.apache.muse.ws.metadata.impl.SimpleMetadataExchange</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Get</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.get.impl.SimpleGetCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/sgw-2/ServiceGroupEntry</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.sg.impl.SimpleEntry</java-capability-class>
+ </capability>
+ <init-param>
+ <param-name>validate-wsrp-schema</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ </resource-type>
+</muse>
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java
new file mode 100644
index 0000000000..4f84128fb3
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java
@@ -0,0 +1,175 @@
+/*
+*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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;
+
+/**
+ * Enumerative interfaces containing all QMan messages.
+ *
+ * @author Andrea Gazzarini
+ */
+public interface Messages
+{
+ // MESSAGES
+ String EVENT_SEVERITY_ATTRIBUTE_DESCRIPTION = "Severity level for this event.";
+ String EVENT_TIMESTAMP_ATTRIBUTE_DESCRIPTION = "Current timestamp of this event.";
+ String ACTION_NOT_SUPPORTED="Action %s not supported by resource %s.";
+
+ // INFO
+ String QMAN_000001_STARTING_QMAN = "<QMAN-000001> : Starting Q-Man...";
+ String QMAN_000002_READING_CONFIGURATION = "<QMAN-000002> : Reading Q-Man configuration...";
+ String QMAN_000003_CREATING_MANAGEMENT_CLIENTS = "<QMAN-000003> : Creating management client(s)...";
+ String QMAN_000004_MANAGEMENT_CLIENT_CONNECTED = "<QMAN-000004> : Management client for broker %s successfully connected.";
+ String QMAN_000005_TYPE_MAPPING_CONFIGURED = "<QMAN-000005> : Type mapping : code = %s associated to %s (validator class is %s)";
+ String QMAN_000006_ACCESS_MODE_MAPPING_CONFIGURED = "<QMAN-000006> : Access Mode mapping : code = %s associated to %s";
+ String QMAN_000007_MANAGEMENT_HANDLER_MAPPING_CONFIGURED = "<QMAN-000007> : Management Queue Message Handler Mapping : opcode = %s associated with %s";
+ String QMAN_000008_METHOD_REPLY_HANDLER_MAPPING_CONFIGURED = "<QMAN-000008> : Method-Reply Queue Message Handler Mapping : opcode = %s associated with %s";
+ String QMAN_000009_BROKER_DATA_CONFIGURED = "<QMAN-000009> : Broker configuration %s: %s";
+ String QMAN_000010_INCOMING_SCHEMA = "<QMAN-000010> : Incoming schema for %s::%s.%s";
+ String QMAN_000011_SHUTDOWN_INITIATED = "<QMAN-000011> : The shutdown sequence has been initiated for management client connected with broker %s";
+ String QMAN_000012_MANAGEMENT_CLIENT_SHUT_DOWN = "<QMAN-000012> : Management client connected with broker %s shut down successfully.";
+ String QMAN_000013_METHOD_REPLY_CONSUMER_INSTALLED = "<QMAN-000013> : Method-reply queue consumer has been successfully installed and bound on broker %s.";
+ String QMAN_000014_MANAGEMENT_CONSUMER_INSTALLED ="<QMAN-000014> : Management queue consumer has been successfully installed and bound on broker %s.";
+ String QMAN_000015_MANAGEMENT_QUEUE_DECLARED = "<QMAN-000015> : Management queue with name %s has been successfully declared and bound on broker %s.";
+ String QMAN_000016_METHOD_REPLY_QUEUE_DECLARED = "<QMAN-000016> : Method-reply queue with name %s has been successfully declared and bound on broker %s.";
+ String QMAN_000017_CONSUMER_HAS_BEEN_REMOVED = "<QMAN-000017> : Consumer %s has been removed from broker %s.";
+ String QMAN_000018_QUEUE_UNDECLARED = "<QMAN-000018> : Queue %s has been removed from broker %s.";
+ String QMAN_000019_QMAN_STARTED = "<QMAN-000019> : Q-Man open for e-business.";
+ String QMAN_000020_SHUTTING_DOWN_QMAN = "<QMAN-000020> : Shutting down Q-Man...";
+ String QMAN_000021_SHUT_DOWN = "<QMAN-000021> : Q-Man shut down.";
+ String QMAN_000022_NO_BROKER_CONFIGURED = "<QMAN-000022> : Q-Man has no configured broker : in order to connect with a running one use Q-Man Administration interface.";
+ String QMAN_000023_QMAN_REGISTERED_AS_MBEAN = "<QMAN-000023> : Q-Man service is now available on MBeanServer.";
+
+ String QMAN_000026_WSDM_ADAPTER_STARTS = "<QMAN-000026> : Initializing WS-DM Adapter Environment...";
+ String QMAN_000027_WSDM_ADAPTER_STARTED = "<QMAN-000027> : WS-DM Adapter ready for incoming requests.";
+ String QMAN_000028_TEST_MODULE_NOT_FOUND = "<QMAN-000028> : Qpid emulator not found. Test notifications are disabled.";
+ String QMAN_000029_DEFAULT_URI = "<QMAN-000029> : Default URI will be set to %s";
+ String QMAN_000030_RESOURCE_HAS_BEEN_CREATED = "<QMAN-000030> : New resource instance has been created and registered. Resource id is %s";
+ String QMAN_000031_RESOURCE_HAS_BEEN_REMOVED = "<QMAN-000031> : WS-Resource %s has been removed";
+ String QMAN_000032_EVENTS_LIFECYCLE_TOPIC_HAS_BEEN_CREATED = "<QMAN-000032> : Events lifecycle topic has been created with name %s";
+ String QMAN_000033_OBJECTS_LIFECYCLE_TOPIC_HAS_BEEN_CREATED = "<QMAN-000033> : Objects lifecycle topic has been created with name %s";
+ String QMAN_000034_UNCLASSIFIED_LIFECYCLE_TOPIC_HAS_BEEN_CREATED = "<QMAN-000034> : Unclassified object types lifecycle topic has been created with name %s";
+ String QMAN_000035_WORK_MANAGER_POOL_SIZE = "<QMAN-000035> : Work Manager thread pool size : %s";
+ String QMAN_000036_WORK_MANAGER_MAX_POOL_SIZE = "<QMAN-000036> : Work Manager thread pool max size : %s";
+ String QMAN_000037_WORK_MANAGER_KEEP_ALIVE_TIME = "<QMAN-000035> : Work Manager keep alive time : %s";
+
+ // DEBUG
+ String QMAN_200001_INCOMING_MESSAGE_HAS_BEEN_RECEIVED = "<QMAN-200001> : New incoming message has been received. Message content is %s";
+ String QMAN_200002_OPCODE_HANDLER_ASSOCIATION = "<QMAN-200002> : \"%s\" opcode is associated to handler %s";
+ String QMAN_200003_MESSAGE_FORWARDING = "<QMAN-200003> : Incoming message with \"%s\" as opcode will be forwarded to %s for processing.";
+ String QMAN_200004_MANAGEMENT_QUEUE_NAME = "<QMAN-200004> : Management queue name : %s";
+ String QMAN_200005_METHOD_REPLY_QUEUE_NAME = "<QMAN-200005> : Method-reply queue name : %s";
+ String QMAN_200006_QPID_CONNECTION_RELEASED = "<QMAN-200006> : Connection %s returned to the pool.";
+ String QMAN_200007_TEST_CONNECTION_ON_RESERVE = "<QMAN-200007> : Test connection on reserve. Is valid? %s";
+ String QMAN_200008_CONNECTION_DESTROYED = "<QMAN-200008> : Connection has been destroyed.";
+ String QMAN_200009_CONNECTION_DESTROY_FAILURE = "<QMAN-200009> : Unable to destroy a connection object.";
+ String QMAN_200010_EVENT_MBEAN_REGISTERED = "<QMAN-200010> : Event instance %s::%s::%s successfully registered with MBean Server with name %s";
+ String QMAN_200011_OBJECT_MBEAN_REGISTERED = "<QMAN-200011> : Object instance %s::%s::%s:%s successfully registered with MBean Server with name %s";
+ String QMAN_200012_OBJECT_MBEAN_UNREGISTERED = "<QMAN-200012> : Object instance %s::%s::%s:%s successfully unregistered from MBean Server. Name was %s";
+ String QMAN_200013_ARGUMENT_VALUE_ENCODED = "<QMAN-200013> : Encoded value %S for argument %s. Type is %s";
+ String QMAN_200014_INCOMING_INSTRUMENTATION_DATA = "<QMAN-200014> : Incoming instrumentation data for %s::%s.%s.%s";
+ String QMAN_200015_INCOMING_CONFIGURATION_DATA = "<QMAN-200015> : Incoming configuration data for %s::%s.%s.%s";
+ String QMAN_200016_PROPERTY_DEFINITION_HAS_BEEN_BUILT = "<QMAN-200016> : Property definition for %s::%s.%s has been built.";
+ String QMAN_200017_STATISTIC_DEFINITION_HAS_BEEN_BUILT = "<QMAN-200017> : Statistic definition for %s::%s.%s has been built.";
+ String QMAN_200018_OPTIONAL_PROPERTIES_INFO = "<QMAN-200018> : Class %s::%s.%s has %s optional properties.";
+ String QMAN_200019_EVENT_ARGUMENT_DEFINITION_HAS_BEEN_BUILT = "<QMAN-200019> : Event argument definition for %s::%s.%s has been built.";
+ String QMAN_200020_ENTITY_DEFINITION_HAS_BEEN_BUILT = "<QMAN-200020> : Entity definition has been built (without schema) for %s::%s.%s";
+ String QMAN_200021_INCOMING_EVENT_DATA = "<QMAN-200021> : Incoming data for event %s::%s.%s";
+ String QMAN_200022_VALIDATOR_INSTALLED = "<QMAN-200022> : Validator %s for type %s successfully installed.";
+ String QMAN_200023_VALIDATOR_NOT_FOUND = "<QMAN-200023> : No validator was found for type %s. The default (empty) validator will be used.";
+ String QMAN_200024_MANAGEMENT_MESSAGE_HAS_BEEN_SENT = "<QMAN-200024> : Message has been sent to management exchange. Message content : %s";
+ String QMAN_200025_SUBSCRIPTION_DECLARED = "<QMAN-200025> : New subscription between queue %s and destination %s has been declared.";
+ String QMAN_200026_SUBSCRIPTION_REMOVED = "<QMAN-200026> : Subscription named %s has been removed from remote broker.";
+ String QMAN_200027_QUEUE_DECLARED = "<QMAN-200027> : New queue with name %s has been declared.";
+ String QMAN_200028_QUEUE_REMOVED= "<QMAN-200028> : New queue with name %s has been undeclared.";
+ String QMAN_200029_BINDING_DECLARED = "<QMAN-200029> : New binding with %s as routing key has been declared between queue %s and exchange %s.";
+ String QMAN_200030_BINDING_REMOVED = "<QMAN-200030> : Binding with %s as routing key has been removed between queue %s and exchange %s.";
+ String QMAN_200031_COMPOUND_MESSAGE_CONTAINS = "<QMAN-200031> : Incoming compound message contains %s message(s).";
+ String QMAN_200032_COMMAND_MESSAGE_ROUTING_KEY = "<QMAN-200032> : Command message routing key : %s";
+ String QMAN_200033_CAPABILITY_CLASS_HAS_BEEN_ADDED = "<QMAN-200033> : Capability has been added to this resource. Class is %s while URI is %s.";
+ String QMAN_200034_RMD_NAME = "<QMAN-200034> : Resource Metadata Descriptor name is %s.";
+ String QMAN_200035_RMD_PATH = "<QMAN-200035> : Resource Metadata Descriptor path is %s.";
+ String QMAN_200036_ADDITIONAL_RMD_PROPERTY = "<QMAN-200036> : Additional RMD property : %s";
+ String QMAN_200037_RMD = "<QMAN-200037> : Resource Metadata Descriptor : %s";
+ String QMAN_200038_WSRP = "<QMAN-200038> : WS Resource Properties fragment : %s";
+ String QMAN_200039_DEBUG_JMX_NOTIFICATION = "<QMAN-200039> : %s";
+ String QMAN_200040_WS_ARTIFACTS_CACHED = "<QMAN-200040> : WS Artifacts has been stored on cache with the following id : %s";
+ String QMAN_200041_INCOMING_OBJECT_NAME_AND_DERIVED_KEY = "<QMAN-200041> : Incoming object name : %s, derived search key : %s";
+ String QMAN_200042_REMOVING_RESOURCE = "<QMAN-200042> : WS-Resource %s is going to be removed";
+ String QMAN_200043_GENERATED_ACCESSOR_METHOD = "<QMAN-200043> : Generated accessor method for %s : %s";
+ String QMAN_200044_GENERATED_METHOD = "<QMAN-200044> : Generated method for %s : %s";
+
+ // WARNING
+ String QMAN_300001_MESSAGE_DISCARDED = "<QMAN-300001> : No handler has been configured for processing messages with \"%s\" as opcode. Message will be discarded.";
+ String QMAN_300002_UNKNOWN_SEQUENCE_NUMBER = "<QMAN-300002> : Unable to deal with incoming message because it contains a unknown sequence number (%s).";
+ String QMAN_300003_BROKER_ALREADY_CONNECTED = "<QMAN-300003> : Unable to enlist given broker connection data : QMan is already connected with broker %s";
+ String QMAN_300004_INVALID_CONFIGURATION_FILE = "<QMAN-300004> : The given configuration file (%s) is not valid (it doesn't exist or cannot be read)";
+ String QMAN_300005_QEMU_INITIALIZATION_FAILURE = "<QMAN-300005> : Unable to initialize QEmu module and therefore emulation won't be enabled...";
+
+ String QMAN_300006_OS_MBEAN_FAILURE = "<QMAN-300006> : Unable to retrieve Operating System properties. No values will be displayed for underlying Operation System.";
+ String QMAN_300007_RUNTIME_MBEAN_FAILURE = "<QMAN-300007> : Unable to retrieve Runtime Environment properties. No values will be displayed.";
+
+ // ERROR
+ String QMAN_100001_BAD_MAGIC_NUMBER_FAILURE = "<QMAN-100001> : Message processing failure : incoming message contains a bad magic number (%s) and therefore will be discaded.";
+ String QMAN_100002_MESSAGE_READ_FAILURE = "<QMAN-100002> : Message I/O failure : unable to read byte message content and therefore it will be discarded.";
+ String QMAN_100003_MESSAGE_PROCESS_FAILURE = "<QMAN-100003> : Message processing failure : unknown exception; see logs for more details.";
+ String QMAN_100004_HANDLER_INITIALIZATION_FAILURE = "<QMAN-100004> : Message handler configured for opcode %s thrown an exception in initialization and therefore will be discarded.";
+ String QMAN_100005_CLASS_SCHEMA_PROCESSING_FAILURE = "<QMAN-100005> : Q-Man was unable to process the schema response message.";
+ String QMAN_100006_EVENT_SCHEMA_PROCESSING_FAILURE = "<QMAN-100006> : Q-Man was unable to process the schema response message.";
+ String QMAN_100007_UNABLE_TO_CONNECT_WITH_BROKER = "<QMAN-100007> : Unable to connect with broker located on %s. This broker will be ignored.";
+
+
+ String QMAN_100010_METHOD_INVOCATION_RESULT_FAILURE = "<QMAN-100010> : an exception occurred while storing the result of a method invocation. Sequence number was %s";
+ String QMAN_100011_UNKNOWN_CLASS_KIND = "<QMAN-100011> : Unknwon class kind : %s).";
+ String QMAN_100012_SCHEMA_MESSAGE_PROCESSING_FAILURE = "<QMAN-100012> : Q-Man was unable to process the schema response message.";
+ String QMAN_100013_MBEAN_REGISTRATION_FAILURE = "<QMAN-100013> : Unable to unregister object instance %s.";
+ String QMAN_100014_ATTRIBUTE_DECODING_FAILURE = "<QMAN-100014> : Unable to decode value for attribute %s";
+ String QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST = "<QMAN-100015> : Unable to send a schema request schema for %s.%s";
+ String QMAN_100016_UNABLE_TO_DECODE_FEATURE_VALUE = "<QMAN-100016> : Unable to decode value for %s::%s::%s";
+ String QMAN_100017_UNABLE_TO_CONNECT = "<QMAN-100017>: Cannot connect to broker %s on %s";
+ String QMAN_100018_UNABLE_TO_STARTUP_CORRECTLY = "<QMAN-100018> : Q-Man was unable to startup correctly : see logs for further details.";
+ String QMAN_100019_REQ_OR_RES_MALFORMED = "<QMAN-100019> : Unexpected exception occurred on WSDM adapter layer : probably request or response was malformed.";
+ String QMAN_100020_ACTION_NOT_SUPPORTED = "<QMAN-100020> : "+ACTION_NOT_SUPPORTED;
+ String QMAN_100021_RMD_BUID_FAILURE = "<QMAN-100021> : Unable to build RDM for resource %s.";
+
+ String QMAN_100023_BUILD_WS_ARTIFACTS_FAILURE = "<QMAN-100023> : Unable to build WS artifacts.";
+ String QMAN_100024_CAPABILITY_INSTANTIATION_FAILURE = "<QMAN-100024> : Unable to instantiate generated capability class for %s.";
+ String QMAN_100025_WSRF_FAILURE = "<QMAN-100025> : Resource manager raised an exception while creating capability for %s.";
+ String QMAN_100026_SOAP_ADDRESS_REPLACEMENT_FAILURE = "<QMAN-100026> : Exception occurred while replacing the placeholder soap address with resource actual location.";
+ String QMAN_100027_RESOURCE_SHUTDOWN_FAILURE = "<QMAN-100027> : Shutdown failure while destroying resource %s.";
+ String QMAN_100029_MALFORMED_RESOURCE_URI_FAILURE = "<QMAN-100029> : Unable to define URI for QMan resources using \"%s\". It violates RFC 2396";
+ String QMAN_100030_JMX_CORE_STARTUP_FAILURE = "<QMAN-100030> : QMan JMX core Unexpected failure while starting up.";
+ String QMAN_100031_WS_RESOURCE_ALREADY_INITIALIZED = "<QMAN-100031> : Bad request has been received on this WS-Resource : Initialization is not possible because the resource has already been initialized.";
+ String QMAN_100032_WS_RESOURCE_NOT_YET_INITIALIZED = "<QMAN-100032> : Bad request has been received on this WS-Resource : Shutdown is not possible because the resource hasn't yet been initialized.";
+ String QMAN_100033_WS_RESOURCE_ALREADY_SHUTDOWN = "<QMAN-100033> : Bad request has been received on this WS-Resource : Shutdown is not possible because the resource has already been shutdown.";
+ String QMAN_100034_WSDL_SCHEMA_SECTION_NOT_FOUND = "<QMAN-100034> : Unable to get via XPath the schema section in WSDL.";
+ String QMAN_100035_RESOURCE_CAPABILITY_INVOCATION_FAILURE = "<QMAN-100035> : Resource thrown a failure while invoking a capability operation.";
+ String QMAN_100036_TOPIC_DECLARATION_FAILURE = "<QMAN-100036> : WS-DM Adapter was unable to declare events and / or objects lifecycle topic(s). As conseguence of that, QMan won't be able to correctly emit lifecycle notifications.";
+
+ // NEW
+ String QMAN_100035_GET_ATTRIBUTE_FAILURE = "<QMAN-100035> : Get Attribute invocation failure for attribute %s, resource %s.";
+ String QMAN_100036_SET_ATTRIBUTE_FAILURE = "<QMAN-100036> : Set Attribute invocation failure for attribute %s, resource %s.";
+ String QMAN_100037_INVOKE_OPERATION_FAILURE = "<QMAN-100037> : Operation Invocation failure for operation.";
+ String QMAN_100038_UNABLE_TO_SEND_WS_NOTIFICATION = "<QMAN-100038> : Unable to send notification.";
+ String QMAN_100039_UNABLE_TO_CONFIGURE_PROPERLY_WORKER_MANAGER = "<QMAN-100039> : Unable to properly configure WorkManager. A malformed property (NaN) was given as input parameter.";
+ String QMAN_100040_UNABLE_TO_LOCATE_WSRP_PROPERTIES = "<QMAN-100040> : Unable to evaluate the WSRP XPath expression on resource WSDL.";
+
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java
new file mode 100644
index 0000000000..b60867d9ff
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java
@@ -0,0 +1,216 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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;
+
+import javax.management.ObjectName;
+import javax.xml.namespace.QName;
+
+/**
+ * Enumeration of literal strings to avoid code duplication.
+ */
+public abstract class Names
+{
+ public static final String MANAGEMENT_EXCHANGE = "qpid.management";
+ public static final String MANAGEMENT_ROUTING_KEY = "console.#";
+
+ public static final String MANAGEMENT_QUEUE_PREFIX = "management.";
+ public static final String METHOD_REPLY_QUEUE_PREFIX = "reply.";
+
+ public static final String AMQ_DIRECT_QUEUE = "amq.direct";
+ public static final String AGENT_ROUTING_KEY_PREFIX = "agent.";
+ public static final String AGENT_ROUTING_KEY = AGENT_ROUTING_KEY_PREFIX+"1.0";
+
+ public static final String APPLICATION_NAME ="Q-Man";
+
+ // Attributes
+ public static final String PACKAGE = "package";
+ public static final String CLASS = "class";
+ public static final String EVENT = "event";
+ public static final String OBJECT_ID="objectId";
+ public static final String BROKER_ID = "brokerId";
+ public static final String DOMAIN_NAME = "Q-MAN";
+
+ public static final String ARG_COUNT_PARAM_NAME = "argCount";
+ public static final String DEFAULT_PARAM_NAME ="default";
+
+ public static final String NUMBER_VALIDATOR = "org.apache.qpid.management.domain.model.QpidProperty$NumberValidator";
+ public static final String STRING_VALIDATOR = "org.apache.qpid.management.domain.model.QpidProperty$StringValidator";
+
+ public static final String QMAN_CONFIG_OPTION_NAME = "qman-config";
+
+ public static final String ADD_BROKER_OPERATION_NAME = "addBroker";
+
+ public static final String NOT_AVAILABLE = "N.A.";
+
+ public static final ObjectName QPID_EMULATOR_OBJECT_NAME;
+ static
+ {
+ try
+ {
+ QPID_EMULATOR_OBJECT_NAME = new ObjectName(
+ new StringBuilder()
+ .append(DOMAIN_NAME)
+ .append(':')
+ .append("Name=Qpid,Type=Emulator")
+ .toString());
+ } catch(Exception exception)
+ {
+ throw new ExceptionInInitializerError(exception);
+ }
+ }
+
+ public static final ObjectName QMAN_OBJECT_NAME;
+ static
+ {
+ try
+ {
+ QMAN_OBJECT_NAME = new ObjectName(
+ new StringBuilder()
+ .append(DOMAIN_NAME)
+ .append(':')
+ .append("Name=QMan,Type=Service")
+ .toString());
+ } catch(Exception exception)
+ {
+ throw new ExceptionInInitializerError(exception);
+ }
+ }
+
+ // WSDM Stuff
+ public static final String NAMESPACE_URI = "http://amqp.apache.org/qpid/management/qman";
+ public final static String PREFIX = "qman";
+
+ public static final String ADDRESSING_URI = "http://amqp.apache.org/qpid/management/qman/addressing";
+ public static final String ADDRESSING_PREFIX = "qman-wsa";
+
+ public static final QName RESOURCE_ID_QNAME = new QName(
+ ADDRESSING_URI,
+ "ResourceId",
+ ADDRESSING_PREFIX);
+
+ public static final QName RES_ID_QNAME = new QName(
+ NAMESPACE_URI,
+ "ResourceId",
+ PREFIX);
+
+ public static final QName RESOURCE_QNAME = new QName(
+ NAMESPACE_URI,
+ "Resource",
+ PREFIX);
+
+ public static final QName LIFECYCLE_EVENT_QNAME = new QName(
+ NAMESPACE_URI,
+ "LifeCycleEvent",
+ PREFIX);
+
+ public static final QName PACKAGE_NAME_QNAME = new QName(
+ NAMESPACE_URI,
+ "PackageName",
+ PREFIX);
+
+ public static final QName ENTITY_NAME_QNAME = new QName(
+ NAMESPACE_URI,
+ "Name",
+ PREFIX);
+
+ public static final String TIMEMILLIS_ATTRIBUTE_NAME="TimeMillis";
+
+ public final static String QMAN_RESOURCE_NAME = "QManWsResource";
+
+ public final static String VALIDATE_WSRP_PARAM = "validate-wsrp-schema";
+
+ public static final String WEB_APP_CLASSES_FOLDER = "/WEB-INF/classes";
+
+
+ public final static QName QMAN_RESOURCE_PORT_TYPE_NAME = new QName(
+ Names.NAMESPACE_URI,
+ "QManWsResourcePortType",
+ Names.PREFIX);
+
+ public final static QName QMAN_STATUS_TEXT_NAME = new QName(
+ Names.NAMESPACE_URI,
+ "Message",
+ Names.PREFIX);
+
+ public final static QName QMAN_STATUS_CODE_NAME = new QName(
+ Names.NAMESPACE_URI,
+ "ReturnCode",
+ Names.PREFIX);
+
+ public final static QName QMAN_STATUS_ATTRIBUTE_NAME= new QName(
+ Names.NAMESPACE_URI,
+ "AttributeName",
+ Names.PREFIX);
+
+ public final static QName OBJECTS_LIFECYLE_TOPIC_NAME= new QName(
+ Names.NAMESPACE_URI,
+ "ObjectsLifeCycleTopic",
+ Names.PREFIX);
+
+ public final static QName EVENTS_LIFECYLE_TOPIC_NAME= new QName(
+ Names.NAMESPACE_URI,
+ "EventsLifeCycleTopic",
+ Names.PREFIX);
+
+ public final static QName HOST_QNAME = new QName(
+ Names.NAMESPACE_URI,
+ "host",
+ Names.PREFIX);
+
+ public final static QName PORT_QNAME = new QName(
+ Names.NAMESPACE_URI,
+ "port",
+ Names.PREFIX);
+
+ public final static QName USERNAME_QNAME= new QName(
+ Names.NAMESPACE_URI,
+ "username",
+ Names.PREFIX);
+
+ public final static QName VIRTUAL_HOST_QNAME= new QName(
+ Names.NAMESPACE_URI,
+ "virtualHost",
+ Names.PREFIX);
+
+ public final static QName UNKNOWN_OBJECT_TYPE_LIFECYLE_TOPIC_NAME= new QName(
+ Names.NAMESPACE_URI,
+ "UnclassifiedLifeCycleTopic",
+ Names.PREFIX);
+
+
+ public final static String NAME_ATTRIBUTE = "name";
+ public final static String MODIFIABILITY = "modifiability";
+ public final static String READ_WRITE = "read-write";
+ public final static String READ_ONLY = "read-only";
+ public final static String MUTABILITY = "mutability";
+ public final static String MUTABLE = "mutable";
+
+ public final static String ENTRY = "entry";
+ public final static String KEY = "key";
+ public final static String VALUE = "value";
+ public final static String TYPE = "type";
+ public final static String XSI_TYPE = "xsi:"+TYPE;
+
+ public final static String ADAPTER_HOST_PROPERTY_NAME = "qman.host";
+ public final static String ADAPTER_PORT_PROPERTY_NAME = "qman.port";
+
+
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java
new file mode 100644
index 0000000000..c1b1ceb5b4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.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.management;
+
+/**
+ * Protocol defined constants.
+ *
+ * @author Andrea Gazzarini
+ */
+public interface Protocol
+{
+ String MAGIC_NUMBER = "AM2";
+
+ char SCHEMA_REQUEST_OPCODE = 'S';
+ char SCHEMA_RESPONSE_OPCODE = Character.toLowerCase(SCHEMA_REQUEST_OPCODE);
+
+ char OPERATION_INVOCATION_REQUEST_OPCODE = 'M';
+ char OPERATION_INVOCATION_RESPONSE_OPCODE = Character.toLowerCase(OPERATION_INVOCATION_REQUEST_OPCODE);
+
+ char INSTRUMENTATION_CONTENT_RESPONSE_OPCODE = 'i';
+ char CONFIGURATION_CONTENT_RESPONSE_OPCDE = 'c';
+ char EVENT_CONTENT_RESPONSE_OPCDE = 'e';
+ char INSTR_AND_CONFIG_CONTENT_RESPONSE_OPCODE = 'g';
+
+ char HEARTBEAT_INDICATION_RESPONSE_OPCODE = 'h';
+
+ int CLASS = 1;
+ int EVENT = 2;
+
+ String DEFAULT_QMAN_HOSTNAME = "localhost";
+ int DEFAULT_QMAN_PORT_NUMBER = 8080;
+
+ String DEFAULT_ENDPOINT_URI = "http://localhost:8080/qman/services/adapter";
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerAlreadyConnectedException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerAlreadyConnectedException.java
new file mode 100644
index 0000000000..f23bf9d25e
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerAlreadyConnectedException.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.management.configuration;
+
+/**
+ * Thrown when an attempt is made in order to connect QMan with an already connected broker.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BrokerAlreadyConnectedException extends Exception {
+
+ private static final long serialVersionUID = -5082431738056504669L;
+
+ private BrokerConnectionData _connectionData;
+
+ /**
+ * Builds a new exception with the given data.
+ *
+ * @param connectionData the broker connection data.
+ */
+ public BrokerAlreadyConnectedException(BrokerConnectionData connectionData) {
+ this._connectionData = connectionData;
+ }
+
+ /**
+ * Returns the connection data of the connected broker.
+ *
+ * @return the connection data of the connected broker.
+ */
+ public BrokerConnectionData getBrokerConnectionData()
+ {
+ return _connectionData;
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java
new file mode 100644
index 0000000000..a64659b17c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java
@@ -0,0 +1,280 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.configuration;
+
+/**
+ * Value object which is holding connection data for a specific broker.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BrokerConnectionData
+{
+ private String _host;
+ private int _port;
+ private String _virtualHost;
+ private String _username;
+ private String _password;
+ private int _maxPoolCapacity;
+ private int _initialPoolCapacity;
+ private long _maxWaitTimeout;
+
+ /**
+ * Builds a connection data with the given parameters.
+ *
+ * @param host the hostname where the broker is running.
+ * @param port the port where the broker is running.
+ * @param username the username for connecting with the broker.
+ * @param password the password for connecting with the broker.
+ * @param virtualHost the virtual host.
+ * @param initialPoolCapacity the number of connections that must be immediately opened.
+ * @param maxPoolCapacity the maximum number of opened connection.
+ * @param maxWaitTimeout the maximum amount of time that a client will wait for obtaining a connection.
+ */
+ public BrokerConnectionData(
+ String host,
+ int port,
+ String virtualHost,
+ String username,
+ String password,
+ int initialPoolCapacity,
+ int maxPoolCapacity,
+ long waitTimeout) {
+
+ this._host = host;
+ this._port = port;
+ this._virtualHost = virtualHost;
+ this._username = username;
+ this._password = password;
+ _maxPoolCapacity = maxPoolCapacity;
+ _initialPoolCapacity = initialPoolCapacity;
+ _maxWaitTimeout = waitTimeout;
+ }
+
+ /**
+ * Builds a new empty broker connection data object.
+ */
+ BrokerConnectionData()
+ {
+ }
+
+ /**
+ * Sets the value of host property for this connection data.
+ *
+ * @param host the host name.
+ */
+ void setHost (String host)
+ {
+ this._host = host;
+ }
+
+ /**
+ * Sets the value of port property for this connection data.
+ *
+ * @param port the port.
+ */
+ void setPort (String port)
+ {
+ this._port = Integer.parseInt(port);
+ }
+
+ /**
+ * Sets the value of virtual host property for this connection data.
+ *
+ * @param virtualHost the virtual host.
+ */
+ void setVirtualHost (String virtualHost)
+ {
+ this._virtualHost = virtualHost;
+ }
+
+ /**
+ * Sets the value of username property for this connection data.
+ *
+ * @param username the username.
+ */
+ void setUsername(String username)
+ {
+ this._username = username;
+ }
+
+ /**
+ * Sets the value of password property for this connection data.
+ *
+ * @param password the password.
+ */
+ void setPassword(String password)
+ {
+ this._password = password;
+ }
+
+ /**
+ * Returns the value of the host property.
+ *
+ * @return the value of the host property.
+ */
+ public String getHost ()
+ {
+ return _host;
+ }
+
+ /**
+ * Returns the value of the port property.
+ *
+ * @return the value of the port property.
+ */
+ public int getPort ()
+ {
+ return _port;
+ }
+
+ /**
+ * Returns the value of the virtual host property.
+ *
+ * @return the value of the virtual host property.
+ */
+ public String getVirtualHost ()
+ {
+ return _virtualHost;
+ }
+
+ /**
+ * Returns the value of the username property.
+ *
+ * @return the value of the username property.
+ */
+ public String getUsername ()
+ {
+ return _username;
+ }
+
+ /**
+ * Returns the value of the password property.
+ *
+ * @return the value of the password property.
+ */
+ public String getPassword ()
+ {
+ return _password;
+ }
+
+ // sofia:5663@pippo/sung1
+ @Override
+ public String toString ()
+ {
+ return new StringBuilder()
+ .append(_host)
+ .append(':')
+ .append(_port)
+ .append('@')
+ .append(_virtualHost)
+ .toString();
+ }
+
+ /**
+ * Sets the max number of allowed connections that can be opened.
+ *
+ * @param value the max number of allowed connections that can be opened.
+ * @throws NumberFormatException if the given value is not a valid integer.
+ */
+ public void setMaxPoolCapacity (String value)
+ {
+ _maxPoolCapacity = Integer.parseInt(value);
+ }
+
+ /**
+ * Sets the max wait timeout for retrieving an available connections from the pool.
+ *
+ * @param value the max wait timeout for retrieving an available connections from the pool..
+ * @throws NumberFormatException if the given value is not a valid long.
+ */
+ public void setMaxWaitTimeout (String value)
+ {
+ this._maxWaitTimeout = Long.parseLong(value);
+ }
+
+ /**
+ * Returns the max number of allowed connections that can be opened.
+ *
+ * @return the max number of allowed connections that can be opened.
+ */
+ public int getMaxPoolCapacity ()
+ {
+ return _maxPoolCapacity;
+ }
+
+ /**
+ * Returns the max wait timeout for retrieving an available connections from the pool.
+ *
+ * @return the max wait timeout for retrieving an available connections from the pool.
+ */
+ public long getMaxWaitTimeout ()
+ {
+ return _maxWaitTimeout;
+ }
+
+ /**
+ * Sets the initial connection pool capacity.
+ *
+ * @param capacity the initial connection pool capacity.
+ */
+ public void setInitialPoolCapacity (String capacity)
+ {
+ _initialPoolCapacity = Integer.parseInt(capacity);
+ }
+
+ /**
+ * Returns the initial connection pool capacity.
+ *
+ * @return the initial connection pool capacity.
+ */
+ public int getInitialPoolCapacity ()
+ {
+ return _initialPoolCapacity;
+ }
+
+ @Override
+ public boolean equals(Object object)
+ {
+ if(object instanceof BrokerConnectionData)
+ {
+ try
+ {
+ BrokerConnectionData connectionData = (BrokerConnectionData) object;
+ return (_host.equals(connectionData._host) )
+ && (_port == connectionData._port)
+ && (_virtualHost.equals(connectionData._virtualHost));
+ }
+ catch (Exception exception)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return _host.hashCode()+_port+_virtualHost.hashCode();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.java
new file mode 100644
index 0000000000..39981dc7cb
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.java
@@ -0,0 +1,136 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.configuration;
+
+import java.util.UUID;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Parser used for building broker connection data settings.
+ * The corresponding section on the configuration file is :
+ *
+ <broker>
+ <host>192.168.148.131</host>
+ <port>5672</port>
+ <virtual-host>test</virtual-host>
+ <user>guest</user>
+ <password>guest</password>
+ <max-pool-capacity>4</max-pool-capacity>
+ <initial-pool-capacity>4</initial-pool-capacity>
+ <max-wait-timeout>-1</max-wait-timeout>
+ </broker>
+ *
+ * @author Andrea Gazzarini
+ */
+class BrokerConnectionDataParser implements IParser
+{
+ private final static Logger LOGGER = Logger.get(Configuration.class);
+ private BrokerConnectionData _connectionData = new BrokerConnectionData();
+ private String _currentValue;
+
+ /**
+ * Callback : the given value is the text content of the current node.
+ */
+ public void setCurrrentAttributeValue (String value)
+ {
+ this._currentValue = value;
+ }
+
+ /**
+ * Callback: each time the end of an element is reached this method is called.
+ * It's here that the built mapping is injected into the configuration.
+ * <broker>
+ <host>192.168.61.130</host>
+ <port>5673</port>
+ <virtual-host>test</virtual-host>
+ <user>andrea</user>
+ <password>andrea</password>
+ </broker>
+ */
+ public void setCurrentAttributeName (String name)
+ {
+ switch (Tag.get(name))
+ {
+ case HOST:
+ {
+ _connectionData.setHost(_currentValue);
+ break;
+ }
+ case PORT :
+ {
+ _connectionData.setPort(_currentValue);
+ break;
+ }
+ case VIRTUAL_HOST:
+ {
+ _connectionData.setVirtualHost(_currentValue);
+ break;
+ }
+ case USER :
+ {
+ _connectionData.setUsername(_currentValue);
+ break;
+ }
+ case MAX_POOL_CAPACITY:
+ {
+ _connectionData.setMaxPoolCapacity (_currentValue);
+ break;
+ }
+ case INITIAL_POOL_CAPACITY:
+ {
+ _connectionData.setInitialPoolCapacity(_currentValue);
+ break;
+ }
+ case MAX_WAIT_TIMEOUT:
+ {
+ _connectionData.setMaxWaitTimeout(_currentValue);
+ break;
+ }
+ case PASSWORD:
+ {
+ _connectionData.setPassword(_currentValue);
+ break;
+ }
+ case BROKER:
+ {
+ try
+ {
+ Configuration.getInstance().addBrokerConnectionData(getUUId(),_connectionData);
+ } catch(Exception exception)
+ {
+ LOGGER.error(exception, Messages.QMAN_100007_UNABLE_TO_CONNECT_WITH_BROKER, _connectionData);
+ }
+ _connectionData = new BrokerConnectionData();
+ break;
+ }
+ }
+ }
+
+ /**
+ * Gets an uuid in order to associate current connection data with a broker.
+ * @return
+ */
+ UUID getUUId(){
+ return UUID.randomUUID();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionException.java
new file mode 100644
index 0000000000..9294cf740e
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionException.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.management.configuration;
+
+/**
+ * Thrown when a connection to a broker cannot be estabilished.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BrokerConnectionException extends Exception
+{
+ private static final long serialVersionUID = 8170112238862494025L;
+
+ /**
+ * Builds a new exception with the given cause.
+ *
+ * @param cause the exception cause.
+ */
+ BrokerConnectionException(Throwable cause)
+ {
+ super(cause);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java
new file mode 100644
index 0000000000..ab90ec294b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java
@@ -0,0 +1,485 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.Map.Entry;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.handler.base.IMessageHandler;
+import org.apache.qpid.management.domain.model.AccessMode;
+import org.apache.qpid.management.domain.model.type.AbsTime;
+import org.apache.qpid.management.domain.model.type.DeltaTime;
+import org.apache.qpid.management.domain.model.type.ObjectReference;
+import org.apache.qpid.management.domain.model.type.Str16;
+import org.apache.qpid.management.domain.model.type.Str8;
+import org.apache.qpid.management.domain.model.type.Type;
+import org.apache.qpid.management.domain.model.type.Uint16;
+import org.apache.qpid.management.domain.model.type.Uint32;
+import org.apache.qpid.management.domain.model.type.Uint64;
+import org.apache.qpid.management.domain.model.type.Uint8;
+import org.apache.qpid.transport.DeliveryProperties;
+import org.apache.qpid.transport.Header;
+import org.apache.qpid.transport.MessageProperties;
+import org.apache.qpid.transport.ReplyTo;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Qpid Management bridge configuration.
+ * Basically iy is a singleton that is holding all the configurtion data loaded at startup.
+ */
+public final class Configuration
+{
+ private final static Logger LOGGER = Logger.get(Configuration.class);
+ private static Configuration INSTANCE = new Configuration();
+
+ // Work Manager default settings
+ private int _poolSize = 5;
+ private int _maxPoolSize = 15;
+ private long _keepAliveTime = 5000;
+
+ Map<Integer, Type> _typeMappings = new HashMap<Integer,Type>();
+ Map<Integer,AccessMode> _accessModes = new HashMap<Integer, AccessMode>();
+ Map<Type,String> _validators = new HashMap<Type, String>();
+
+ Map<UUID,BrokerConnectionData> _brokerConnectionInfos = new HashMap<UUID, BrokerConnectionData>();
+
+ Map<Character, IMessageHandler> _managementQueueHandlers = new HashMap<Character, IMessageHandler>();
+ Map<Character, IMessageHandler> _methodReplyQueueHandlers = new HashMap<Character, IMessageHandler>();
+
+ private String _managementQueueName;
+ private String _methodReplyQueueName;
+
+ private Header _headerForCommandMessages;
+ private DeliveryProperties _deliveryProperties = new DeliveryProperties();
+ private MessageProperties _messageProperties = new MessageProperties();
+
+ // Private constructor.
+ private Configuration()
+ {
+ defineQueueNames();
+
+ createHeaderForCommandMessages();
+
+ addAccessModeMappings();
+
+ addTypeMappings();
+ }
+
+
+ /**
+ * Returns the singleton instance.
+ *
+ * @return the singleton instance.
+ */
+ public static Configuration getInstance ()
+ {
+ return INSTANCE;
+ }
+
+ /**
+ * Returns true if this configuration has at least
+ * one broker configured.
+ *
+ * @return true if this configuration has at least one
+ * broker configured.
+ */
+ public boolean hasOneOrMoreBrokersDefined()
+ {
+ return !_brokerConnectionInfos.isEmpty();
+ }
+
+ /**
+ * Returns the type associated to the given code.
+ *
+ * @param code the code used as search criteria.
+ * @return the type associated to the given code.
+ * @throws UnknownTypeCodeException when the given code is not associated to any type.
+ */
+ public Type getType(int code) throws UnknownTypeCodeException
+ {
+ Type result = _typeMappings.get(code);
+ if (result == null)
+ {
+ throw new UnknownTypeCodeException(code);
+ }
+ return result;
+ }
+
+ /**
+ * Returns the access mode associated to the given code.
+ *
+ * @param code the code used as search criteria.
+ * @return the access mode associated to the given code.
+ * @throws UnknownAccessCodeException when the given code is not associated to any access mode.
+ */
+ public AccessMode getAccessMode(int code) throws UnknownAccessCodeException
+ {
+ AccessMode result = _accessModes.get(code);
+ if (result == null)
+ {
+ throw new UnknownAccessCodeException(code);
+ }
+ return result;
+ }
+
+ /**
+ * Returns the validator class name associated to the given type.
+ *
+ * @param type the type.
+ * @return the validator class name associated to the given type.
+ */
+ public String getValidatorClassName (Type type)
+ {
+ return _validators.get(type);
+ }
+
+ /**
+ * Gets from this configuration the list of known broker (I mean, only their connection data).
+ *
+ * @return the list of known broker
+ */
+ public Set<Entry<UUID, BrokerConnectionData>> getConnectionInfos(){
+ return _brokerConnectionInfos.entrySet();
+ }
+
+ /**
+ * Gets from this configuration the connection data of the broker associated with the given id.
+ *
+ * @param brokerId the broker identifier.
+ * @return the connection data of the broker associated with the given id.
+ * @throws UnknownBrokerException when the given id is not associated with any broker.
+ */
+ public BrokerConnectionData getBrokerConnectionData (UUID brokerId) throws UnknownBrokerException
+ {
+ BrokerConnectionData connectionData = _brokerConnectionInfos.get(brokerId);
+ if (connectionData == null)
+ {
+ throw new UnknownBrokerException(brokerId);
+ }
+ return _brokerConnectionInfos.get(brokerId);
+ }
+
+ /**
+ * Returns the name of the management queue.
+ *
+ * @return the name of the management queue.
+ */
+ public String getManagementQueueName() {
+ return _managementQueueName;
+ }
+
+ /**
+ * Returns the name of the method-reply queue.
+ *
+ * @return the name of the method-reply queue.
+ */
+ public String getMethodReplyQueueName() {
+ return _methodReplyQueueName;
+ }
+
+ /**
+ * Returns a map containing all the configured management message handlers.
+ * A management message handler it is a basically a processor for a management queue incoming message associated
+ * with a specific opcode.
+ *
+ * @return a map containing all the configured management message handlers.
+ */
+ public Map<Character, IMessageHandler> getManagementQueueHandlers()
+ {
+ return _managementQueueHandlers;
+ }
+
+ /**
+ * Returns a map containing all the configured method-reply message handlers.
+ * A management message handler it is a basically a processor for a method-reply queue incoming message associated
+ * with a specific opcode.
+ *
+ * @return a map containing all the configured method-reply message handlers.
+ */
+ public Map<Character, IMessageHandler> getMethodReplyQueueHandlers()
+ {
+ return _methodReplyQueueHandlers;
+ }
+
+ /**
+ * Returns the message header used for sending command message on management queue.
+ *
+ * @return the message header used for sending command message on management queue.
+ */
+ public Header getCommandMessageHeader ()
+ {
+ return _headerForCommandMessages;
+ }
+
+ /**
+ * Returns the command message properties.
+ *
+ * @return the command message properties.
+ */
+ public MessageProperties getCommandMessageProperties ()
+ {
+ return _messageProperties;
+ }
+
+ /**
+ * Returns the command message delivery properties.
+ *
+ * @return the command message delivery properties.
+ */
+ public DeliveryProperties getCommandDeliveryProperties ()
+ {
+ return _deliveryProperties;
+ }
+
+ /**
+ * Adds a new type mapping to this configuration.
+ *
+ * @param code the code that will be associated with the declared type.
+ * @param type the type.
+ * @param vailidatorClassName the FQN of the validator class that will be
+ * associated with the given type.
+ */
+ void addTypeMapping(int code, Type type, String validatorClassName) {
+ _typeMappings.put(code, type);
+ _validators.put(type, validatorClassName);
+
+ LOGGER.info(
+ Messages.QMAN_000005_TYPE_MAPPING_CONFIGURED,
+ code,
+ type,
+ validatorClassName);
+ }
+
+
+ /**
+ * Adds a new type mapping to this configuration.
+ *
+ * @param code the code that will be associated with the declared type.
+ * @param type the type.
+ */
+ void addTypeMapping(int code, Type type) {
+ _typeMappings.put(code, type);
+
+ LOGGER.info(
+ Messages.QMAN_000005_TYPE_MAPPING_CONFIGURED,
+ code,
+ type,
+ "not configured for this type.");
+ }
+
+ /**
+ * Adds a new access mode mapping to this configuration.
+ *
+ * @param code the code that will be associated with the access mode,
+ * @param accessMode the accessMode.
+ */
+ void addAccessModeMapping(int code, AccessMode accessMode){
+ _accessModes.put(code, accessMode);
+
+ LOGGER.info(Messages.QMAN_000006_ACCESS_MODE_MAPPING_CONFIGURED, code,accessMode);
+ }
+
+ /**
+ * Adds a new management message handler to this configuration.
+ * The incoming mapping object will contains an opcode and the class (as a string) of the message handler that will be used
+ * for processing incoming messages with that opcode.
+ *
+ * @param mapping the message handler mapping.
+ */
+ void addManagementMessageHandlerMapping (MessageHandlerMapping mapping)
+ {
+ Character opcode = mapping.getOpcode();
+ IMessageHandler handler = mapping.getMessageHandler();
+ _managementQueueHandlers.put(opcode, handler);
+
+ LOGGER.info(Messages.QMAN_000007_MANAGEMENT_HANDLER_MAPPING_CONFIGURED, opcode,handler.getClass().getName());
+ }
+
+ /**
+ * Adds a new method-reply message handler to this configuration.
+ * The incoming mapping object will contains an opcode and the class (as a string) of the message handler that will be used
+ * for processing incoming messages with that opcode.
+ *
+ * @param mapping the message handler mapping.
+ */
+ void addMethodReplyMessageHandlerMapping (MessageHandlerMapping mapping)
+ {
+ Character opcode = mapping.getOpcode();
+ IMessageHandler handler = mapping.getMessageHandler();
+ _methodReplyQueueHandlers.put(opcode, handler);
+
+ LOGGER.info(Messages.QMAN_000008_METHOD_REPLY_HANDLER_MAPPING_CONFIGURED, opcode,handler.getClass().getName());
+ }
+
+ /**
+ * Adds to this configuration a new broker connection data.
+ *
+ * @param brokerId the broker identifier.
+ * @param connectionData the connection data.
+ * @throws BrokerAlreadyConnectedException when the broker is already connected.
+ * @throws BrokerConnectionException when a connection cannot be estabilished.
+ */
+ void addBrokerConnectionData (UUID brokerId, BrokerConnectionData connectionData) throws BrokerAlreadyConnectedException, BrokerConnectionException
+ {
+ if (_brokerConnectionInfos.containsValue(connectionData))
+ {
+ throw new BrokerAlreadyConnectedException(connectionData);
+ }
+
+ try
+ {
+ QpidDatasource.getInstance().addConnectionPool(brokerId, connectionData);
+ _brokerConnectionInfos.put(brokerId,connectionData);
+
+ LOGGER.info(Messages.QMAN_000009_BROKER_DATA_CONFIGURED,brokerId,connectionData);
+ } catch(Exception exception)
+ {
+ throw new BrokerConnectionException(exception);
+ }
+
+ }
+
+ /**
+ * Header for command messages is created once because it only contains static values.
+ */
+ private void createHeaderForCommandMessages ()
+ {
+ ReplyTo replyTo=new ReplyTo();
+ replyTo.setRoutingKey(_methodReplyQueueName);
+ _messageProperties.setReplyTo(replyTo);
+ _deliveryProperties.setRoutingKey(Names.AGENT_ROUTING_KEY);
+ _headerForCommandMessages = new Header(_deliveryProperties, _messageProperties);
+ }
+
+ /**
+ * Creates the name of the queues used by this service.
+ * This is done because if a broker should be managed by one or more management client, then each of them
+ * must have its own channels to communicate with.
+ */
+ private void defineQueueNames()
+ {
+ UUID uuid = UUID.randomUUID();
+ _managementQueueName = Names.MANAGEMENT_QUEUE_PREFIX+uuid;
+ _methodReplyQueueName = Names.METHOD_REPLY_QUEUE_PREFIX+uuid;
+
+ LOGGER.debug(Messages.QMAN_200004_MANAGEMENT_QUEUE_NAME,_managementQueueName);
+ LOGGER.debug(Messages.QMAN_200005_METHOD_REPLY_QUEUE_NAME,_methodReplyQueueName);
+ }
+
+ /**
+ * Returns the worker manager thread pool size.
+ *
+ * @return the worker manager thread pool size.
+ */
+ public int getWorkerManagerPoolSize()
+ {
+ return _poolSize;
+ }
+
+ /**
+ * Sets the size of the worker manager thread pool.
+ *
+ * @param poolSize the size of the worker manager thread pool.
+ */
+ void setWorkerManagerPoolSize(int poolSize)
+ {
+ this._poolSize = poolSize;
+ }
+
+ /**
+ * Returns the maximum size of the worker manager
+ * thread pool size.
+ *
+ * @return the max size of the worker manager thread pool.
+ */
+ public int getWorkerManagerMaxPoolSize()
+ {
+ return _maxPoolSize;
+ }
+
+ /**
+ * Sets the maximum size of the worker manager
+ * thread pool size.
+ *
+ * @param maxPoolSize the max size of the worker manager thread pool.
+ */
+ void setWorkerManagerMaxPoolSize(int maxPoolSize)
+ {
+ this._maxPoolSize = maxPoolSize;
+ }
+
+ /**
+ * Returns the max amount of time that an excess thread
+ * can be idle before purging from the pool.
+ *
+ * @return the max keep alive time.
+ */
+ public long getWorkerManagerKeepAliveTime()
+ {
+ return _keepAliveTime;
+ }
+
+ /**
+ * Sets the max amount of time that an excess thread
+ * can be idle before purging from the pool.
+ *
+ * @param keepAliveTime the max keep alive time.
+ */
+ void setWorkerManagerKeepAliveTime(long keepAliveTime)
+ {
+ this._keepAliveTime = keepAliveTime;
+ }
+
+ /**
+ * Configures access mode mappings.
+ * An access mode mapping is an association between a code and an access mode.
+ */
+ private void addAccessModeMappings() {
+ addAccessModeMapping(1,AccessMode.RC);
+ addAccessModeMapping(2,AccessMode.RW);
+ addAccessModeMapping(3,AccessMode.RO);
+ }
+
+ /**
+ * Configures type mappings.
+ * A type mapping is an association between a code and a management type.
+ */
+ private void addTypeMappings()
+ {
+ addTypeMapping(1,new Uint8(),Names.NUMBER_VALIDATOR);
+ addTypeMapping(2,new Uint16(),Names.NUMBER_VALIDATOR);
+ addTypeMapping(3,new Uint32(),Names.NUMBER_VALIDATOR);
+ addTypeMapping(4,new Uint64(),Names.NUMBER_VALIDATOR);
+ addTypeMapping(6,new Str8(),Names.STRING_VALIDATOR);
+ addTypeMapping(7,new Str16(),Names.STRING_VALIDATOR);
+ addTypeMapping(8,new AbsTime());
+ addTypeMapping(9,new DeltaTime());
+ addTypeMapping(10,new ObjectReference());
+ addTypeMapping(11,new org.apache.qpid.management.domain.model.type.Boolean());
+ addTypeMapping(14,new org.apache.qpid.management.domain.model.type.Uuid());
+ addTypeMapping(15,new org.apache.qpid.management.domain.model.type.Map());
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/ConfigurationException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/ConfigurationException.java
new file mode 100644
index 0000000000..6eed515e11
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/ConfigurationException.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.management.configuration;
+
+/**
+ * Thrown when a problem is encountered during building the configuration.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ConfigurationException extends Exception
+{
+ private static final long serialVersionUID = 8238481177714286259L;
+
+ public ConfigurationException(String msg)
+ {
+ super(msg);
+ }
+
+ /**
+ * Builds a new ConfigurationException with the given cause.
+ *
+ * @param exception the exception cause.
+ */
+ public ConfigurationException(Exception exception)
+ {
+ super(exception);
+ }
+
+ public ConfigurationException(String msg,Exception exception)
+ {
+ super(msg,exception);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java
new file mode 100644
index 0000000000..fe44c6aff7
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java
@@ -0,0 +1,240 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.configuration;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.UUID;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.domain.handler.impl.ConfigurationMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.EventContentMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.HeartBeatIndicationMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.InstrumentationMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.MethodResponseMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.SchemaResponseMessageHandler;
+import org.apache.qpid.transport.util.Logger;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Director used for coordinating the build process of configuration.
+ * This is the only component which has a read-write permission on Configuration object.
+ */
+public class Configurator extends DefaultHandler
+{
+ private final static Logger LOGGER = Logger.get(Configurator.class);
+
+ /**
+ * Default (empty) parser used when there's no need to process data (non relevant elements).
+ */
+ final static IParser DEFAULT_PARSER = new IParser() {
+
+ public void setCurrrentAttributeValue (String value)
+ {
+ }
+
+ public void setCurrentAttributeName (String name)
+ {
+ }
+ };
+
+ IParser _brokerConfigurationParser = new BrokerConnectionDataParser();
+ IParser _workerManagerConfigurationParser = new WorkerManagerConfigurationParser();
+ IParser _currentParser = DEFAULT_PARSER;
+
+ /**
+ * Delegates the processing to the current parser.
+ */
+ @Override
+ public void characters (char[] ch, int start, int length) throws SAXException
+ {
+ String value = new String(ch,start,length).trim();
+ if (value.length() != 0) {
+ _currentParser.setCurrrentAttributeValue(value);
+ }
+ }
+
+ /**
+ * Here is defined what parser needs to be used for processing the current data.
+ */
+ @Override
+ public void startElement (String uri, String localName, String name, Attributes attributes) throws SAXException
+ {
+ switch(Tag.get(name))
+ {
+ case BROKERS :
+ {
+ _currentParser = _brokerConfigurationParser;
+ break;
+ }
+ case WORK_MANAGER :
+ {
+ _currentParser = _workerManagerConfigurationParser;
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void endElement (String uri, String localName, String name) throws SAXException
+ {
+ _currentParser.setCurrentAttributeName(name);
+ }
+
+ /**
+ * Builds whole configuration.
+ *
+ * @throws ConfigurationException when the build fails.
+ */
+ public void configure() throws ConfigurationException
+ {
+ BufferedReader reader = null;
+ try
+ {
+ String initialConfigFileName = System.getProperty(Names.QMAN_CONFIG_OPTION_NAME);
+ if (initialConfigFileName != null && initialConfigFileName.trim().length() != 0)
+ {
+ File initialConfigurationFile = new File(initialConfigFileName);
+ if (initialConfigurationFile.canRead())
+ {
+ SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+ reader = new BufferedReader(
+ new InputStreamReader(
+ new FileInputStream(initialConfigFileName)));
+ InputSource source = new InputSource(reader);
+ parser.parse(source, this);
+ } else {
+ LOGGER.warn(
+ Messages.QMAN_300004_INVALID_CONFIGURATION_FILE,
+ initialConfigFileName);
+ }
+ }
+
+ addMandatoryManagementMessageHandlers();
+ addMandatoryMethodReplyMessageHandlers();
+ } catch (Exception exception)
+ {
+ throw new ConfigurationException(exception);
+ } finally
+ {
+ try
+ {
+ reader.close();
+ } catch (Exception ignore)
+ {
+ }
+ }
+ }
+
+ /**
+ * Creates and return a value object (BrokerConnectionData) with the given parameters.
+ * Note that that object will be stored on configuration and it could be used to set a connection with the broker.
+ * This happens when the "initialPoolCapacity" is greater than 0 : in this case the caller is indicatinf that it wants to open
+ * one or more connections immediately at startup and therefore Q-Man will try to do that.
+ *
+ * @param host the hostname where the broker is running.
+ * @param port the port where the broker is running.
+ * @param username the username for connecting with the broker.
+ * @param password the password for connecting with the broker.
+ * @param virtualHost the virtual host.
+ * @param initialPoolCapacity the number of the connection that must be immediately opened.
+ * @param maxPoolCapacity the maximum number of opened connection.
+ * @param maxWaitTimeout the maximum amount of time that a client will wait for obtaining a connection.
+ * @return the value object containing the data above.
+ * @throws BrokerAlreadyConnectedException when the broker is already connected.
+ * @throws BrokerConnectionException when a connection cannot be estabilished.
+ */
+ public BrokerConnectionData createAndReturnBrokerConnectionData(
+ UUID brokerId,
+ String host,
+ int port,
+ String username,
+ String password,
+ String virtualHost,
+ int initialPoolCapacity,
+ int maxPoolCapacity,
+ long maxWaitTimeout) throws BrokerAlreadyConnectedException, BrokerConnectionException
+ {
+ BrokerConnectionData data = new BrokerConnectionData(
+ host,
+ port,
+ virtualHost,
+ username,
+ password,
+ initialPoolCapacity,
+ maxPoolCapacity,
+ maxWaitTimeout);
+ Configuration.getInstance().addBrokerConnectionData(brokerId, data);
+ return data;
+ }
+
+ /**
+ * Configures the mandatory management message handlers.
+ */
+ void addMandatoryMethodReplyMessageHandlers ()
+ {
+ Configuration.getInstance().addMethodReplyMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.OPERATION_INVOCATION_RESPONSE_OPCODE,
+ new MethodResponseMessageHandler()));
+
+ Configuration.getInstance().addMethodReplyMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.SCHEMA_RESPONSE_OPCODE,
+ new SchemaResponseMessageHandler()));
+ }
+
+ /**
+ * Configures the mandatory management message handlers.
+ */
+ void addMandatoryManagementMessageHandlers ()
+ {
+ Configuration.getInstance().addManagementMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.INSTRUMENTATION_CONTENT_RESPONSE_OPCODE,
+ new InstrumentationMessageHandler()));
+
+ Configuration.getInstance().addManagementMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.CONFIGURATION_CONTENT_RESPONSE_OPCDE,
+ new ConfigurationMessageHandler()));
+
+ Configuration.getInstance().addManagementMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.EVENT_CONTENT_RESPONSE_OPCDE,
+ new EventContentMessageHandler()));
+
+ Configuration.getInstance().addManagementMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.HEARTBEAT_INDICATION_RESPONSE_OPCODE,
+ new HeartBeatIndicationMessageHandler()));
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/IParser.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/IParser.java
new file mode 100644
index 0000000000..a221686765
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/IParser.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.management.configuration;
+
+/**
+ * Interface definition for configuration parser
+ * Concrete implementors are responsible for parsing a specific XML part of configuration data.
+ *
+ * @author Andrea Gazzarini
+ */
+interface IParser
+{
+ /**
+ * Main director callback : Sets the name of the current attribute.
+ *
+ * @param name the name of the current attribute.
+ */
+ void setCurrentAttributeName(String name);
+
+ /**
+ * Main director callback : sets the value of the current attribute.
+ *
+ * @param value the value of the current attribute.
+ */
+ void setCurrrentAttributeValue(String value);
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java
new file mode 100644
index 0000000000..b02fb789cc
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.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.management.configuration;
+
+import org.apache.qpid.management.domain.handler.base.IMessageHandler;
+
+/**
+ * Message Handler mapping used for associating an opcode with a message handler.
+ */
+class MessageHandlerMapping
+{
+ private final Character _opcode;
+ private final IMessageHandler _handler;
+
+ /**
+ * Builds a new mapping with the given opcode and handler class.
+ *
+ * @param opcode the opcode.
+ * @param handlerClass the handler class.
+ */
+ MessageHandlerMapping(Character opcode, IMessageHandler handler)
+ {
+ this._opcode = opcode;
+ this._handler = handler;
+ }
+
+ /**
+ * Returns the opcode of this mapping.
+ *
+ * @return the code of this mapping.
+ */
+ Character getOpcode ()
+ {
+ return _opcode;
+ }
+
+ /**
+ * Returns the message handler for this mapping.
+ *
+ * @return the message handler for this mapping.
+ */
+ IMessageHandler getMessageHandler()
+ {
+ return _handler;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/QpidDatasource.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/QpidDatasource.java
new file mode 100644
index 0000000000..569a65a782
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/QpidDatasource.java
@@ -0,0 +1,249 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.commons.pool.BasePoolableObjectFactory;
+import org.apache.commons.pool.ObjectPool;
+import org.apache.commons.pool.impl.GenericObjectPool;
+import org.apache.commons.pool.impl.GenericObjectPoolFactory;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.ConnectionException;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Qpid datasource.
+ * Basically it is a connection pool manager used for optimizing broker connections usage.
+ *
+ * @author Andrea Gazzarini
+ */
+public final class QpidDatasource
+{
+ private final static Logger LOGGER = Logger.get(QpidDatasource.class);
+
+ /**
+ * A connection decorator used for adding pool interaction behaviour to an existing connection.
+ *
+ * @author Andrea Gazzarini
+ */
+ class PooledConnection extends Connection
+ {
+ private final UUID _brokerId;
+ private boolean _valid;
+
+ /**
+ * Builds a new decorator with the given connection.
+ *
+ * @param brokerId the broker identifier.
+ */
+ private PooledConnection(UUID brokerId)
+ {
+ this._brokerId = brokerId;
+ _valid = true;
+ }
+
+ /**
+ * Returns true if the underlying connection is still valid and can be used.
+ *
+ * @return true if the underlying connection is still valid and can be used.
+ */
+ boolean isValid()
+ {
+ return _valid;
+ }
+
+ void reallyClose()
+ {
+ super.close();
+ }
+
+ /**
+ * Returns the connection to the pool. That is, marks this connections as available.
+ * After that, this connection will be available for further operations.
+ */
+ public void close()
+ {
+ try
+ {
+ pools.get(_brokerId).returnObject(this);
+
+ LOGGER.debug(Messages.QMAN_200006_QPID_CONNECTION_RELEASED, this);
+ }
+ catch (Exception e)
+ {
+ throw new ConnectionException(e);
+ }
+ }
+
+ public void exception(Throwable t)
+ {
+ //super.exception(t);
+ _valid = false;
+ }
+ }
+
+ /**
+ * This is the connection factory, that is, the factory used to manage the lifecycle (create, validate & destroy) of
+ * the broker connection(s).
+ *
+ * @author Andrea Gazzarini
+ */
+ class QpidConnectionFactory extends BasePoolableObjectFactory
+ {
+ private final BrokerConnectionData _connectionData;
+ private final UUID _brokerId;
+
+ /**
+ * Builds a new connection factory with the given parameters.
+ *
+ * @param brokerId the broker identifier.
+ * @param connectionData the connecton data.
+ */
+ private QpidConnectionFactory(UUID brokerId, BrokerConnectionData connectionData)
+ {
+ this._connectionData = connectionData;
+ this._brokerId = brokerId;
+ }
+
+ /**
+ * Creates a new underlying connection.
+ */
+ @Override
+ public Connection makeObject () throws Exception
+ {
+ PooledConnection connection = new PooledConnection(_brokerId);
+ connection.connect(
+ _connectionData.getHost(),
+ _connectionData.getPort(),
+ _connectionData.getVirtualHost(),
+ _connectionData.getUsername(),
+ _connectionData.getPassword(),
+ false);
+ return connection;
+ }
+
+ /**
+ * Validates the underlying connection.
+ */
+ @Override
+ public boolean validateObject (Object obj)
+ {
+ PooledConnection connection = (PooledConnection) obj;
+ boolean isValid = connection.isValid();
+
+ LOGGER.debug(Messages.QMAN_200007_TEST_CONNECTION_ON_RESERVE,isValid);
+
+ return isValid;
+ }
+
+ /**
+ * Closes the underlying connection.
+ */
+ @Override
+ public void destroyObject (Object obj) throws Exception
+ {
+ try
+ {
+ PooledConnection connection = (PooledConnection) obj;
+ connection.reallyClose();
+
+ LOGGER.debug(Messages.QMAN_200008_CONNECTION_DESTROYED);
+ } catch (Exception exception)
+ {
+ LOGGER.debug(exception, Messages.QMAN_200009_CONNECTION_DESTROY_FAILURE);
+ }
+ }
+ }
+
+ // Singleton instance.
+ private static QpidDatasource instance = new QpidDatasource();
+
+ // Each entry contains a connection pool for a specific broker.
+ private Map<UUID, ObjectPool> pools = new HashMap<UUID, ObjectPool>();
+
+ // Private constructor.
+ private QpidDatasource()
+ {
+ }
+
+ /**
+ * Gets an available connection from the pool of the given broker.
+ *
+ * @param brokerId the broker identifier.
+ * @return a valid connection to the broker associated with the given identifier.
+ */
+ public Connection getConnection(UUID brokerId) throws Exception
+ {
+ return (Connection) pools.get(brokerId).borrowObject();
+ }
+
+ /**
+ * Entry point method for retrieving the singleton instance of this datasource.
+ *
+ * @return the qpid datasource singleton instance.
+ */
+ public static QpidDatasource getInstance()
+ {
+ return instance;
+ }
+
+ /**
+ * Adds a connection pool to this datasource.
+ *
+ * @param brokerId the broker identifier that will be associated with the new connection pool.
+ * @param connectionData the broker connection data.
+ * @throws Exception when the pool cannot be created.
+ */
+ void addConnectionPool(UUID brokerId,BrokerConnectionData connectionData) throws Exception
+ {
+ GenericObjectPoolFactory factory = new GenericObjectPoolFactory(
+ new QpidConnectionFactory(brokerId,connectionData),
+ connectionData.getMaxPoolCapacity(),
+ GenericObjectPool.WHEN_EXHAUSTED_BLOCK,
+ connectionData.getMaxWaitTimeout(),-1,
+ true,
+ false);
+
+ ObjectPool pool = factory.createPool();
+
+ // Open connections at startup according to initial capacity param value.
+ int howManyConnectionAtStartup = connectionData.getInitialPoolCapacity();
+ Object [] openStartupList = new Object[howManyConnectionAtStartup];
+
+ // Open...
+ for (int index = 0; index < howManyConnectionAtStartup; index++)
+ {
+ openStartupList[index] = pool.borrowObject();
+ }
+
+ // ...and immediately return them to pool. In this way the pooled connection has been opened.
+ for (int index = 0; index < howManyConnectionAtStartup; index++)
+ {
+ pool.returnObject(openStartupList[index]);
+ }
+
+ pools.put(brokerId,pool);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.java
new file mode 100644
index 0000000000..c2b6e1e27d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.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.management.configuration;
+
+/**
+ * Configuration Tag catalogue.
+ *
+ * @author Andrea Gazzarini
+ */
+public enum Tag {
+ CONFIGURATION { @Override public String toString() { return "configuration"; }},
+ BROKER { @Override public String toString() { return "broker"; }},
+ HOST { @Override public String toString() { return "host"; }},
+ PORT { @Override public String toString() { return "port"; }},
+ MAX_POOL_CAPACITY { @Override public String toString() { return "max-pool-capacity"; }},
+ MAX_WAIT_TIMEOUT { @Override public String toString() { return "max-wait-timeout"; }},
+ INITIAL_POOL_CAPACITY { @Override public String toString() { return "initial-pool-capacity"; }},
+ VIRTUAL_HOST { @Override public String toString() { return "virtual-host"; }},
+ USER { @Override public String toString() { return "user"; }},
+ PASSWORD { @Override public String toString() { return "password"; }},
+ BROKERS { @Override public String toString() { return "brokers"; }},
+ WORK_MANAGER { @Override public String toString() { return "work-manager"; }},
+ POOL_CAPACITY { @Override public String toString() { return "pool-capacity"; }},
+ KEEP_ALIVE_TIME { @Override public String toString() { return "keep-alive-time"; }};
+
+ /**
+ * Returns the enum entry associated to the given tag name.
+ *
+ * @param name the name of tag.
+ * @return the enum entry associated to the given tag name.
+ */
+ public static Tag get(String name) {
+ return valueOf(name.replaceAll("-", "_").toUpperCase());
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownAccessCodeException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownAccessCodeException.java
new file mode 100644
index 0000000000..b7f1c0a7ec
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownAccessCodeException.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.management.configuration;
+
+/**
+ * Thrown when no access mode is found in configuration associated to the given code.
+ *
+ * @author Andrea Gazzarini
+ */
+public class UnknownAccessCodeException extends Exception
+{
+ private static final long serialVersionUID = 2350963503092509119L;
+ private final int _code;
+
+ /**
+ * Builds a new UnknownAccessCodeException with the given code.
+ *
+ * @param code the access code.
+ */
+ UnknownAccessCodeException(int code)
+ {
+ super(String.valueOf(code));
+ this._code = code;
+ }
+
+ /**
+ * Returns the unknown code.
+ *
+ * @return the unknown code.
+ */
+ public int getCode ()
+ {
+ return _code;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownBrokerException.java
index 1f69973b96..5b08e09c24 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownBrokerException.java
@@ -18,30 +18,26 @@
* under the License.
*
*/
-package org.apache.qpid.transport.network;
+package org.apache.qpid.management.configuration;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
+import java.util.UUID;
-import org.apache.qpid.transport.Sender;
-
-public interface NetworkConnection
+/**
+ * Thrown when someone requests connection data for an unknown broker.
+ *
+ * @author Andrea Gazzarini
+ */
+public class UnknownBrokerException extends Exception
{
- Sender<ByteBuffer> getSender();
-
- void close();
-
- /**
- * Returns the remote address of the underlying socket.
- */
- SocketAddress getRemoteAddress();
+ private static final long serialVersionUID = 4965395428832158924L;
/**
- * Returns the local address of the underlying socket.
+ * Builds a new UnknownBrokerException with the given broker id.
+ *
+ * @param brokerId the broker identifier.
*/
- SocketAddress getLocalAddress();
-
- void setMaxWriteIdle(int sec);
-
- void setMaxReadIdle(int sec);
+ UnknownBrokerException(UUID brokerId)
+ {
+ super(String.valueOf(brokerId));
+ }
} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownTypeCodeException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownTypeCodeException.java
new file mode 100644
index 0000000000..57005d21e5
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownTypeCodeException.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.management.configuration;
+
+/**
+ * Thrown when no type is found in configuration associated to the given code.
+ *
+ * @author Andrea Gazzarini
+ */
+public class UnknownTypeCodeException extends Exception
+{
+ private static final long serialVersionUID = 5440934037645111591L;
+ private int _code;
+
+ /**
+ * Builds a new UnknownTypeCodeException with the given code.
+ *
+ * @param code the access code.
+ */
+ UnknownTypeCodeException(int code)
+ {
+ super(String.valueOf(code));
+ this._code = code;
+ }
+
+ /**
+ * Returns the unknown code.
+ *
+ * @return the unknown code.
+ */
+ public int getCode ()
+ {
+ return _code;
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/WorkerManagerConfigurationParser.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/WorkerManagerConfigurationParser.java
new file mode 100644
index 0000000000..4e68b54b12
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/WorkerManagerConfigurationParser.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.management.configuration;
+
+import java.util.UUID;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Parser used for building worker manager settings.
+ * The corresponding section of the configuration file is :
+ *
+ <work-manager>
+ <pool-capacity>5</pool-capacity>
+ <max-pool-capacity>15</max-pool-capacity>
+ <keep-alive-time>5000</keep-alive-time>
+ </work-manager>
+
+ *
+ * @author Andrea Gazzarini
+ */
+class WorkerManagerConfigurationParser implements IParser
+{
+ private final static Logger LOGGER = Logger.get(Configuration.class);
+ private String _currentValue;
+
+ private String _poolSizeAsString;
+ private String _maxPoolSizeAsString;
+ private String _keepAliveTimeAsString;
+
+ /**
+ * Callback : the given value is the text content of the current node.
+ */
+ public void setCurrrentAttributeValue (String value)
+ {
+ this._currentValue = value;
+ }
+
+ /**
+ * Callback: each time the end of an element is reached
+ * this method is called.
+ */
+ public void setCurrentAttributeName (String name)
+ {
+ switch (Tag.get(name))
+ {
+ case POOL_CAPACITY:
+ {
+ _poolSizeAsString = _currentValue.trim();
+ break;
+ }
+ case MAX_POOL_CAPACITY :
+ {
+ _maxPoolSizeAsString = _currentValue;
+ break;
+ }
+ case KEEP_ALIVE_TIME:
+ {
+ _keepAliveTimeAsString = _currentValue;
+ break;
+ }
+ case WORK_MANAGER:
+ {
+ Configuration configuration = Configuration.getInstance();
+ try
+ {
+ configuration.setWorkerManagerPoolSize(Integer.parseInt(_poolSizeAsString));
+ configuration.setWorkerManagerMaxPoolSize(Integer.parseInt(_maxPoolSizeAsString));
+ configuration.setWorkerManagerKeepAliveTime(Long.parseLong(_keepAliveTimeAsString));
+ } catch(Exception exception)
+ {
+ LOGGER.error(Messages.QMAN_100039_UNABLE_TO_CONFIGURE_PROPERLY_WORKER_MANAGER);
+ } finally {
+ LOGGER.info(Messages.QMAN_000035_WORK_MANAGER_POOL_SIZE,configuration.getWorkerManagerPoolSize());
+ LOGGER.info(Messages.QMAN_000036_WORK_MANAGER_MAX_POOL_SIZE,configuration.getWorkerManagerMaxPoolSize());
+ LOGGER.info(Messages.QMAN_000037_WORK_MANAGER_KEEP_ALIVE_TIME,configuration.getWorkerManagerKeepAliveTime());
+ }
+ break;
+ }
+ }
+ }
+
+ /**
+ * Gets an uuid in order to associate current connection data with a broker.
+ * @return
+ */
+ UUID getUUId(){
+ return UUID.randomUUID();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/BaseMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/BaseMessageHandler.java
new file mode 100644
index 0000000000..798e835ff4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/BaseMessageHandler.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.management.domain.handler.base;
+
+import org.apache.qpid.management.domain.model.DomainModel;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Base class for all message handlers.
+ * A message handler is an handler for a specific type of message.
+ * Message type is defined by the opcode.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class BaseMessageHandler implements IMessageHandler
+{
+ /**
+ * Logger used for logging.
+ */
+ protected final Logger _logger = Logger.get(getClass());
+
+ /**
+ * Managed broker domain model.
+ */
+ protected DomainModel _domainModel;
+
+ /**
+ * Sets the broker domain model.
+ *
+ * @param domainModel the broker domain model.
+ */
+ public void setDomainModel(DomainModel domainModel)
+ {
+ this._domainModel = domainModel;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandler.java
new file mode 100644
index 0000000000..be000e9a05
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandler.java
@@ -0,0 +1,114 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.handler.base;
+
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * Base class for content indication message handlers.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class ContentIndicationMessageHandler extends BaseMessageHandler
+{
+ /**
+ * Processes the income message.
+ *
+ * @param decoder the decoder used to parse the message.
+ * @param sequenceNumber the sequence number of the message.
+ */
+ public final void process (Decoder decoder, int sequenceNumber)
+ {
+ String packageName = decoder.readStr8();
+ String className = decoder.readStr8();
+ Binary classHash = new Binary(decoder.readBin128());
+
+ long timeStampOfCurrentSample = decoder.readDatetime();
+ long timeObjectWasCreated = decoder.readDatetime();
+ long timeObjectWasDeleted = decoder.readDatetime();
+
+ Binary objectId = new Binary(decoder.readBin128());
+
+ if (objectHasBeenRemoved(timeObjectWasDeleted, timeStampOfCurrentSample))
+ {
+ removeObjectInstance(packageName,className,classHash,objectId);
+ } else
+ {
+ updateDomainModel(
+ packageName,
+ className,
+ classHash,
+ objectId,
+ timeStampOfCurrentSample,
+ timeObjectWasCreated,
+ timeObjectWasDeleted,
+ decoder.readReaminingBytes());
+ }
+ }
+
+ /**
+ * Removes an object instance from the domain model.
+ *
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param classHash the class hash.
+ * @param objectId the object identifier.
+ */
+ void removeObjectInstance(String packageName, String className,Binary classHash, Binary objectId)
+ {
+ _domainModel.removeObjectInstance(packageName,className,classHash,objectId);
+ }
+
+ /**
+ * Checks if the timestamps contained in the message indicate that the object has been removed.
+ *
+ * @param deletionTimestamp time object was deleted.
+ * @param now timestamp of the current message.
+ * @return true if the object has been removed, false otherwise.
+ */
+ boolean objectHasBeenRemoved(long deletionTimestamp, long now) {
+ return (deletionTimestamp != 0) && (now > deletionTimestamp);
+ }
+
+ /**
+ * Updates domain model with the incoming data.
+ * This is a template method that each concrete subclass must implement in order to update the domain model
+ * with the incoming data.
+ *
+ * @param packageName the name of the package.
+ * @param className the name of the class.
+ * @param objectId the object identifier.
+ * @param timeStampOfCurrentSample timestamp of current sample.
+ * @param timeObjectWasCreated time object was created.
+ * @param timeObjectWasDeleted time object was deleted.
+ * @param contentData object instance incoming data.
+ */
+ protected abstract void updateDomainModel(
+ String packageName,
+ String className,
+ Binary classHash,
+ Binary objectId,
+ long timeStampOfCurrentSample,
+ long timeObjectWasCreated,
+ long timeObjectWasDeleted,
+ byte []contentData );
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/IMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/IMessageHandler.java
new file mode 100644
index 0000000000..c120334d30
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/IMessageHandler.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.management.domain.handler.base;
+
+import org.apache.qpid.management.domain.model.DomainModel;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * Interface definition for a processor able to deal with a specific message.
+ * The concrete implementor must define what has to be done with the supplied (incoming) stream and the sequence
+ * number.
+ *
+ * @author Andrea Gazzarini.
+ */
+public interface IMessageHandler
+{
+ /**
+ * Processes the (incoming) stream message.
+ * Note that the main controller (the component that is controlling this handler) has already read the magic number and
+ * the sequence number so here concrete implementors must start from that point (that is, just after the sequence
+ * number).
+ *
+ * @param decoder the stream decoder.
+ * @param sequenceNumber the sequence number of the message.
+ */
+ void process (Decoder decoder, int sequenceNumber);
+
+ /**
+ * Injects the domain model into this handler.
+ *
+ * @param domainModel the domain model.
+ */
+ void setDomainModel(DomainModel domainModel);
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/ConfigurationMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/ConfigurationMessageHandler.java
new file mode 100644
index 0000000000..3158138172
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/ConfigurationMessageHandler.java
@@ -0,0 +1,57 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.handler.impl;
+
+import org.apache.qpid.management.domain.handler.base.ContentIndicationMessageHandler;
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Schema Response message handler.
+ * This handler is responsible to process 'c'(opcode) messages sent by the management broker.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ConfigurationMessageHandler extends ContentIndicationMessageHandler
+{
+ /**
+ * Broker domain model is going to be updated with incoming configuration data.
+ *
+ * @param packageName the name of the package.
+ * @param className the name of the class.
+ * @param objectId the object identifier.
+ * @param timeStampOfCurrentSample the timestamp of incoming data.
+ * @param timeObjectWasCreated time object was created.
+ * @param timeObjectWasDeleted time object was deleted.
+ */
+ @Override
+ protected void updateDomainModel (
+ String packageName,
+ String className,
+ Binary classHash,
+ Binary objectId,
+ long timeStampOfCurrentSample,
+ long timeObjectWasCreated,
+ long timeObjectWasDeleted,
+ byte[] contentData)
+ {
+ _domainModel.addConfigurationRawData(packageName,className,classHash,objectId,contentData);
+ }
+ }
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java
new file mode 100644
index 0000000000..0a590d2836
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.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.management.domain.handler.impl;
+
+import org.apache.qpid.management.domain.handler.base.BaseMessageHandler;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * Base class for content indication message handlers.
+ *
+ * @author Andrea Gazzarini
+ */
+public class EventContentMessageHandler extends BaseMessageHandler
+{
+ /**
+ * Processes the income message.
+ *
+ * @param decoder the decoder used to parse the message.
+ * @param sequenceNumber the sequence number of the message.
+ */
+ public final void process (Decoder decoder, int sequenceNumber)
+ {
+ String packageName = decoder.readStr8();
+ String eventName = decoder.readStr8();
+ Binary eventHash = new Binary(decoder.readBin128());
+ long timeStampOfCurrentSample = decoder.readDatetime();
+ int severity = decoder.readUint8();
+ byte[] argumentsData = decoder.readReaminingBytes();
+
+ _domainModel.addEventRawData(packageName, eventName, eventHash, argumentsData,timeStampOfCurrentSample,severity);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/HeartBeatIndicationMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/HeartBeatIndicationMessageHandler.java
new file mode 100644
index 0000000000..08c4f1bc5d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/HeartBeatIndicationMessageHandler.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.management.domain.handler.impl;
+
+import org.apache.qpid.management.domain.handler.base.BaseMessageHandler;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * This is the handler responsible for processing the heartbeat indication response messages.
+ * At the moment it simply updates the last refresh update timestamp of the domain model.
+ *
+ * @author Andrea Gazzarini.
+ */
+public class HeartBeatIndicationMessageHandler extends BaseMessageHandler
+{
+ public void process(Decoder decoder, int sequenceNumber)
+ {
+ _domainModel.updateLastRefreshDate();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/IMethodInvocationListener.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/IMethodInvocationListener.java
new file mode 100644
index 0000000000..4ce64dd339
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/IMethodInvocationListener.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.management.domain.handler.impl;
+
+import java.util.EventListener;
+
+import org.apache.qpid.management.domain.model.InvocationEvent;
+
+/**
+ * Listener interface used to denote a component interested in method invocation events.
+ *
+ * @author Andrea Gazzarini
+ */
+public interface IMethodInvocationListener extends EventListener
+{
+ /**
+ * An operation is going to be invoked on a specific object instance.
+ * This lets this listener to be informed about the imminent invocation.
+ *
+ * @param event the invocation event.
+ */
+ void operationIsGoingToBeInvoked(InvocationEvent event);
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InstrumentationMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InstrumentationMessageHandler.java
new file mode 100644
index 0000000000..e86a44f829
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InstrumentationMessageHandler.java
@@ -0,0 +1,57 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.handler.impl;
+
+import org.apache.qpid.management.domain.handler.base.ContentIndicationMessageHandler;
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Schema Response message handler.
+ * This handler is responsible to process 'i'(opcode) messages sent by the management broker.
+ *
+ * @author Andrea Gazzarini
+ */
+public class InstrumentationMessageHandler extends ContentIndicationMessageHandler
+{
+ /**
+ * Broker domain model is going to be updated with incoming instrumentation data.
+ *
+ * @param packageName the name of the package.
+ * @param className the name of the class.
+ * @param objectId the object identifier.
+ * @param timeStampOfCurrentSample the timestamp of incoming data.
+ * @param timeObjectWasCreated time object was created.
+ * @param timeObjectWasDeleted time object was deleted.
+ */
+ @Override
+ protected void updateDomainModel (
+ String packageName,
+ String className,
+ Binary classHash,
+ Binary objectId,
+ long timeStampOfCurrentSample,
+ long timeObjectWasCreated,
+ long timeObjectWasDeleted,
+ byte[] contentData)
+ {
+ _domainModel.addInstrumentationRawData(packageName,className,classHash,objectId,contentData);
+ }
+ }
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java
new file mode 100644
index 0000000000..019fce5a50
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java
@@ -0,0 +1,157 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.handler.impl;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.qpid.management.domain.services.MethodInvocationException;
+
+/**
+ * Value object used for storing an invocation method result.
+ * This is done in order to accomplish multiple return value requirement.
+ * As we know, it's not possible to do that only with method signature and therefore this value object / struct is used.
+ *
+ * @author Andrea Gazzarini
+ */
+public class InvocationResult implements Serializable
+{
+ private static final long serialVersionUID = 2062662997326399693L;
+
+ private final long _returnCode;
+ private final String _statusText;
+ private final byte [] _outputAndBidirectionalArgumentValues;
+ private Map<String, Object> _outputSection;
+
+ /**
+ * Builds an invocation result with the given status code and status text.
+ *
+ * @param statusCode the status code.
+ * @param statusText the status text.
+ */
+ InvocationResult(long statusCode, String statusText,byte [] outputAndBidirectionalArgumentValues)
+ {
+ this._returnCode = statusCode;
+ this._statusText = statusText;
+ this._outputAndBidirectionalArgumentValues = outputAndBidirectionalArgumentValues;
+ }
+
+ /**
+ * Checks if this result contains an error return code.
+ *
+ * @return true if this result object contains an error return code.
+ */
+ public boolean isException ()
+ {
+ return _returnCode != 0;
+ }
+
+ /**
+ * Simply throws a new MethodInvocationException.
+ * Usually this method is called in conjunction with the isException() method in order to raise an exception if
+ * the wrapped return code means that there was an error.
+ *
+ * @throws MethodInvocationException always.
+ */
+ public void createAndThrowException() throws MethodInvocationException
+ {
+ throw new MethodInvocationException(_returnCode, _statusText);
+ }
+
+ @Override
+ public String toString ()
+ {
+ StringBuilder builder = new StringBuilder()
+ .append("Status code : ")
+ .append(_returnCode)
+ .append(",")
+ .append("Status Text : ")
+ .append(_statusText);
+ if (_outputSection != null && !_outputSection.isEmpty())
+ {
+ builder.append(". Parameters : ");
+ for (Entry<String, Object> outputEntry : _outputSection.entrySet())
+ {
+ builder.append(outputEntry.getKey()).append('=').append(outputEntry.getValue());
+ builder.append(',');
+ }
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Returns the return code of this invocation result.
+ *
+ * @return the return code of this invocation result.
+ */
+ public long getReturnCode ()
+ {
+ return _returnCode;
+ }
+
+ /**
+ * Contains the status text of this invocation result.
+ *
+ * @return the status text of this invocation result.
+ */
+ public String getStatusText ()
+ {
+ return _statusText;
+ }
+
+ /**
+ * Returns the output and bidirectional argument values in raw format (byte [])
+ *
+ * @return the output and bidirectional argument values in raw format (byte [])
+ */
+ public byte [] getOutputAndBidirectionalArgumentValues()
+ {
+ return _outputAndBidirectionalArgumentValues;
+ }
+
+ /**
+ * Sets the output section (decoded) of this invocation result.
+ * When an incoming message arrives, the output section (output and bidirectional argument values) are
+ * initially stored in raw format.
+ * After that, their values need to be converted.
+ * The final result is a map containing (for each Output or Input/Output parameter) the name of the argument as key
+ * and its value as value.
+ *
+ * @param output a map containing outptu and bidirectional values (not in schema order).
+ */
+ public void setOutputSection (Map<String, Object> outputSection)
+ {
+ this._outputSection = outputSection;
+ }
+
+ /**
+ * Returns the output section of this invocation result.
+ * The output section consists in output and bidirectional argument values.
+ * Note that the order of the arguments is not guaranteed.
+ *
+ * @param outputSection the output section of this invocation result;
+ */
+ public Map<String, Object> getOutputSection ()
+ {
+ return _outputSection;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodOrEventDataTransferObject.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodOrEventDataTransferObject.java
new file mode 100644
index 0000000000..bc6a77d804
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodOrEventDataTransferObject.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.management.domain.handler.impl;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Simple transfer object used for holding method / event definition data.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MethodOrEventDataTransferObject
+{
+ private final Map<String, Object> _definition;
+ private List<Map<String, Object>> _argumentDefinitions;
+
+ /**
+ * Builds a new trasfer object with the given parameters.
+ *
+ * @param definition the method definition.
+ * @param argumentDefinitions the arguments definitions.
+ */
+ public MethodOrEventDataTransferObject(
+ Map<String, Object> definition,
+ List<Map<String, Object>> argumentDefinitions)
+ {
+ this._definition = definition;
+ this._argumentDefinitions = argumentDefinitions;
+ }
+
+ /**
+ * Returns the method definition.
+ *
+ * @return the method definition.
+ */
+ public Map<String, Object> getDefinition() {
+ return _definition;
+ }
+
+ /**
+ * Returns the arguemnts definitions.
+ *
+ * @return the arguemnts definitions.
+ */
+ public List<Map<String, Object>> getArgumentsDefinitions()
+ {
+ return _argumentDefinitions;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodResponseMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodResponseMessageHandler.java
new file mode 100644
index 0000000000..9c99eb09aa
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodResponseMessageHandler.java
@@ -0,0 +1,106 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.handler.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.domain.handler.base.BaseMessageHandler;
+import org.apache.qpid.management.domain.model.DomainModel;
+import org.apache.qpid.management.domain.model.InvocationEvent;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Message handler for method response messages.
+ * This handler is installed on domain model as a method invocation result listener.
+ * When a method is going to be invoked this listener is notified with the exchange channel that will be used between it and
+ * the event (method invocation) source object.
+ *
+ * @author Andrea Gazzarini
+ *
+ */
+public class MethodResponseMessageHandler extends BaseMessageHandler
+{
+ private final static Logger LOGGER = Logger.get(MethodResponseMessageHandler.class);
+
+ private Map<Integer, BlockingQueue<InvocationResult>> _exchangeChannels = new HashMap<Integer, BlockingQueue<InvocationResult>>();
+
+ /**
+ * This is the listener installed on domain model for method invocations.
+ */
+ private final IMethodInvocationListener methodInvocationListener = new IMethodInvocationListener()
+ {
+ /**
+ * Event source callback.
+ * A method is going to be invoked and this method lets this listener take the exchange channel that will be used
+ * with the event source for synchronous communication.
+ *
+ * @param event the operation invocation event.
+ */
+ public void operationIsGoingToBeInvoked (InvocationEvent event)
+ {
+ _exchangeChannels.put(event.getSequenceNumber(), event.getExchangeChannel());
+ }
+ };
+
+ /**
+ * Processes the incoming message.
+ *
+ * @param decoder the decoder used for parsing incoming data.
+ * @param sequenceNumber the sequence number of the incoming message.
+ */
+ public void process (Decoder decoder, int sequenceNumber)
+ {
+ InvocationResult result = new InvocationResult(decoder.readUint32(), decoder.readStr16(),decoder.readReaminingBytes());
+ BlockingQueue<InvocationResult> exchangeChannel = _exchangeChannels.remove(sequenceNumber);
+ if (exchangeChannel != null)
+ {
+ try
+ {
+ exchangeChannel.put(result);
+ } catch (InterruptedException exception)
+ {
+ LOGGER.error(exception,Messages.QMAN_100010_METHOD_INVOCATION_RESULT_FAILURE,sequenceNumber);
+ }
+ } else
+ {
+ LOGGER.warn(
+ "Unable to deal with incoming message because it contains a unknown sequence number (%s).",
+ sequenceNumber);
+ }
+ }
+
+ /**
+ * Sets the domain model on this handler.
+ * In addiction, this handler registers a method invocation listener on the domain model.
+ *
+ * @param domainModel the managed broker domain model.
+ */
+ @Override
+ public void setDomainModel (DomainModel domainModel)
+ {
+ super.setDomainModel(domainModel);
+ domainModel.setMethodInvocationListener(methodInvocationListener);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObject.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObject.java
new file mode 100644
index 0000000000..8456b2f8ac
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObject.java
@@ -0,0 +1,314 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.handler.impl;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.management.domain.services.MethodInvocationException;
+
+/**
+ * This is a sample entity used on QMan test case.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidDomainObject implements QpidDomainObjectMBean
+{
+ private UUID _vhostRef;
+ private String _name;
+ private Boolean _durable;
+ private Map<String, Object> _arguments;
+ private Long _msgTotalEnqueues;
+ private Integer _consumerCount;
+ private Short _mgmtPubInterval;
+ private Date _expireTime;
+ private String _type;
+ private byte [] _byteArray;
+
+ /**
+ * Builds a new QpidDomainObject with default values for
+ * its properties.
+ */
+ public QpidDomainObject()
+ {
+ _vhostRef = UUID.randomUUID();
+ _name = "Initial Name";
+ _durable = Boolean.TRUE;
+ _arguments = new HashMap<String, Object>();
+ _arguments.put("Key1", "aStringValue");
+ _arguments.put("Key2", Long.MIN_VALUE);
+ _arguments.put("Key3", Integer.MAX_VALUE);
+ _arguments.put("Key4", Double.MIN_VALUE);
+ _arguments.put("Key4", Float.MAX_VALUE);
+
+ _msgTotalEnqueues = Long.MAX_VALUE-10;
+ _consumerCount = Integer.MIN_VALUE+10;
+ _mgmtPubInterval = Short.MAX_VALUE;
+ _expireTime = new Date(Long.MAX_VALUE);
+ _byteArray = new byte[]{1,2,3,5,6,7,8,7,56};
+ }
+
+ /**
+ * A method that is throwing an exception, everytime.
+ *
+ * @throws Exception each time the method is called.
+ */
+ public void throwsException() throws Exception
+ {
+ throw new MethodInvocationException(-1,"KO");
+ }
+
+ /**
+ * Sample echo method that return an empty result object.
+ * That is, an object with only status code / text valorized
+ * (no output parameters).
+ *
+ * @return an empty result object.
+ */
+ public InvocationResult voidWithoutArguments()
+ {
+ return new InvocationResult(0,"OK,null",null);
+ }
+
+ /**
+ * Echo method that accepts and returns primitive type arrays.
+ *
+ * @param longs an array of long.
+ * @param booleans an array of boolean.
+ * @param doubles an array of double.
+ * @param floats an array of float.
+ * @param integers an array of int.
+ * @param shorts an array of short.
+ * @return a result object with the same input parameters (as output parameters).
+ */
+ public InvocationResult echoWithSimpleTypeArrays(
+ long [] longs,
+ boolean [] booleans,
+ double [] doubles,
+ float [] floats,
+ int [] integers,
+ short [] shorts)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put(long.class.getName(), longs);
+ outputParameters.put(boolean.class.getName(), booleans);
+ outputParameters.put(double.class.getName(), doubles);
+ outputParameters.put(float.class.getName(), floats);
+ outputParameters.put(int.class.getName(), integers);
+ outputParameters.put(short.class.getName(), shorts);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns wrapper types.
+ *
+ * @param aLong a java.lang.Long
+ * @param aBoolean a java.lang.Boolean
+ * @param aDouble a java.lang.Double
+ * @param aFloat a java.lang.Float
+ * @param anInteger a java.lang.Integer
+ * @param aShort a java.lang.Short
+ * @param aString a java.lang.String
+ * @param anURI a java.net.URI
+ * @param aDate a java.util.Date
+ * @return a result object with the same given parameters (as output parameters)
+ */
+ public InvocationResult echoWithSimpleTypes(
+ Long aLong,
+ Boolean aBoolean,
+ Double aDouble,
+ Float aFloat,
+ Integer anInteger,
+ Short aShort,
+ String aString,
+ URI anURI,
+ Date aDate)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put("p1", aLong);
+ outputParameters.put("p2", aBoolean);
+ outputParameters.put("p3", aDouble);
+ outputParameters.put("p4", aFloat);
+ outputParameters.put("p5", anInteger);
+ outputParameters.put("p6", aShort);
+ outputParameters.put("p7", aString);
+ outputParameters.put("p8", anURI);
+ outputParameters.put("p9", aDate);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns wrapper type arrays .
+ *
+ * @param longs an array of java.lang.Long
+ * @param booleans an array of java.lang.Boolean
+ * @param doubles an array of java.lang.Double
+ * @param floats an array of java.lang.Float
+ * @param integers an array of java.lang.Integer
+ * @param shorts an array of java.lang.Short
+ * @param strings an array of java.lang.String
+ * @param uris an array of java.net.URI
+ * @param dates an array of java.util.Date
+ * @return a result object with the same input parameters (as output parameters).
+ */
+ public InvocationResult echoWithArrays(
+ Long [] longs,
+ Boolean [] booleans,
+ Double [] doubles,
+ Float [] floats,
+ Integer [] integers,
+ Short [] shorts,
+ String [] strings,
+ URI [] uris,
+ Date [] dates)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put(Long.class.getName(), longs);
+ outputParameters.put(Boolean.class.getName(), booleans);
+ outputParameters.put(Double.class.getName(), doubles);
+ outputParameters.put(Float.class.getName(), floats);
+ outputParameters.put(Integer.class.getName(), integers);
+ outputParameters.put(Short.class.getName(), shorts);
+ outputParameters.put(String.class.getName(), strings);
+ outputParameters.put(URI.class.getName(), uris);
+ outputParameters.put(Date.class.getName(), dates);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns a byte array.
+ *
+ * @param byteArray a byte array
+ * @return a result containing the input byte array (as output parameter)
+ */
+ public InvocationResult echoWithByteArray(byte [] byteArray)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put(byte[].class.getName(),byteArray);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns an UUID.
+ *
+ * @param uuid a java.util.UUID.
+ * @return a result containing the input UUID (as output parameter)
+ */
+ public InvocationResult echoWithUUID(UUID uuid)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put("uuid",uuid);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns a Map.
+ *
+ * @param map a java.util.Map.
+ * @return a result containing the input Map (as output parameter)
+ */
+ public InvocationResult echoWithMap(Map<String,Object> map)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put("map",map);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ public UUID getVhostRef()
+ {
+ return _vhostRef;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public Boolean getDurable()
+ {
+ return _durable;
+ }
+
+ public Map<String, Object> getArguments()
+ {
+ return _arguments;
+ }
+
+ public Long getMsgTotalEnqueues()
+ {
+ return _msgTotalEnqueues;
+ }
+
+ public Integer getConsumerCount()
+ {
+ return _consumerCount;
+ }
+
+ public Date getExpireTime()
+ {
+ return _expireTime;
+ }
+
+ public Short getMgmtPubInterval()
+ {
+ return _mgmtPubInterval;
+ }
+
+ public void setExpireTime(Date expireTime)
+ {
+ this._expireTime = expireTime;
+ }
+
+ public void setMgmtPubInterval(Short value)
+ {
+ this._mgmtPubInterval = value;
+ }
+
+ public void setType(String type)
+ {
+ this._type = type;
+ }
+
+ public String getType()
+ {
+ return _type;
+ }
+
+ public byte[] getByteArray()
+ {
+ return _byteArray;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObjectMBean.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObjectMBean.java
new file mode 100644
index 0000000000..da585a9f43
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObjectMBean.java
@@ -0,0 +1,234 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.handler.impl;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Management interface for Qpid domain object.
+ *
+ * @author Andrea Gazzarini
+ */
+public interface QpidDomainObjectMBean
+{
+ /**
+ * A method that is throwing an exception, everytime.
+ *
+ * @throws Exception each time the method is called.
+ */
+ void throwsException() throws Exception;
+
+ /**
+ * Sample echo method that return an empty result object.
+ * That is, an object with only status code / text valorized
+ * (no output parameters).
+ *
+ * @return an empty result object.
+ */
+ InvocationResult voidWithoutArguments();
+
+ /**
+ * Echo method that accepts and returns wrapper types.
+ *
+ * @param aLong a java.lang.Long
+ * @param aBoolean a java.lang.Boolean
+ * @param aDouble a java.lang.Double
+ * @param aFloat a java.lang.Float
+ * @param anInteger a java.lang.Integer
+ * @param aShort a java.lang.Short
+ * @param aString a java.lang.String
+ * @param anURI a java.net.URI
+ * @param aDate a java.util.Date
+ * @return a result object with the same given parameters (as output parameters)
+ */
+ InvocationResult echoWithSimpleTypes(
+ Long aLong,
+ Boolean aBoolean,
+ Double aDouble,
+ Float aFloat,
+ Integer anInteger,
+ Short aShort,
+ String aString,
+ URI anURI,
+ Date aDate);
+
+ /**
+ * Echo method that accepts and returns wrapper type arrays .
+ *
+ * @param longs an array of java.lang.Long
+ * @param booleans an array of java.lang.Boolean
+ * @param doubles an array of java.lang.Double
+ * @param floats an array of java.lang.Float
+ * @param integers an array of java.lang.Integer
+ * @param shorts an array of java.lang.Short
+ * @param strings an array of java.lang.String
+ * @param uris an array of java.net.URI
+ * @param dates an array of java.util.Date
+ * @return a result object with the same input parameters (as output parameters).
+ */
+ InvocationResult echoWithArrays(
+ Long [] longs,
+ Boolean [] booleans,
+ Double [] doubles,
+ Float [] floats,
+ Integer [] integers,
+ Short [] shorts,
+ String [] strings,
+ URI [] uris,
+ Date [] dates);
+
+ /**
+ * Echo method that accepts and returns primitive type arrays.
+ *
+ * @param longs an array of long.
+ * @param booleans an array of boolean.
+ * @param doubles an array of double.
+ * @param floats an array of float.
+ * @param integers an array of int.
+ * @param shorts an array of short.
+ * @return a result object with the same input parameters (as output parameters).
+ */
+ InvocationResult echoWithSimpleTypeArrays(
+ long [] longs,
+ boolean [] booleans,
+ double [] doubles,
+ float [] floats,
+ int [] integers,
+ short [] shorts);
+
+ /**
+ * Echo method that accepts and returns a byte array.
+ *
+ * @param byteArray a byte array
+ * @return a result containing the input byte array (as output parameter)
+ */
+ InvocationResult echoWithByteArray(byte [] byteArray);
+
+ /**
+ * Echo method that accepts and returns an UUID.
+ *
+ * @param uuid a java.util.UUID.
+ * @return a result containing the input UUID (as output parameter)
+ */
+ InvocationResult echoWithUUID(UUID uuid);
+
+ /**
+ * Echo method that accepts and returns a Map.
+ *
+ * @param map a java.util.Map.
+ * @return a result containing the input Map (as output parameter)
+ */
+ InvocationResult echoWithMap(Map<String,Object> map);
+
+ /**
+ * Returns the VHostRef property value.
+ *
+ * @return the VHostRef property value.
+ */
+ UUID getVhostRef();
+
+ /**
+ * Returns the name property value.
+ *
+ * @return the name property value.
+ */
+ String getName();
+
+ /**
+ * Returns the durable property value.
+ *
+ * @return the durable property value.
+ */
+ Boolean getDurable();
+
+ /**
+ * Returns the arguments property value.
+ *
+ * @return the arguments property value.
+ */
+ Map<String, Object> getArguments();
+
+ /**
+ * Returns the msgTotalEnqueues property value.
+ *
+ * @return the msgTotalEnqueues property value.
+ */
+ Long getMsgTotalEnqueues();
+
+ /**
+ * Returns the consumerCount property value.
+ *
+ * @return the consumerCount property value.
+ */
+ Integer getConsumerCount();
+
+ /**
+ * Returns the mgmtPubInterval property value.
+ *
+ * @return the mgmtPubInterval property value.
+ */
+ Short getMgmtPubInterval();
+
+ /**
+ * Sets the mgmtPubInterval property value.
+ *
+ * @param the mgmtPubInterval property value.
+ */
+ void setMgmtPubInterval(Short mgmtPubInterval);
+
+ /**
+ * Returns the expireTime property value.
+ *
+ * @return the expireTime property value.
+ */
+ Date getExpireTime();
+
+ /**
+ * Sets the expireTime property value.
+ *
+ * @return the expireTime property value.
+ */
+ void setExpireTime(Date expireTime);
+
+ /**
+ * Returns the type property value.
+ *
+ * @return the type property value.
+ */
+ void setType(String type);
+
+ /**
+ * Sets the type property value.
+ *
+ * @return the type property value.
+ */
+ String getType();
+
+// /**
+// * Returns the byteArray property value.
+// *
+// * @return the byteArray property value.
+// */
+// byte[] getByteArray();
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java
new file mode 100644
index 0000000000..4564acc9d0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java
@@ -0,0 +1,217 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.handler.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.domain.handler.base.BaseMessageHandler;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * Schema Response message handler.
+ * This handler is responsible to process 'S'(opcode) messages sent by the management broker containing the full
+ * schema details for a class.
+ *
+ * @author Andrea Gazzarini
+ */
+public class SchemaResponseMessageHandler extends BaseMessageHandler
+{
+ /**
+ * Behavioural interface for classes that are responsible to deal with schema messages.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface IProcessor
+ {
+ /**
+ * Processes the incoming message using the given decoder.
+ *
+ * @param decoder the decoder used for dealing with incoming message.
+ */
+ void process(Decoder decoder);
+ }
+
+ /**
+ * Processor responsible to deal with class schema related messages.
+ */
+ final IProcessor _classSchemaProcessor = new IProcessor()
+ {
+ public void process(Decoder decoder)
+ {
+ try
+ {
+ String packageName = decoder.readStr8();
+ String className = decoder.readStr8();
+
+ Binary schemaHash = new Binary(decoder.readBin128());
+
+ int howManyProperties = decoder.readUint16();
+ int howManyStatistics = decoder.readUint16();
+ int howManyMethods = decoder.readUint16();
+
+ _domainModel.addSchema(
+ packageName,
+ className,
+ schemaHash,
+ getAttributes(decoder, howManyProperties),
+ getAttributes(decoder, howManyStatistics),
+ getMethods(decoder, howManyMethods));
+ } catch(Exception exception)
+ {
+ _logger.error(exception,Messages.QMAN_100005_CLASS_SCHEMA_PROCESSING_FAILURE);
+ }
+ }
+ };
+
+ /**
+ * Processor responsible to deal with class event related messages.
+ */
+ final IProcessor _eventSchemaProcessor = new IProcessor()
+ {
+ public void process(Decoder decoder)
+ {
+ try
+ {
+ String packageName = decoder.readStr8();
+ String className = decoder.readStr8();
+ Binary hash = new Binary(decoder.readBin128());
+ int howManyArguments = decoder.readUint16();
+
+ _domainModel.addEventSchema(
+ packageName,
+ className,
+ hash,
+ getAttributes(decoder, howManyArguments));
+ } catch(Exception exception)
+ {
+ _logger.error(exception,Messages.QMAN_100006_EVENT_SCHEMA_PROCESSING_FAILURE);
+ }
+ }
+ };
+
+ /**
+ * Processes an incoming schema response.
+ * This will be used for building the corresponding class definition.
+ *
+ * @param decoder the decoder used for parsing the incoming stream.
+ * @param sequenceNumber the sequence number of the incoming message.
+ */
+ public void process (Decoder decoder, int sequenceNumber)
+ {
+ try
+ {
+ int classKind = decoder.readUint8();
+ switch(classKind)
+ {
+ case Protocol.CLASS :
+ {
+ _classSchemaProcessor.process(decoder);
+ break;
+ }
+ case Protocol.EVENT :
+ {
+ _eventSchemaProcessor.process(decoder);
+ break;
+ }
+ default :
+ {
+ _logger.error(Messages.QMAN_100011_UNKNOWN_CLASS_KIND,classKind);
+ }
+ }
+ } catch(Exception exception)
+ {
+ _logger.error(exception,Messages.QMAN_100012_SCHEMA_MESSAGE_PROCESSING_FAILURE);
+ }
+ }
+
+ /**
+ * Reads from the incoming message stream the properties definitions.
+ *
+ * @param decoder the decoder used for decode incoming data.
+ * @param howManyProperties the number of properties to read.
+ * @return a list of maps. Each map contains a property definition.
+ */
+ List<Map<String, Object>> getAttributes(Decoder decoder,int howMany)
+ {
+ List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(howMany);
+ for (int i = 0; i < howMany; i++ )
+ {
+ result.add(decoder.readMap());
+ }
+ return result;
+ }
+
+ /**
+ * Reads the methods definitions from the incoming message stream.
+ *
+ * @param decoder the decoder used for decode incoming data.
+ * @param howManyMethods the number of methods to read.
+ * @return a list method definitions.
+ */
+ List<MethodOrEventDataTransferObject> getMethods(Decoder decoder, int howManyMethods)
+ {
+ List<MethodOrEventDataTransferObject> result = new ArrayList<MethodOrEventDataTransferObject>(howManyMethods);
+ for (int i = 0; i < howManyMethods; i++)
+ {
+ Map<String,Object> method = decoder.readMap();
+ int howManyArguments = (Integer) method.get(Names.ARG_COUNT_PARAM_NAME);
+
+ List<Map<String,Object>> arguments = new ArrayList<Map<String,Object>>(howManyArguments);
+ for (int argIndex = 0; argIndex < howManyArguments; argIndex++)
+ {
+ arguments.add(decoder.readMap());
+ }
+ result.add(new MethodOrEventDataTransferObject(method,arguments));
+ }
+ return result;
+ }
+
+ /**
+ * Reads the events definitions from the incoming message stream.
+ *
+ * @param decoder the decoder used for decode incoming data.
+ * @param howManyEvents the number of events to read.
+ * @return a list event definitions.
+ */
+ List<MethodOrEventDataTransferObject> getEvents(Decoder decoder, int howManyEvents)
+ {
+ List<MethodOrEventDataTransferObject> result = new ArrayList<MethodOrEventDataTransferObject>(howManyEvents);
+ for (int i = 0; i < howManyEvents; i++)
+ {
+ Map<String,Object> method = decoder.readMap();
+ int howManyArguments = (Integer) method.get(Names.ARG_COUNT_PARAM_NAME);
+
+ List<Map<String,Object>> arguments = new ArrayList<Map<String,Object>>(howManyArguments);
+ for (int argIndex = 0; argIndex < howManyArguments; argIndex++)
+ {
+ arguments.add(decoder.readMap());
+ }
+ result.add(new MethodOrEventDataTransferObject(method,arguments));
+ }
+ return result;
+ }
+ }
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/AccessMode.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/AccessMode.java
new file mode 100644
index 0000000000..6d1426c122
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/AccessMode.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.management.domain.model;
+
+/**
+ * Enumeration for Access modes.
+ *
+ * @author Andrea Gazzarini
+ */
+public enum AccessMode
+{
+ RC { @Override public String toString() { return "Read-Create"; }},
+ RO { @Override public String toString() { return "Read-Only"; }},
+ RW { @Override public String toString() { return "Read-Write"; }}
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/Direction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/Direction.java
new file mode 100644
index 0000000000..8166c35eb6
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/Direction.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.management.domain.model;
+
+/**
+ * Enumeration of allowed method argument direction codes.
+ *
+ * @author Andrea Gazzarini
+ */
+public enum Direction
+{
+ I{ @Override public String toString() { return "Input"; }},
+ O{ @Override public String toString() { return "Output"; }},
+ IO{ @Override public String toString() { return "Input-Output"; }};
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java
new file mode 100644
index 0000000000..5a0ebaf1f7
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java
@@ -0,0 +1,239 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.management.domain.handler.impl.IMethodInvocationListener;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Broker domain model.
+ * This is the local representation of a remote broker domain model.
+ *
+ * @author Andrea Gazzarini
+ */
+public class DomainModel
+{
+ private final UUID _id;
+
+ /** Here the known packages of the remote broker are stored. */
+ Map<String,QpidPackage> _packages = new HashMap<String, QpidPackage>();
+
+ private Date _lastRefreshDate = new Date();
+
+ private IMethodInvocationListener _methodInvocationListener;
+
+ /**
+ * Builds a new domain model with the given broker identifier.
+ *
+ * @param brokerId the broker identifier.
+ */
+ public DomainModel(UUID brokerId)
+ {
+ this._id = brokerId;
+ }
+
+ /**
+ * Returns the identifier of the broker associated with this domain model.
+ *
+ * @return the identifier of the broker associated with this domain model.
+ */
+ public UUID getBrokerId()
+ {
+ return _id;
+ }
+
+ /**
+ * Adds the specified schema to this domain model.
+ *
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param classHash the class schema hash.
+ * @param properties the class properties.
+ * @param statistics the class statistics.
+ * @param methods the class methods.
+ * @throws UnableToBuildFeatureException
+ */
+ public void addSchema(
+ String packageName,
+ String className,
+ Binary classHash,
+ List<Map<String, Object>> properties,
+ List<Map<String, Object>> statistics,
+ List<MethodOrEventDataTransferObject> methods) throws UnableToBuildFeatureException
+ {
+ QpidPackage qpidPackage = getPackageByName(packageName);
+ qpidPackage.addClassDefinition(className,classHash,properties,statistics,methods);
+ }
+
+ /**
+ * Updates the last refresh date.
+ */
+ public void updateLastRefreshDate()
+ {
+ this._lastRefreshDate = new Date();
+ }
+
+ /**
+ * Returns the last refresh date.
+ *
+ * @return the last refresh date.
+ */
+ public Date getLastRefreshDate()
+ {
+ return _lastRefreshDate;
+ }
+
+ /**
+ * Adds the specified schema to this domain model.
+ *
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param classHash the class schema hash.
+ * @param properties the class properties.
+ * @param statistics the class statistics.
+ * @param methods the class methods.
+ * @throws UnableToBuildFeatureException
+ */
+ public void addEventSchema(
+ String packageName,
+ String className,
+ Binary classHash,
+ List<Map<String, Object>> arguments) throws UnableToBuildFeatureException
+ {
+ QpidPackage qpidPackage = getPackageByName(packageName);
+ qpidPackage.addEventDefinition(className,classHash,arguments);
+ }
+
+ /**
+ * Gets the package with the specified name.
+ * Note that if the package doesn't exist a new one will be created and returned.
+ *
+ * @param packageName the name of the package.
+ * @return the package.
+ */
+ QpidPackage getPackageByName (String packageName)
+ {
+ QpidPackage qpidPackage = _packages.get(packageName);
+ if (qpidPackage == null)
+ {
+ qpidPackage = new QpidPackage(packageName,this);
+ _packages.put(packageName, qpidPackage);
+ }
+ return qpidPackage;
+ }
+
+ /**
+ * Returns true if a package with the specified name already exists on this domain model.
+ *
+ * @param packageName the name of the package.
+ * @return true if the package exists, false otherwise.
+ */
+ boolean containsPackage (String packageName)
+ {
+ return _packages.containsKey(packageName);
+ }
+
+ /**
+ * Adds the given instrumentation data (raw format) to this domain model.
+ * Note that this data is belonging to a specific object instance.
+ *
+ * @param packageName the name of the ower package.
+ * @param className the name of the owner class.
+ * @param classHash the schema hash for this class.
+ * @param objectId the object instance identifier.
+ * @param rawData the instrumentation data.
+ */
+ public void addInstrumentationRawData (String packageName, String className,Binary classHash, Binary objectId, byte[] rawData)
+ {
+ QpidPackage qpidPackage = getPackageByName(packageName);
+ qpidPackage.setObjectInstanceInstrumentationRawData(className,classHash,objectId,rawData);
+ }
+
+ public void addEventRawData (
+ String packageName,
+ String eventName,
+ Binary eventHash,
+ byte[] rawData,
+ long currentTimestamp,
+ int severity)
+ {
+ QpidPackage qpidPackage = getPackageByName(packageName);
+ qpidPackage.setEventInstanceRawData(eventName,eventHash,rawData,currentTimestamp,severity);
+ }
+
+ /**
+ * Adds the given configuration data (raw format) to this domain model.
+ * Note that this data is belonging to a specific object instance.
+ *
+ * @param packageName the name of the ower package.
+ * @param className the name of the owner class.
+ * @param classHash the schema hash for this class.
+ * @param objectId the object instance identifier.
+ * @param rawData the configuration data.
+ */
+ public void addConfigurationRawData (String packageName, String className, Binary classHash,Binary objectId, byte[] rawData)
+ {
+ QpidPackage qpidPackage = getPackageByName(packageName);
+ qpidPackage.setObjectInstanceConfigurationRawData(className,classHash,objectId,rawData);
+ }
+
+ /**
+ * Removes the object instance associated to the given parameters.
+ *
+ * @param packageName the owner package.
+ * @param className the class definition of the object instance.
+ * @param classHash the class hash
+ * @param objectId the object identifier.
+ */
+ public void removeObjectInstance (String packageName, String className, Binary classHash, Binary objectId)
+ {
+ QpidPackage qpidPackage = getPackageByName(packageName);
+ qpidPackage.removeObjectInstance(className, classHash, objectId);
+ }
+
+ /**
+ * Releases all the resources kept by domain model entitiies.
+ */
+ public void releaseResources()
+ {
+ for (QpidPackage qpidPackage : _packages.values())
+ {
+ qpidPackage.releaseResources();
+ }
+ }
+
+ public void setMethodInvocationListener(IMethodInvocationListener listener)
+ {
+ this._methodInvocationListener = listener;
+ }
+
+ IMethodInvocationListener getMethodInvocationListener ()
+ {
+ return _methodInvocationListener;
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/IncomingNetworkTransport.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/IValidator.java
index 7099916c33..1ede559145 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/IncomingNetworkTransport.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/IValidator.java
@@ -18,13 +18,21 @@
* under the License.
*
*/
-package org.apache.qpid.transport.network;
+package org.apache.qpid.management.domain.model;
-import org.apache.qpid.protocol.ProtocolEngineFactory;
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.transport.NetworkTransportConfiguration;
-
-public interface IncomingNetworkTransport extends NetworkTransport
+/**
+ * Interface definition for attribute validators.
+ *
+ * @author Andrea Gazzarini
+ */
+interface IValidator
{
- public void accept(NetworkTransportConfiguration config, ProtocolEngineFactory factory, SSLContextFactory sslFactory);
+ /**
+ * Validates the given value according to the rules definied by this validator.
+ *
+ * @param value the value be checked.
+ *
+ * @throws ValidationException when the value is violating validator's rules.
+ */
+ void validate(Object value) throws ValidationException;
} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/InvocationEvent.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/InvocationEvent.java
new file mode 100644
index 0000000000..d84a018346
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/InvocationEvent.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.management.domain.model;
+
+import java.util.EventObject;
+import java.util.concurrent.BlockingQueue;
+
+import org.apache.qpid.management.domain.handler.impl.InvocationResult;
+
+/**
+ * Operation invocation event.
+ * This encapsulates all the information that a method invocation listener needs to know about an operation which is
+ * going to be invoked.
+ *
+ * @author Andrea Gazzarini
+ */
+public class InvocationEvent extends EventObject
+{
+ private static final long serialVersionUID = 240229490753008597L;
+
+ private final int _sequenceNumber;
+ private final BlockingQueue<InvocationResult> _exchangeChannel;
+
+ /**
+ * Builds a new invocation event with the given data.
+ *
+ * @param source the event source.
+ * @param sequenceNumber the sequence number of the method invocation.
+ * @param exchangeChannel the exchange channel for synchronous communication.
+ */
+ InvocationEvent(Object source, int sequenceNumber, BlockingQueue<InvocationResult> exchangeChannel)
+ {
+ super(source);
+ this._sequenceNumber = sequenceNumber;
+ this._exchangeChannel = exchangeChannel;
+ }
+
+ /**
+ * Returns the sequence number that will be / has been used for method invocation.
+ *
+ * @return the sequence number that will be / has been used for method invocation.
+ */
+ public int getSequenceNumber()
+ {
+ return _sequenceNumber;
+ }
+
+ /**
+ * Returns the exchange channel that will be used between event source and event listener for synchronous
+ * communication.
+ *
+ * @return the exchange channel that will be used for synchronous communication.
+ */
+ public BlockingQueue<InvocationResult> getExchangeChannel()
+ {
+ return _exchangeChannel;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java
new file mode 100644
index 0000000000..657d7e6210
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java
@@ -0,0 +1,410 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model;
+
+import java.lang.management.ManagementFactory;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.management.MBeanException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.model.QpidClass.QManManagedObject;
+import org.apache.qpid.management.domain.model.QpidEvent.QManManagedEvent;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.management.domain.services.QMan;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * A simple facade used to perform operations on Mbean server.
+ */
+public class JmxService
+{
+ private final static Logger LOGGER = Logger.get(JmxService.class);
+ MBeanServer _mxServer = ManagementFactory.getPlatformMBeanServer();
+
+ /**
+ * Registers QMan with the MBeanServer.
+ * After that QMan management interface will be JMX-exposed.
+ *
+ * @param qman QMan
+ * @throws MBeanException when some error occurs during registration.
+ */
+ public void registerQManService(QMan qman) throws MBeanException
+ {
+ if (!_mxServer.isRegistered(Names.QMAN_OBJECT_NAME))
+ {
+ try {
+ _mxServer.registerMBean(qman, Names.QMAN_OBJECT_NAME);
+ } catch (Exception exception) {
+ throw new MBeanException(exception);
+ }
+ }
+ }
+
+ /**
+ * Registers an event instance with MBean server.
+ *
+ * @param eventInstance the mben event instance
+ * @param brokerId the broker identifier.
+ * @param packageName the package name.
+ * @param eventClassName the event class name.
+ * @return the object name used for registration.
+ */
+ ObjectName registerEventInstance(
+ QManManagedEvent eventInstance,
+ UUID brokerId,
+ String packageName,
+ String eventClassName)
+ {
+ ObjectName name = createEventName(brokerId, packageName, eventClassName);
+ if (!_mxServer.isRegistered(name))
+ {
+ try
+ {
+ _mxServer.registerMBean(eventInstance, name);
+
+ LOGGER.debug(
+ Messages.QMAN_200010_EVENT_MBEAN_REGISTERED,
+ brokerId,
+ packageName,
+ eventClassName,
+ name);
+ } catch (Exception exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+ return name;
+}
+
+ /**
+ * Registers a pre-existing object instance as an MBean with the MBean
+ * server.
+ *
+ * @param instance the object instance.
+ * @param brokerId the broker identifier.
+ * @param packageName the name of the package containing this instance.
+ * @param className the name of the owner class of this instance.
+ * @param objectId the object instance identifier.
+ * @return the object name used for registration.
+ */
+ ObjectName registerObjectInstance(
+ QManManagedObject instance,
+ UUID brokerId,
+ String packageName,
+ String className,
+ Binary objectId)
+ {
+ ObjectName name = createObjectName(brokerId, packageName, className, objectId);
+ if (!_mxServer.isRegistered(name))
+ {
+ try
+ {
+ _mxServer.registerMBean(instance, name);
+
+ LOGGER.debug(
+ Messages.QMAN_200011_OBJECT_MBEAN_REGISTERED,
+ brokerId,
+ packageName,
+ className,
+ objectId,
+ name);
+ } catch (Exception exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+ return name;
+ }
+
+ /**
+ * Removes / unregisters a managed object instance from the MBean Server.
+ *
+ * @param brokerId the broker identifier.
+ * @param packageName the name of the package containing this instance.
+ * @param className the name of the owner class of this instance.
+ * @param objectId the object instance identifier.
+ * @return obejctName the obejct name used for deregistration.
+ */
+ ObjectName unregisterObjectInstance(
+ UUID brokerId,
+ String packageName,
+ String className,
+ Binary objectId)
+ {
+ ObjectName name = createObjectName(brokerId, packageName, className, objectId);
+ if (_mxServer.isRegistered(name))
+ {
+ try
+ {
+ _mxServer.unregisterMBean(name);
+
+ LOGGER.debug(
+ Messages.QMAN_200012_OBJECT_MBEAN_UNREGISTERED,
+ brokerId,
+ packageName,
+ className,
+ objectId,
+ name);
+ } catch (Exception exception)
+ {
+ LOGGER.error(exception,Messages.QMAN_100013_MBEAN_REGISTRATION_FAILURE,name);
+ }
+ }
+ return name;
+ }
+
+ /**
+ * Removes (unregister) all events from MBean Server.
+ */
+ void unregisterEvents()
+ {
+ for (ObjectName name : getEventMBeans())
+ {
+ try
+ {
+ _mxServer.unregisterMBean(name);
+ } catch(Exception ignore)
+ {
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ Set<ObjectName> getEventMBeans()
+ {
+ return _mxServer.queryNames(createEventSearchName(),null);
+ }
+
+ /**
+ * Removes (unregister) all object instances from MBean Server.
+ */
+ @SuppressWarnings("unchecked")
+ void unregisterObjectInstances()
+ {
+ Set<ObjectName> names = _mxServer.queryNames(createObjectInstanceSearchName(),null);
+ for (ObjectName name : names)
+ {
+ try
+ {
+ _mxServer.unregisterMBean(name);
+ } catch(Exception ignore)
+ {
+ }
+ }
+ }
+
+ /**
+ * Factory method for ObjectNames.
+ *
+ * @param brokerId the broker identifier.
+ * @param packageName the name of the package containing this instance.
+ * @param className the name of the owner class of this instance.
+ * @param objectId the object instance identifier.
+ * @return the object name built according to the given parameters.
+ */
+ private ObjectName createObjectName(UUID brokerId, String packageName, String className, Binary objectId)
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(':')
+ .append(Names.BROKER_ID)
+ .append('=')
+ .append(brokerId)
+ .append(",type=Object,")
+ .append(Names.PACKAGE)
+ .append('=')
+ .append(packageName)
+ .append(',')
+ .append(Names.CLASS)
+ .append('=')
+ .append(className)
+ .append(',')
+ .append(Names.OBJECT_ID)
+ .append('=')
+ .append(objectId)
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ /**
+ * Creates an object name that will be used for searching all registered events.
+ *
+ * @return the object name that will be used for searching all registered events.
+ */
+ ObjectName createEventSearchName()
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(':')
+ .append('*')
+ .append(",type=Event")
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ /**
+ * Creates an object name that will be used for searching all registered events.
+ *
+ * @return the object name that will be used for searching all registered events.
+ */
+ ObjectName createClassDefinitionSearchName()
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(":Category=Schema,*")
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ /**
+ * Creates an object name that will be used for searching all registered object instances.
+ *
+ * @return the object name that will be used for searching all registered object instances.
+ */
+ private ObjectName createObjectInstanceSearchName()
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(':')
+ .append('*')
+ .append(",type=Object")
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ /**
+ * Factory method for ObjectNames.
+ *
+ * @param brokerId the broker identifier.
+ * @param packageName the name of the package containing this instance.
+ * @param className the name of the owner class of this instance.
+ * @return the object name built according to the given parameters.
+ */
+ private ObjectName createEventName(UUID brokerId, String packageName, String className)
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(':')
+ .append(Names.BROKER_ID)
+ .append('=')
+ .append(brokerId)
+ .append(",type=Event,")
+ .append(Names.PACKAGE)
+ .append('=')
+ .append(packageName)
+ .append(',')
+ .append(Names.CLASS)
+ .append('=')
+ .append(className)
+ .append(',')
+ .append(Names.OBJECT_ID)
+ .append('=')
+ .append(UUID.randomUUID())
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ ObjectName createEntityDefinitionName(String packageName, String className, String type)
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(':')
+ .append("Category=Schema,Type=")
+ .append(type)
+ .append(",package=")
+ .append(packageName)
+ .append(",name=")
+ .append(className)
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ public void registerEntityDefinition(ObjectName name, QpidEntity entity,String packageName, String className)
+ {
+ try
+ {
+ if (!_mxServer.isRegistered(name))
+ _mxServer.registerMBean(entity, name);
+ _mxServer.addNotificationListener(name, Names.QMAN_OBJECT_NAME, null, null);
+ } catch(Exception exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void unregisterClassDefinitions()
+ {
+ Set<ObjectName> names = _mxServer.queryNames(createClassDefinitionSearchName(),null);
+ for (ObjectName name : names)
+ {
+ try
+ {
+ _mxServer.unregisterMBean(name);
+ } catch(Exception ignore)
+ {
+ }
+ }
+
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/MissingFeatureAttributesException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/MissingFeatureAttributesException.java
new file mode 100644
index 0000000000..160054059b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/MissingFeatureAttributesException.java
@@ -0,0 +1,35 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model;
+
+import java.util.List;
+
+import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute;
+
+public class MissingFeatureAttributesException extends UnableToBuildFeatureException
+{
+ private static final long serialVersionUID = 671471705085787235L;
+
+ public MissingFeatureAttributesException(List<Attribute> missingAttributeList)
+ {
+ super(String.valueOf(missingAttributeList));
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java
new file mode 100644
index 0000000000..e126fcb8f5
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java
@@ -0,0 +1,123 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.transport.codec.Encoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * An argument is the formal definition of a parameter belonging to a specific method / operation.
+ */
+class QpidArgument extends QpidProperty
+{
+ private final static Logger LOGGER = Logger.get(QpidArgument.class);
+
+ private Object _defaultValue;
+
+ private Direction _direction;
+
+ /**
+ * Sets the direction of this argument.
+ *
+ * @param the direction of this argument.
+ */
+ public void setDirection(String code)
+ {
+ this._direction = Direction.valueOf(code);
+ }
+
+ /**
+ * Returns the direction of this argument.
+ *
+ * @return the direction of this argument.
+ */
+ public Direction getDirection()
+ {
+ return _direction;
+ }
+
+ /**
+ * Sets the default value of this argument.
+ *
+ * @param defaultValue the default value of this argument.
+ */
+ public void setDefaultValue(Object defaultValue)
+ {
+ this._defaultValue = defaultValue;
+ }
+
+ /**
+ * Returns the default value of this argument.
+ *
+ * @return the default value of this argument.
+ */
+ public Object getDefaultValue()
+ {
+ return _defaultValue;
+ }
+
+ /**
+ * Returns true if this is an Input argument.
+ *
+ * @return true if this is an Input argument.
+ */
+ public boolean isInput()
+ {
+ return _direction != Direction.O;
+ }
+
+ @Override
+ public String toString ()
+ {
+ return new StringBuilder()
+ .append(getJavaType().getName())
+ .append(' ')
+ .append(_name)
+ .append("(")
+ .append(_direction)
+ .append(")")
+ .toString();
+ }
+
+ /**
+ * Encodes the given value according to this argument type & definition.
+ *
+ * @param value the value to be encoded.
+ * @param encoder the encoder.
+ */
+ public void encode(Object value,Encoder encoder)
+ {
+ _type.encode(value, encoder);
+ LOGGER.debug(Messages.QMAN_200013_ARGUMENT_VALUE_ENCODED,value,_name,_type);
+ }
+
+ /**
+ * Decodes the value for this argument according to its type & definition.
+ *
+ * @param decoder the decoder
+ * @return the decoded value of this argument.
+ */
+ public Object decode(org.apache.qpid.transport.codec.Decoder decoder)
+ {
+ return _type.decode(decoder);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidAttribute.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidAttribute.java
new file mode 100644
index 0000000000..6712a14075
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidAttribute.java
@@ -0,0 +1,105 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.domain.model.type.Type;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Layer supertype for qpid properties and statistics.
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidAttribute extends QpidFeature
+{
+ private final static Logger LOGGER = Logger.get(QpidAttribute.class);
+
+ /** feature type */
+ protected Type _type;
+
+ /** feature unit */
+ protected String _unit;
+
+ /**
+ * Returns the units used for numeric values (i.e. seconds, bytes, etc.)
+ *
+ * @return the units used for numeric values (i.e. seconds, bytes, etc.)
+ */
+ String getUnit ()
+ {
+ return _unit;
+ }
+
+ /**
+ * Sets the unit for this property.
+ *
+ * @param unit the unit of this property.
+ */
+ void setUnit (String unit)
+ {
+ this._unit = unit;
+ }
+
+ /**
+ * Returns the java type (class) of this feature.
+ *
+ * @return the java type (class) of this feature.
+ */
+ Class<?> getJavaType ()
+ {
+ return _type.getJavaType();
+ }
+
+ /**
+ * Sets the type of this feature.
+ *
+ * @param type the type of this feature.
+ */
+ void setType (Type type)
+ {
+ this._type = type;
+ }
+
+ /**
+ * Gets the value of this feature according to its type definition.
+ *
+ * @param decoder the decoder used to extract the value.
+ * @return the value of this feature according to its type definition
+ */
+ Object decodeValue(Decoder decoder)
+ {
+ try {
+ return _type.decode(decoder);
+ } catch(RuntimeException exception)
+ {
+ LOGGER.error(exception,Messages.QMAN_100014_ATTRIBUTE_DECODING_FAILURE,this);
+ throw exception;
+ }
+ }
+
+ @Override
+ public String toString ()
+ {
+ return super.toString()+",type="+_type;
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java
new file mode 100644
index 0000000000..667e600668
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java
@@ -0,0 +1,833 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.Map.Entry;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.RuntimeOperationsException;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.handler.impl.IMethodInvocationListener;
+import org.apache.qpid.management.domain.handler.impl.InvocationResult;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.management.domain.services.SequenceNumberGenerator;
+import org.apache.qpid.management.jmx.EntityLifecycleNotification;
+import org.apache.qpid.management.jmx.OperationHasBeenInvokedNotification;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Qpid Class definition.
+ * A type definition for a manageable object.
+ * This class is also responsible to manage incoming obejct instance data (configuration & instrumentation).
+ * How can we handle data before schema is injected into this class? simply we must retain that data in raw format.
+ * This class has 3 states :
+ * 1) first state is when schema is not yet injected. In this case the incoming object data is retained as is (in raw format)
+ * and a schema request is sent;
+ * 2) second state is when schema has been requested but not yet injected. The incoming object data is still retained as is
+ * (in raw format)
+ * 3) third state is when schema is injected. Each injection of data will result in an update / create / delete of
+ * the corresponding object instance. In addition, the first time the state change, the old retained raw data is cnverted in
+ * object instance(s).
+ */
+class QpidClass extends QpidEntity implements QpidClassMBean
+{
+ /**
+ * State interface for this class definition.
+ * Each state is responsible to handle the injection of the data and / or schema.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface State
+ {
+ /**
+ * Adds configuration data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw configuration data.
+ */
+ void addInstrumentationData (Binary objectId, byte[] rawData);
+
+ /**
+ * Adds instrumentation data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw instrumentation data.
+ */
+ void addConfigurationData (Binary objectId, byte[] rawData);
+
+ /**
+ * Inject the schema into this class definition.
+ *
+ * @param propertyDefinitions
+ * @param statisticDefinitions
+ * @param methodDefinitions
+ * @throws UnableToBuildFeatureException when it's not possibile to parse schema and build the class definition.
+ */
+ public void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException;
+ };
+
+ /**
+ * This is the initial state of every qpid class.
+ * The class definition instance is created but its schema has not been injected.
+ * Incoming configuration & instrumentation data will be stored in raw format because we don't know how to
+ * parse it until the schema arrives.
+ * In addition, this state is responsible (when data arrives) to request its schema.
+ */
+ final State _schemaNotRequested = new State() {
+
+ /**
+ * Stores the incoming data in raw format and request the schema for this class.
+ * After that a transition to the next state is made.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming configuration data.
+ */
+ public synchronized void addConfigurationData (Binary objectId, byte[] rawData)
+ {
+ try
+ {
+ requestSchema();
+ _state = _schemaRequestedButNotYetInjected;
+ } catch (Exception exception)
+ {
+ _logger.error(
+ exception,
+ Messages.QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST,
+ _parent.getName(),
+ _name);
+ } finally {
+ QManManagedObject instance = getObjectInstance(objectId,false);
+ instance._rawConfigurationData.add(rawData);
+ }
+ }
+
+ /**
+ * Stores the incoming data in raw format and request the schema for this class.
+ * After that a transition to the next state is made.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming instrumentation data.
+ */
+ public synchronized void addInstrumentationData (Binary objectId, byte[] rawData)
+ {
+ try
+ {
+ requestSchema();
+ _state = _schemaRequestedButNotYetInjected;
+ } catch (Exception e)
+ {
+ _logger.error(
+ Messages.QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST,
+ _parent.getName(),
+ _name);
+ } finally {
+ QManManagedObject instance = getObjectInstance(objectId,false);
+ instance._rawConfigurationData.add(rawData);
+ }
+ }
+
+ /**
+ * This method only throws an illegal state exception because when a schema arrives
+ * this state is no longer valid.
+ */
+ public void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
+ {
+ throw new IllegalStateException("When a schema arrives it's not possible for this class to be in this state.");
+ }
+ };
+
+ /**
+ * This is the first state of this class definition : the schema is not yet injected so each injection of object data will be
+ * retained in raw format.
+ */
+ final State _schemaRequestedButNotYetInjected = new State()
+ {
+ /**
+ * Stores the incoming data in raw format.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming configuration data.
+ */
+ public void addConfigurationData (Binary objectId, byte[] rawData)
+ {
+ QManManagedObject instance = getObjectInstance(objectId,false);
+ instance._rawConfigurationData.add(rawData);
+ }
+
+ /**
+ * Stores the incoming data in raw format.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming instrumentation data.
+ */
+ public void addInstrumentationData (Binary objectId, byte[] rawData)
+ {
+ QManManagedObject instance = getObjectInstance(objectId,false);
+ instance._rawInstrumentationData.add(rawData);
+ }
+
+ /**
+ * When a schema is injected into this defintiion the following should happen :
+ * 1) the incoming schema is parsed and the class definition is built;
+ * 2) the retained raw data is converted into object instance(s)
+ * 3) the internal state of this class changes;
+ *
+ * If someting is wrong during that process the schema is not built and the state don't change.
+ */
+ public synchronized void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
+ {
+
+ MBeanAttributeInfo [] attributesMetadata = new MBeanAttributeInfo[propertyDefinitions.size()+statisticDefinitions.size()];
+ MBeanOperationInfo [] operationsMetadata = new MBeanOperationInfo[methodDefinitions.size()];
+
+ buildAttributes(propertyDefinitions,statisticDefinitions,attributesMetadata);
+ buildMethods(methodDefinitions,operationsMetadata);
+
+ _metadata = new MBeanInfo(_name,_name,attributesMetadata,null,operationsMetadata,null);
+
+ EntityLifecycleNotification notification = new EntityLifecycleNotification(
+ EntityLifecycleNotification.SCHEMA_INJECTED_NOTIFICATION_TYPE,
+ _parent.getName(),
+ _name,
+ Names.CLASS,
+ _objectName);
+
+ sendNotification(notification);
+
+ // Converting stored object instances into JMX MBean and removing raw instance data.
+ for (Entry<Binary, QManManagedObject> instanceEntry : _objectInstances.entrySet())
+ {
+ Binary objectId = instanceEntry.getKey();
+ QManManagedObject instance = instanceEntry.getValue();
+
+ for (Iterator<byte[]> iterator = instance._rawInstrumentationData.iterator(); iterator.hasNext();)
+ {
+ updateInstanceWithInstrumentationData(instance,iterator.next());
+ iterator.remove();
+ }
+
+ for (Iterator<byte[]> iterator = instance._rawConfigurationData.iterator(); iterator.hasNext();)
+ {
+ updateInstanceWithConfigurationData(instance, iterator.next());
+ iterator.remove();
+ }
+
+ registerMBean(instance,_parent.getOwnerId(),_parent.getName(),_name,objectId);
+ }
+ _state = _schemaInjected;
+
+ }
+ };
+
+ /**
+ * After a schema is built into this definition this is the current state of the class.
+ */
+ final State _schemaInjected = new State()
+ {
+ /**
+ * Updates the configuration state of the object instance associates with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the configuration data (raw format).
+ */
+ public void addConfigurationData (Binary objectId, byte[] rawData)
+ {
+ QManManagedObject instance = getObjectInstance(objectId,true);
+ updateInstanceWithConfigurationData(instance, rawData);
+ }
+
+ /**
+ * Updates the instrumentation state of the object instance associates with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the instrumentation data (raw format).
+ */
+ public void addInstrumentationData (Binary objectId, byte[] rawData)
+ {
+ QManManagedObject instance = getObjectInstance(objectId,true);
+ updateInstanceWithInstrumentationData(instance, rawData);
+ }
+
+ /**
+ * Never called when the class definition has this state.
+ */
+ public void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
+ {
+ throw new IllegalStateException("When a schema arrives it's not possible for this class to be in this state.");
+ }
+ };
+
+ /**
+ * MBean used for representing remote broker object instances.
+ * This is the core component of the QMan domain model
+ */
+ class QManManagedObject extends QManManagedEntity implements MBeanRegistration
+ {
+ private Binary _objectId;
+
+ // Arrays used for storing raw data before this mbean is registered to mbean server.
+ List<byte[]> _rawInstrumentationData = new ArrayList<byte[]>();
+ List<byte[]> _rawConfigurationData = new ArrayList<byte[]>();
+
+ /**
+ * Builds a new managed object with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ */
+ QManManagedObject(Binary objectId)
+ {
+ this._objectId = objectId;
+ }
+
+ /**
+ * Returns the value of the given attribute.s
+ *
+ * @throws AttributeNotFoundException when no attribute is found with the given name.
+ */
+ public Object getAttribute (String attributeName) throws AttributeNotFoundException, MBeanException, ReflectionException
+ {
+ if (attributeName == null)
+ {
+ throw new RuntimeOperationsException(new IllegalArgumentException("attribute name must not be null"));
+ }
+
+ if (_properties.containsKey(attributeName) || _statistics.containsKey(attributeName))
+ {
+ return _attributes.get(attributeName);
+ } else
+ {
+ throw new AttributeNotFoundException(attributeName);
+ }
+ }
+
+ /**
+ * Executes an operation on this object instance.
+ *
+ * @param actionName the name of the method.
+ * @param params the method parameters
+ * @param signature the method signature.
+ */
+ public Object invoke (String actionName, Object[] params, String[] signature) throws MBeanException,ReflectionException
+ {
+ OperationHasBeenInvokedNotification notification = null;
+ try
+ {
+ QpidMethod method = _methods.get(actionName);
+ if (method != null)
+ {
+ try
+ {
+ method.validate(params);
+ InvocationResult result = invokeMethod(_objectId, method, params);
+ notification = new OperationHasBeenInvokedNotification(actionName,params,signature,result);
+ return result;
+ } catch (Exception ex)
+ {
+ MBeanException exception = new MBeanException(ex);
+ notification = new OperationHasBeenInvokedNotification(actionName,params,signature,exception);
+ throw exception;
+ }
+ } else
+ {
+ ReflectionException exception = new ReflectionException(new NoSuchMethodException(actionName));
+ notification = new OperationHasBeenInvokedNotification(actionName,params,signature,exception);
+ throw exception;
+ }
+ } finally
+ {
+ sendNotification(notification);
+ }
+ }
+
+ /**
+ * Sets the value of the given attribute on this object instance.
+ *
+ * @param attribute contains the new value of the attribute.
+ * @throws AttributeNotFoundException when the given attribute is not found on this object instance.
+ * @throws InvalidAttributeValueException when the given value is violating one attribute invariant.
+ */
+ public void setAttribute (Attribute attribute) throws AttributeNotFoundException,
+ InvalidAttributeValueException, MBeanException, ReflectionException
+ {
+ QpidProperty property = _properties.get(attribute.getName());
+ try
+ {
+ property.validate(attribute.getValue());
+ } catch(ValidationException exception)
+ {
+ throw new InvalidAttributeValueException(exception.getMessage());
+ }
+ throw new RuntimeException("Not yet implemented.");
+ }
+
+ /**
+ * Sets the values of several attributes of this MBean.
+ *
+ * @param attributes a list of attributes: The identification of the attributes to be set and the values they are to be set to.
+ * @return The list of attributes that were set, with their new values.
+ */
+ public AttributeList setAttributes (AttributeList attributes)
+ {
+ throw new RuntimeException("Not yet implemented.");
+ }
+
+ /**
+ * MBean server callback after deregistration.
+ */
+ public void postDeregister ()
+ {
+ }
+
+ /**
+ * After the object is registered the raw data is set to null.
+ * This is done because we no longer need this data : it has already been
+ * injected into this object instance.
+ *
+ * @param registrationDone a flag indicating if the instance has been registered to mbean server.
+ */
+ public void postRegister (Boolean registrationDone)
+ {
+ if (registrationDone)
+ {
+ _rawConfigurationData = null;
+ _rawInstrumentationData = null;
+ }
+ }
+
+ /**
+ * MBean server callback before deregistration.
+ */
+ public void preDeregister () throws Exception
+ {
+ }
+
+ /**
+ * MBean server callback before registration.
+ */
+ public ObjectName preRegister (MBeanServer server, ObjectName name) throws Exception
+ {
+ return name;
+ }
+ }
+
+ Map<String, QpidProperty> _properties = new HashMap<String, QpidProperty>();
+ Map<String, QpidStatistic> _statistics = new HashMap<String, QpidStatistic>();
+ private Map<String, QpidMethod> _methods = new HashMap<String, QpidMethod>();
+
+ private List<QpidProperty> _schemaOrderedProperties = new ArrayList<QpidProperty>();
+ private List<QpidStatistic> _schemaOrderedStatistics= new ArrayList<QpidStatistic>();
+
+ private int _howManyPresenceBitMasks;
+ private BlockingQueue<InvocationResult> _exchangeChannelForMethodInvocations;
+ private final IMethodInvocationListener _methodInvocationListener;
+
+ Map<Binary, QManManagedObject> _objectInstances = new HashMap<Binary, QManManagedObject>();
+ State _state = _schemaNotRequested;;
+
+ private final static class Log
+ {
+ private final static Logger LOGGER = Logger.get(QpidClass.class);
+ final static void logMethodInvocationResult(InvocationResult result)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(String.valueOf(result));
+ }
+ }
+ }
+
+ /**
+ * Builds a new class with the given name and package as parent.
+ *
+ * @param className the name of the class.
+ * @param hash the class schema hash.
+ * @param parentPackage the parent of this class.
+ */
+ QpidClass(String className, Binary hash, QpidPackage parentPackage)
+ {
+ super(className,hash, parentPackage,Names.CLASS);
+ this._methodInvocationListener = _parent.getMethodInvocationListener();
+ this._exchangeChannelForMethodInvocations = new SynchronousQueue<InvocationResult>();
+ }
+
+ /**
+ * Adds the configuration data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw configuration data.
+ */
+ void addInstrumentationData (Binary objectId, byte[] rawData)
+ {
+ _logger.debug(
+ Messages.QMAN_200014_INCOMING_INSTRUMENTATION_DATA,
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name,
+ objectId);
+ _state.addInstrumentationData(objectId, rawData);
+ }
+
+ /**
+ * Adds the instrumentation data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw instrumentation data.
+ */
+ void addConfigurationData (Binary objectId, byte[] rawData)
+ {
+ _logger.debug(
+ Messages.QMAN_200015_INCOMING_CONFIGURATION_DATA,
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name,
+ objectId);
+ _state.addConfigurationData(objectId, rawData);
+ }
+
+ /**
+ * Sets the schema for this class definition.
+ * A schema is basically a metadata description of all properties, statistics, methods and events of this class.
+ *
+ * @param propertyDefinitions properties metadata.
+ * @param statisticDefinitions statistics metadata.
+ * @param methodDefinitions methods metadata.
+ * @throws UnableToBuildFeatureException when some error occurs while parsing the incoming schema.
+ */
+ void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
+ {
+ _logger.info(Messages.QMAN_000010_INCOMING_SCHEMA,_parent.getOwnerId(),_parent.getName(),_name);
+ _state.setSchema(propertyDefinitions, statisticDefinitions, methodDefinitions);
+ }
+
+ /**
+ * Internal method used for building attributes definitions.
+ *
+ * @param props the map contained in the properties schema.
+ * @param stats the map contained in the statistics schema.
+ * @param attributes the management metadata for attributes.
+ * @throws UnableToBuildFeatureException when it's not possibile to build one attribute definition.
+ */
+ void buildAttributes (
+ List<Map<String, Object>> props,
+ List<Map<String, Object>> stats,
+ MBeanAttributeInfo[] attributes) throws UnableToBuildFeatureException
+ {
+ int index = 0;
+ int howManyOptionalProperties = 0;
+
+ for (Map<String, Object> propertyDefinition : props)
+ {
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createPropertyBuilder(propertyDefinition);
+ builder.build();
+
+ QpidProperty property = (QpidProperty) builder.getQpidFeature();
+
+ howManyOptionalProperties += (property.isOptional()) ? 1 : 0;
+
+ _properties.put(property.getName(),property);
+ _schemaOrderedProperties.add(property);
+ attributes[index++]=(MBeanAttributeInfo) builder.getManagementFeature();
+
+ _logger.debug(
+ Messages.QMAN_200016_PROPERTY_DEFINITION_HAS_BEEN_BUILT,
+ _parent.getName(),
+ _name,
+ property);
+ }
+
+ _howManyPresenceBitMasks = (int)Math.ceil((double)howManyOptionalProperties / 8);
+
+ _logger.debug(
+ Messages.QMAN_200018_OPTIONAL_PROPERTIES_INFO,
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name,
+ _howManyPresenceBitMasks);
+
+ for (Map<String, Object> statisticDefinition : stats)
+ {
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createStatisticBuilder(statisticDefinition);
+ builder.build();
+ QpidStatistic statistic = (QpidStatistic) builder.getQpidFeature();
+
+ _statistics.put(statistic.getName(),statistic);
+ _schemaOrderedStatistics.add(statistic);
+ attributes[index++]=(MBeanAttributeInfo) builder.getManagementFeature();
+
+ _logger.debug(
+ Messages.QMAN_200017_STATISTIC_DEFINITION_HAS_BEEN_BUILT,
+ _parent.getName(),
+ _name,
+ statistic);
+ }
+ }
+
+ /**
+ * Returns the object instance associated to the given identifier.
+ * Note that if the identifier is not associated to any obejct instance, a new one will be created.
+ *
+ * @param objectId the object identifier.
+ * @param registration a flag indicating whenever the (new ) instance must be registered with MBean server.
+ * @return the object instance associated to the given identifier.
+ */
+ QManManagedObject getObjectInstance(Binary objectId, boolean registration)
+ {
+ QManManagedObject objectInstance = _objectInstances.get(objectId);
+ if (objectInstance == null)
+ {
+ objectInstance = new QManManagedObject(objectId);
+ _objectInstances.put(objectId, objectInstance);
+ if (registration)
+ {
+ registerMBean(objectInstance,_parent.getOwnerId(),_parent.getName(),_name,objectId);
+ }
+ }
+ return objectInstance;
+ }
+
+ /**
+ * Internal method used for building method defintiions.
+ *
+ * @param definitions the properties map contained in the incoming schema.
+ * @param operationsMetadata
+ * @throws UnableToBuildFeatureException when it's not possibile to build one or more definitions.
+ */
+ void buildMethods (List<MethodOrEventDataTransferObject> definitions, MBeanOperationInfo[] operationsMetadata) throws UnableToBuildFeatureException
+ {
+ int index = 0;
+ for (MethodOrEventDataTransferObject definition: definitions)
+ {
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createMethodBuilder(definition);
+ builder.build();
+ operationsMetadata [index++]= (MBeanOperationInfo) builder.getManagementFeature();
+ QpidMethod method = (QpidMethod) builder.getQpidFeature();
+ _methods.put(method.getName(),method);
+ }
+ }
+
+ /**
+ * Header (opcode='M')
+ * ObjectId of target object (128 bits)
+ * Package name (str8)
+ * Class name (str8)
+ * Class hash (bin128)
+ * Method name (str8) [as defined in the schema]
+ * Now encode all input ("I") and i/o (IO) arguments in the order in which they are defined in the schema.
+ * (i.e. make one pass over the argument list and encode arguments that are either input or inptu/output).
+
+ * @param objectId
+ * @param method
+ * @param parameters
+ * @throws Exception
+ */
+ private InvocationResult invokeMethod(Binary objectId,QpidMethod method,Object [] parameters) throws Exception
+ {
+ try
+ {
+ _service.connect();
+
+ int sequenceNumber = SequenceNumberGenerator.getNextSequenceNumber();
+ _methodInvocationListener.operationIsGoingToBeInvoked(new InvocationEvent(this,sequenceNumber,_exchangeChannelForMethodInvocations));
+ _service.invoke(_parent.getName(), _name, _hash,objectId,parameters, method,sequenceNumber,objectId.getBankId(),objectId.getBrokerId());
+
+ InvocationResult result = _exchangeChannelForMethodInvocations.poll(5000,TimeUnit.MILLISECONDS);
+
+ if (result == null)
+ {
+ throw new TimeoutException();
+ }
+
+ Map<String, Object> output = method.decodeParameters(result.getOutputAndBidirectionalArgumentValues());
+ result.setOutputSection(output);
+
+ Log.logMethodInvocationResult(result);
+
+ if (result.isException())
+ {
+ result.createAndThrowException();
+ }
+ return result;
+ } finally
+ {
+ _service.close();
+ }
+ }
+
+ /**
+ * Updates the given obejct instance with the given incoming configuration data.
+ *
+ * @param instance the managed object instance.
+ * @param rawData the incoming configuration data which contains new values for instance properties.
+ */
+ void updateInstanceWithConfigurationData(QManManagedObject instance,byte [] rawData)
+ {
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(ByteBuffer.wrap(rawData));
+
+ byte [] presenceBitMasks = decoder.readBytes(_howManyPresenceBitMasks);
+ for (QpidProperty property : _schemaOrderedProperties)
+ {
+ try {
+ Object value = property.decodeValue(decoder,presenceBitMasks);
+ instance.createOrReplaceAttributeValue(property.getName(),value);
+ } catch(Exception ignore) {
+ _logger.error(Messages.QMAN_100016_UNABLE_TO_DECODE_FEATURE_VALUE, _parent.getName(),_name,property.getName());
+ }
+ }
+ }
+
+ /**
+ * Updates the given object instance with the given incoming instrumentation data.
+ *
+ * @param instance the managed object instance.
+ * @param rawData the incoming instrumentation data which contains new values for instance properties.
+ */
+ void updateInstanceWithInstrumentationData(QManManagedObject instance,byte [] rawData)
+ {
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(ByteBuffer.wrap(rawData));
+
+ for (QpidStatistic statistic : _schemaOrderedStatistics)
+ {
+ try {
+ Object value = statistic.decodeValue(decoder);
+ instance.createOrReplaceAttributeValue(statistic.getName(),value);
+ } catch(Exception ignore) {
+ _logger.error(Messages.QMAN_100016_UNABLE_TO_DECODE_FEATURE_VALUE, _parent.getName(),_name,statistic.getName());
+ }
+ }
+ }
+
+ @Override
+ public String toString ()
+ {
+ return new StringBuilder()
+ .append(_parent.getOwnerId())
+ .append("::")
+ .append(_parent.getName())
+ .append('.')
+ .append(_name)
+ .toString();
+ }
+
+ /**
+ * Removes the object instance associated to the given identifier.
+ *
+ * @param objectId the object identifier.
+ */
+ void removeObjectInstance (Binary objectId)
+ {
+ QManManagedObject toBeRemoved = _objectInstances.remove(objectId);
+ if (toBeRemoved != null)
+ {
+ ObjectName objectName = JMX_SERVICE.unregisterObjectInstance(_parent.getOwnerId(),_parent.getName(),_name,toBeRemoved._objectId);
+
+ EntityLifecycleNotification notification = new EntityLifecycleNotification(
+ EntityLifecycleNotification.INSTANCE_REMOVED_NOTIFICATION_TYPE,
+ _parent.getName(),
+ _name,
+ Names.CLASS,
+ objectName);
+
+ sendNotification(notification);
+ }
+ }
+
+ /**
+ * Deregisters all the object instances and release all previously acquired resources.
+ */
+ void releaseResources ()
+ {
+ _objectInstances.clear();
+ JMX_SERVICE.unregisterObjectInstances();
+ JMX_SERVICE.unregisterClassDefinitions();
+ _service.close();
+ }
+
+ /**
+ * Compose method used for registering mbean instance.
+ *
+ * @param instance the mbean instance.
+ * @param brokerId the broker identifier.
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param objectId the object identifier.
+ */
+ private void registerMBean(
+ QManManagedObject instance,
+ UUID brokerId,
+ String packageName,
+ String className,
+ Binary objectId)
+ {
+ ObjectName objectName = JMX_SERVICE.registerObjectInstance(instance,_parent.getOwnerId(),_parent.getName(),_name,objectId);
+
+ EntityLifecycleNotification notification = new EntityLifecycleNotification(
+ EntityLifecycleNotification.INSTANCE_ADDED_NOTIFICATION_TYPE,
+ packageName,
+ className,
+ Names.CLASS,
+ objectName);
+
+ sendNotification(notification);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClassMBean.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClassMBean.java
new file mode 100644
index 0000000000..eeb4e0e2d8
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClassMBean.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.management.domain.model;
+
+/**
+ * Management interface for Qpid entity class..
+ */
+public interface QpidClassMBean
+{
+ /**
+ * Retruns the name of the class.
+ *
+ * @return the name of the class.
+ */
+ String getName();
+
+ /**
+ * Returns the name of the package.
+ *
+ * @return the name of the package.
+ */
+ String getPackageName();
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java
new file mode 100644
index 0000000000..ea0acb5fd1
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java
@@ -0,0 +1,184 @@
+package org.apache.qpid.management.domain.model;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.DynamicMBean;
+import javax.management.MBeanInfo;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.ObjectName;
+import javax.management.RuntimeOperationsException;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.management.domain.services.QpidService;
+import org.apache.qpid.management.jmx.EntityLifecycleNotification;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Layer supertype for QMan entities.
+ */
+public abstract class QpidEntity extends NotificationBroadcasterSupport
+{
+ /**
+ * Layer supertype for QMan managed bean entities.
+ */
+ abstract class QManManagedEntity implements DynamicMBean
+ {
+ // After mbean is registered with the MBean server this collection holds the mbean attribute values.
+ Map<String,Object> _attributes = new HashMap<String, Object>();
+
+ /**
+ * Creates or replace the given attribute.
+ * Note that this is not part of the management interface of this object instance and therefore will be accessible only
+ * from within this class.
+ * It is used to update directly the object attributes bypassing jmx interface.
+ *
+ * @param attributeName the name of the attribute.
+ * @param property newValue the new value of the attribute.
+ */
+ void createOrReplaceAttributeValue(String attributeName, Object newValue)
+ {
+ _attributes.put(attributeName, newValue);
+ }
+
+ /**
+ * Get the values of several attributes of the Dynamic MBean.
+ *
+ * @param attributes A list of the attributes to be retrieved.
+ *
+ * @return The list of attributes retrieved.
+ */
+ public AttributeList getAttributes (String[] attributes)
+ {
+ if (attributes == null)
+ {
+ throw new RuntimeOperationsException(new IllegalArgumentException("Attributes array must not be null"));
+ }
+
+ AttributeList result = new AttributeList(attributes.length);
+ for (int i = 0; i < attributes.length; i++)
+ {
+ String attributeName = attributes[i];
+ try
+ {
+ result.add(new Attribute(attributeName,getAttribute(attributeName)));
+ } catch(Exception exception)
+ {
+ // Already logged.
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns metadata for this object instance.
+ */
+ // Developer Note : note that this metadata is a member of the outer class definition : in that way we create
+ // that metadata only once and then it will be shared between all object instances (it's a readonly object)
+ public MBeanInfo getMBeanInfo ()
+ {
+ return _metadata;
+ }
+ };
+
+ final Logger _logger = Logger.get(getClass());
+ final static JmxService JMX_SERVICE = new JmxService();
+
+ final String _name;
+ final Binary _hash;
+
+ final QpidPackage _parent;
+ MBeanInfo _metadata;
+ final QpidService _service;
+
+ protected ObjectName _objectName;
+
+ private final String _type;
+
+ /**
+ * Builds a new class with the given name and package as parent.
+ *
+ * @param className the name of the class.
+ * @param hash the class schema hash.
+ * @param parentPackage the parent of this class.
+ */
+ QpidEntity(String className, Binary hash, QpidPackage parentPackage,String type)
+ {
+ this._name = className;
+ this._parent = parentPackage;
+ this._hash = hash;
+ this._type = type;
+ this._service = new QpidService(_parent.getOwnerId());
+
+ _logger.debug(
+ Messages.QMAN_200020_ENTITY_DEFINITION_HAS_BEEN_BUILT,
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name);
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public String getPackageName()
+ {
+ return _parent.getName();
+ }
+
+ /**
+ * Internal method used to send a schema request for this entity.
+ *
+ * @throws Exception when the request cannot be sent.
+ */
+ void requestSchema() throws Exception
+ {
+
+ _objectName = JMX_SERVICE.createEntityDefinitionName(_parent.getName(), _name,_type);
+ JMX_SERVICE.registerEntityDefinition(_objectName,this,_parent.getName(),_name);
+
+ try
+ {
+ _service.connect();
+ _service.requestSchema(_parent.getName(), _name, _hash);
+ _service.sync();
+ } finally
+ {
+ _service.close();
+ }
+
+ EntityLifecycleNotification notification = new EntityLifecycleNotification(
+ EntityLifecycleNotification.SCHEMA_REQUESTED_NOTIFICATION_TYPE,
+ _parent.getName(),
+ _name,
+ Names.CLASS,
+ _objectName);
+ sendNotification(notification);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java
new file mode 100644
index 0000000000..31d8d01fc9
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java
@@ -0,0 +1,493 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.RuntimeOperationsException;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.management.jmx.EntityLifecycleNotification;
+import org.apache.qpid.transport.codec.BBDecoder;
+
+/**
+ * Qpid event definition.
+ */
+class QpidEvent extends QpidEntity implements QpidEventMBean
+{
+
+ /**
+ * State interface for this event definition.
+ * Each state is responsible to handle the injection of the data and / or schema.
+ */
+ interface State
+ {
+ /**
+ * Adds the given data for the object instance associated to the given object identifier.
+ *
+ * @param rawData the raw configuration data.
+ */
+ void addNewEventData (byte[] rawData, long currentTimestamp, int severity);
+
+ /**
+ * Inject the schema into this class definition.
+ *
+ * @param propertyDefinitions
+ * @param statisticDefinitions
+ * @param methodDefinitions
+ * @throws UnableToBuildFeatureException when it's not possibile to parse schema and build the class definition.
+ */
+ public void setSchema (List<Map<String, Object>> agumentDefinitions) throws UnableToBuildFeatureException;
+ };
+
+
+ /**
+ * This is the initial state of every qpid class.
+ * The class definition instance is created but its schema has not been injected.
+ * Incoming configuration & instrumentation data will be stored in raw format because we don't know how to
+ * parse it until the schema arrives.
+ * In addition, this state is responsible (when data arrives) to request its schema.
+ */
+ final State _schemaNotRequested = new State() {
+
+ /**
+ * Stores the incoming data in raw format and request the schema for this class.
+ * After that a transition to the next state is made.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming configuration data.
+ */
+ public synchronized void addNewEventData (byte[] rawData, long currentTimestamp, int severity)
+ {
+ try
+ {
+ requestSchema();
+ _state = _schemaRequestedButNotYetInjected;
+ } catch (Exception exception)
+ {
+ _logger.error(
+ exception,
+ Messages.QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST,
+ _parent.getName(),
+ _name);
+ } finally {
+ createEventInstance(rawData,currentTimestamp,severity);
+ }
+ }
+
+ /**
+ * This method only throws an illegal state exception because when a schema arrives
+ * this state is no longer valid.
+ */
+ public void setSchema (List<Map<String, Object>> agumentDefinitions) throws UnableToBuildFeatureException
+ {
+ throw new IllegalStateException("When a schema arrives it's not possible for this event to be in this state.");
+ }
+ };
+
+ /**
+ * This is the first state of this class definition : the schema is not yet injected so each injection of object data will be
+ * retained in raw format.
+ */
+ final State _schemaRequestedButNotYetInjected = new State()
+ {
+ /**
+ * Stores the incoming data in raw format and request the schema for this class.
+ * After that a transition to the next state is made.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming configuration data.
+ */
+ public synchronized void addNewEventData (byte[] rawData,long currentTimestamp, int severity)
+ {
+ createEventInstance(rawData,currentTimestamp, severity);
+ }
+
+ /**
+ * When a schema is injected into this defintiion the following should happen :
+ * 1) the incoming schema is parsed and the class definition is built;
+ * 2) the retained raw data is converted into object instance(s)
+ * 3) the internal state of this class changes;
+ *
+ * If someting is wrong during that process the schema is not built and the state don't change.
+ */
+ public synchronized void setSchema (List<Map<String, Object>> argumentDefinitions) throws UnableToBuildFeatureException
+ {
+ MBeanAttributeInfo [] attributesMetadata = new MBeanAttributeInfo[argumentDefinitions.size()+2];
+
+ buildArguments(argumentDefinitions, attributesMetadata);
+
+ _metadata = new MBeanInfo(_name,_name,attributesMetadata,null,null,null);
+
+ // Converting stored object instances into JMX MBean and removing raw instance data.
+ for (QManManagedEvent instance : _eventInstances)
+ {
+ updateEventInstanceWithData(instance);
+ registerEventInstance(instance,_parent.getOwnerId(),_parent.getName(),_name);
+ }
+ _state = _schemaInjected;
+
+ EntityLifecycleNotification notification = new EntityLifecycleNotification(
+ EntityLifecycleNotification.SCHEMA_INJECTED_NOTIFICATION_TYPE,
+ _parent.getName(),
+ _name,
+ Names.EVENT,
+ _objectName);
+
+ sendNotification(notification);
+ }
+ };
+
+ /**
+ * After a schema is built into this definition this is the current state of the class.
+ */
+ final State _schemaInjected = new State()
+ {
+ /**
+ * Updates the configuration state of the object instance associates with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the configuration data (raw format).
+ */
+ public void addNewEventData (byte[] rawData,long currentTimestamp, int severity)
+ {
+ QManManagedEvent instance = createEventInstance(rawData,currentTimestamp, severity);
+ updateEventInstanceWithData(instance);
+ registerEventInstance(instance,_parent.getOwnerId(),_parent.getName(),_name);
+ }
+
+ /**
+ * Never called when the class definition has this state.
+ */
+ public void setSchema (List<Map<String, Object>> agumentDefinitions) throws UnableToBuildFeatureException
+ {
+ // N.A. : Schema is already injected.
+ }
+ };
+
+ /**
+ * MBean used for representing remote broker object instances.
+ * This is the core component of the QMan domain model
+ *
+ * @author Andrea Gazzarini
+ */
+ class QManManagedEvent extends QManManagedEntity
+ {
+
+
+ // Arrays used for storing raw data before this mbean is registered to mbean server.
+ final byte[] _rawEventData;
+ final long _timestamp;
+ final int _severity;
+
+ /**
+ * Builds a new managed object with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ */
+ private QManManagedEvent(byte [] data, long timestamp, int severity)
+ {
+ this._rawEventData = data;
+ this._timestamp = timestamp;
+ this._severity = severity;
+ _attributes.put(SEVERITY_ATTR_NAME, _severity);
+ _attributes.put(TIMESTAMP_ATTR_NAME, new Date(_timestamp));
+ }
+
+ /**
+ * Returns the value of the given attribute.s
+ *
+ * @throws AttributeNotFoundException when no attribute is found with the given name.
+ */
+ public Object getAttribute (String attributeName) throws AttributeNotFoundException, MBeanException, ReflectionException
+ {
+ if (attributeName == null)
+ {
+ throw new RuntimeOperationsException(new IllegalArgumentException("Attribute name must not be null."));
+ }
+
+ if (_arguments.containsKey(attributeName) || SEVERITY_ATTR_NAME.equals(attributeName) || TIMESTAMP_ATTR_NAME.equals(attributeName))
+ {
+ return _attributes.get(attributeName);
+ } else
+ {
+ throw new AttributeNotFoundException(attributeName);
+ }
+ }
+
+ /**
+ * Executes an operation on this object instance.
+ *
+ * @param actionName the name of the method.
+ * @param params the method parameters
+ * @param signature the method signature.
+ */
+ public Object invoke (String actionName, Object[] params, String[] signature) throws MBeanException,ReflectionException
+ {
+ throw new ReflectionException(new NoSuchMethodException(actionName));
+ }
+
+ /**
+ * Sets the value of the given attribute on this object instance.
+ *
+ * @param attribute contains the new value of the attribute.
+ * @throws AttributeNotFoundException when the given attribute is not found on this object instance.
+ * @throws InvalidAttributeValueException when the given value is violating one attribute invariant.
+ */
+ public void setAttribute (Attribute attribute) throws AttributeNotFoundException,
+ InvalidAttributeValueException, MBeanException, ReflectionException
+ {
+ throw new ReflectionException(new NoSuchMethodException());
+ }
+
+ /**
+ * Sets the values of several attributes of this MBean.
+ *
+ * @param attributes a list of attributes: The identification of the attributes to be set and the values they are to be set to.
+ * @return The list of attributes that were set, with their new values.
+ */
+ public AttributeList setAttributes (AttributeList attributes)
+ {
+ throw new RuntimeException();
+ }
+ }
+
+ final static String SEVERITY_ATTR_NAME = "Severity";
+ final static String TIMESTAMP_ATTR_NAME = "Date";
+
+ private List<QpidProperty> _schemaOrderedArguments = new ArrayList<QpidProperty>();
+
+ Map<String, QpidProperty> _arguments = new HashMap<String, QpidProperty>();
+ List<QManManagedEvent> _eventInstances = new LinkedList<QManManagedEvent>();
+ State _state = _schemaNotRequested;;
+
+ /**
+ * Builds a new class with the given name and package as parent.
+ *
+ * @param className the name of the class.
+ * @param hash the class schema hash.
+ * @param parentPackage the parent of this class.
+ */
+ QpidEvent(String eventClassName, Binary hash, QpidPackage parentPackage)
+ {
+ super(eventClassName,hash,parentPackage,Names.EVENT);
+ }
+
+ /**
+ * Adds the configuration data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw configuration data.
+ */
+ void addEventData (byte[] rawData, long currentTimestamp, int severity)
+ {
+ _logger.debug(
+ Messages.QMAN_200021_INCOMING_EVENT_DATA,
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name);
+ _state.addNewEventData(rawData, currentTimestamp, severity);
+ }
+
+ /**
+ * Sets the schema for this class definition.
+ * A schema is basically a metadata description of all properties, statistics, methods and events of this class.
+ *
+ * @param propertyDefinitions properties metadata.
+ * @param statisticDefinitions statistics metadata.
+ * @param methodDefinitions methods metadata.
+ * @throws UnableToBuildFeatureException when some error occurs while parsing the incoming schema.
+ */
+ void setSchema (List<Map<String, Object>> argumentDefinitions) throws UnableToBuildFeatureException
+ {
+ _logger.info(Messages.QMAN_000010_INCOMING_SCHEMA,_parent.getOwnerId(),_parent.getName(),_name);
+ _state.setSchema(argumentDefinitions);
+ }
+
+ /**
+ * Internal method used for building attributes definitions.
+ *
+ * @param props the map contained in the properties schema.
+ * @param stats the map contained in the statistics schema.
+ * @param attributes the management metadata for attributes.
+ * @throws UnableToBuildFeatureException when it's not possibile to build one attribute definition.
+ */
+ void buildArguments (
+ List<Map<String, Object>> arguments,MBeanAttributeInfo[] attributes) throws UnableToBuildFeatureException
+ {
+ int index = 0;
+
+ for (Map<String, Object> argumentDefinition : arguments)
+ {
+ // Force metadata attributes. It is needed because arguments are "similar" to properties but they
+ // aren't properties and then they haven't optional, index and access metadata attributes
+ // (mandatory for build a property definition).
+ argumentDefinition.put(QpidFeatureBuilder.Attribute.optional.name(),0);
+ argumentDefinition.put(QpidFeatureBuilder.Attribute.index.name(),1);
+ argumentDefinition.put(QpidFeatureBuilder.Attribute.access.name(),3);
+
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createPropertyBuilder(argumentDefinition);
+ builder.build();
+
+ QpidProperty argument = (QpidProperty) builder.getQpidFeature();
+
+ _arguments.put(argument.getName(),argument);
+ _schemaOrderedArguments.add(argument);
+ attributes[index++]=(MBeanAttributeInfo) builder.getManagementFeature();
+
+ _logger.debug(
+ Messages.QMAN_200019_EVENT_ARGUMENT_DEFINITION_HAS_BEEN_BUILT,
+ _parent.getName(),
+ _name,
+ argument);
+ }
+
+ attributes[index++] = new MBeanAttributeInfo(
+ SEVERITY_ATTR_NAME,
+ Integer.class.getName(),
+ Messages.EVENT_SEVERITY_ATTRIBUTE_DESCRIPTION,
+ true,
+ false,
+ false);
+
+ attributes[index++] = new MBeanAttributeInfo(
+ TIMESTAMP_ATTR_NAME,
+ Date.class.getName(),
+ Messages.EVENT_TIMESTAMP_ATTRIBUTE_DESCRIPTION,
+ true,
+ false,
+ false);
+ }
+
+ /**
+ * Returns the object instance associated to the given identifier.
+ * Note that if the identifier is not associated to any obejct instance, a new one will be created.
+ *
+ * @param objectId the object identifier.
+ * @param registration a flag indicating whenever the (new ) instance must be registered with MBean server.
+ * @return the object instance associated to the given identifier.
+ */
+ QManManagedEvent createEventInstance(byte [] data, long timestamp, int severity)
+ {
+ QManManagedEvent eventInstance = new QManManagedEvent(data, timestamp, severity);
+ _eventInstances.add(eventInstance);
+ return eventInstance;
+ }
+
+ /**
+ * Updates the given obejct instance with the given incoming configuration data.
+ *
+ * @param instance the managed object instance.
+ * @param rawData the incoming configuration data which contains new values for instance properties.
+ */
+ void updateEventInstanceWithData(QManManagedEvent instance)
+ {
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(ByteBuffer.wrap(instance._rawEventData));
+
+ for (QpidProperty property : _schemaOrderedArguments)
+ {
+ try {
+ Object value = property.decodeValue(decoder);
+ instance.createOrReplaceAttributeValue(property.getName(),value);
+ } catch(Exception ignore) {
+ _logger.error(Messages.QMAN_100016_UNABLE_TO_DECODE_FEATURE_VALUE, _parent.getName(),_name,property.getName());
+ }
+ }
+ }
+
+ @Override
+ public String toString ()
+ {
+ return new StringBuilder()
+ .append(_parent.getOwnerId())
+ .append("::")
+ .append(_parent.getName())
+ .append(".")
+ .append(_name)
+ .toString();
+ }
+
+ /**
+ * Deregisters all the object instances and release all previously acquired resources.
+ */
+ void releaseResources ()
+ {
+ _eventInstances.clear();
+ JMX_SERVICE.unregisterEvents();
+ JMX_SERVICE.unregisterClassDefinitions();
+ _service.close();
+ }
+
+ /**
+ * Checks if this event definition contains event instance(s).
+ *
+ * @return true if there is one or more managed instances.
+ */
+ boolean hasNoInstances()
+ {
+ return _eventInstances.isEmpty();
+ }
+
+ /**
+ * Compose method used for registering an mbean (event) instance.
+ *
+ * @param instance the mbean event.
+ * @param brokerId the broker identifier.
+ * @param packageName the package name.
+ * @param eventClassName the event class name.
+ */
+ private void registerEventInstance(
+ QManManagedEvent instance,
+ UUID brokerId,
+ String packageName,
+ String eventClassName)
+ {
+ ObjectName objectName = JMX_SERVICE.registerEventInstance(instance,brokerId,packageName,eventClassName);
+
+ EntityLifecycleNotification notification = new EntityLifecycleNotification(
+ EntityLifecycleNotification.INSTANCE_ADDED_NOTIFICATION_TYPE,
+ packageName,
+ eventClassName,
+ Names.EVENT,
+ objectName);
+
+ sendNotification(notification);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEventMBean.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEventMBean.java
new file mode 100644
index 0000000000..35ba62e02c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEventMBean.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.management.domain.model;
+
+/**
+ * Management interface for Qpid entity class..
+ */
+public interface QpidEventMBean
+{
+ /**
+ * Retruns the name of the event.
+ *
+ * @return the name of the event.
+ */
+ String getName();
+
+ /**
+ * Returns the name of the package.
+ *
+ * @return the name of the package.
+ */
+ String getPackageName();
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java
new file mode 100644
index 0000000000..3262448bd4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.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.management.domain.model;
+
+/**
+ * Layer Supertype for all qpid management features.
+ */
+abstract class QpidFeature
+{
+ /** The name of the feature. */
+ protected String _name;
+
+ /**
+ * The description of the feature.
+ */
+ protected String _description;
+
+ /**
+ * Returns the description of this feature.
+ *
+ * @return the description of this feature.
+ */
+ String getDescription ()
+ {
+ return _description;
+ }
+
+ /**
+ * Sets the description for this feature.
+ *
+ * @param description the description for this feature.
+ */
+ void setDescription (String description)
+ {
+ this._description = description;
+ }
+
+ /**
+ * Returns the name of the feature.
+ *
+ * @return the name of the feature.
+ */
+ public String getName ()
+ {
+ return _name;
+ }
+
+ /**
+ * Sets the name for this feature.
+ *
+ * @param name the name of this feature.
+ */
+ void setName (String name)
+ {
+ this._name = name;
+ }
+
+ /**
+ * Returns the name of the feature.
+ *
+ * @return the name of the feature.
+ */
+ @Override
+ public String toString ()
+ {
+ return _name;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java
new file mode 100644
index 0000000000..d0862c15ca
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java
@@ -0,0 +1,454 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanFeatureInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.configuration.UnknownTypeCodeException;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.Names;
+
+/**
+ * A builder used to parse incoming schema message and therefore to build a feature (property, statistic, method, event)
+ * definition.
+ * In order to set up the correct state for this builder, clients must create an instance of this class
+ * The product of the builder will be a QpidFeature and a JMX Managemtn feature used for describing that feature in a
+ * JMX environment. So, for example, for building a property definition client code should be :
+ *
+ * <br>- QpidFeatureBuilder builder = QpidFeature.createPropertyBuilder(...);
+ * <br>- builder.build();
+ * <br>- QpidProperty property = (QpidProperty) builder.getQpidFeature();
+ * <br>- MBeanAttributeInfo managementAttributeInfo = (MBeanAttributeInfo)builder.getManagementFeature();
+ *
+ * <br>N.B.: a builder instance is not supposed to be reused. One instance for one feature!
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidFeatureBuilder
+{
+
+ static enum Attribute {
+ name,type,access,index,optional,unit,min,max,maxlen,desc,dir,argCount;
+ };
+
+ private List<Attribute> _mandatoryAttributes = new ArrayList<Attribute>();
+
+ /**
+ * Builder state for this class.
+ * Each concrete implementor is a builder for a specific feature.
+ * using the appropriate factory method.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface State {
+ void build() throws UnableToBuildFeatureException;
+ }
+
+ /**
+ * Builder used for building property definition.
+ */
+ final State _propertyBuilder = new State() {
+
+ /**
+ * Builds a property definition as well a management attribute feature.
+ */
+ public void build () throws UnableToBuildFeatureException
+ {
+ QpidProperty property = new QpidProperty();
+ try {
+ int optionalIndex = 0;
+ for (Entry<String, Object> propertyAttribute : _featureDefinition.entrySet())
+ {
+ Attribute attribute = Attribute.valueOf(propertyAttribute.getKey());
+ switch(attribute)
+ {
+ case name :
+ {
+ property.setName(String.valueOf(propertyAttribute.getValue()));
+ break;
+ }
+ case access :
+ {
+ int code = (Integer)propertyAttribute.getValue();
+ property.setAccessMode(Configuration.getInstance().getAccessMode(code));
+ break;
+ }
+ case unit :
+ {
+ property.setUnit(String.valueOf(propertyAttribute.getValue()));
+ break;
+ }
+ case min :
+ {
+ property.setMinValue((Integer)propertyAttribute.getValue());
+ break;
+ }
+ case max :
+ {
+ property.setMaxValue((Integer)propertyAttribute.getValue());
+ break;
+ }
+ case maxlen :
+ {
+ property.setMaxLength((Integer)propertyAttribute.getValue());
+ break;
+ }
+ case desc :
+ {
+ property.setDescription(String.valueOf(propertyAttribute.getValue()));
+ break;
+ }
+ case type :
+ {
+ int code = (Integer) propertyAttribute.getValue();
+ property.setType(Configuration.getInstance().getType(code));
+ break;
+ }
+ case index :
+ {
+ break;
+ }
+ case optional :
+ {
+ int code = (Integer) propertyAttribute.getValue();
+ if (code == 1)
+ {
+ property.markAsOptional(optionalIndex);
+ optionalIndex++;
+ }
+ break;
+ }
+ }
+ _mandatoryAttributes.remove(attribute);
+ }
+ } catch(Exception exception)
+ {
+ throw new UnableToBuildFeatureException(exception,property.getName());
+ }
+
+ if (!_mandatoryAttributes.isEmpty())
+ {
+ throw new MissingFeatureAttributesException(_mandatoryAttributes);
+ }
+
+ _managementFeatureInfo = new MBeanAttributeInfo(
+ property.getName(),
+ property.getJavaType().getName(),
+ property.getDescription(),
+ true,
+ property.getAccessMode()==AccessMode.RW,
+ false);
+ _qpidFeature = property;
+ }
+ };
+
+ final State _statisticBuilder = new State()
+ {
+ public void build () throws UnableToBuildFeatureException
+ {
+ QpidStatistic statistic = new QpidStatistic();
+ try
+ {
+ for (Entry<String, Object> statisticAttribute : _featureDefinition.entrySet())
+ {
+ Attribute attribute = Attribute.valueOf(statisticAttribute.getKey());
+ switch(attribute)
+ {
+ case name :
+ {
+ statistic.setName(String.valueOf(statisticAttribute.getValue()));
+ break;
+ }
+ case unit :
+ {
+ statistic.setUnit(String.valueOf(statisticAttribute.getValue()));
+ break;
+ }
+ case desc :
+ {
+ statistic.setDescription(String.valueOf(statisticAttribute.getValue()));
+ break;
+ }
+ case type :
+ {
+ int code = (Integer) statisticAttribute.getValue();
+ statistic.setType(Configuration.getInstance().getType(code));
+ break;
+ }
+ }
+ _mandatoryAttributes.remove(attribute);
+ }
+ } catch(Exception exception)
+ {
+ throw new UnableToBuildFeatureException(exception,statistic.getName());
+ }
+
+ if (!_mandatoryAttributes.isEmpty())
+ {
+ throw new MissingFeatureAttributesException(_mandatoryAttributes);
+ }
+
+ _managementFeatureInfo = new MBeanAttributeInfo(
+ statistic.getName(),
+ statistic.getJavaType().getName(),
+ statistic.getDescription(),
+ true,
+ false,
+ false);
+ _qpidFeature = statistic;
+ }
+ };
+
+ /**
+ * Builder used for building a statistic definition.
+ */
+ final State _argumentBuilder = new State()
+ {
+ /**
+ * Builds a property definition as well a management attribute feature.
+ */
+ public void build () throws UnableToBuildFeatureException
+ {
+ QpidArgument argument = new QpidArgument();
+ for (Entry<String, Object> argumentAttribute : _featureDefinition.entrySet())
+ {
+ String key = argumentAttribute.getKey();
+ if (Names.DEFAULT_PARAM_NAME.equals(key))
+ {
+ argument.setDefaultValue(argumentAttribute.getValue());
+ } else {
+ Attribute attribute = Attribute.valueOf(key);
+ switch (attribute)
+ {
+ case name :
+ {
+ argument.setName((String)argumentAttribute.getValue());
+ break;
+ }
+ case desc :
+ {
+ argument.setDescription((String)argumentAttribute.getValue());
+ break;
+ }
+ case type :
+ {
+ try
+ {
+ argument.setType(Configuration.getInstance().getType((Integer)argumentAttribute.getValue()));
+ break;
+ } catch(UnknownTypeCodeException exception)
+ {
+ throw new UnableToBuildFeatureException(exception,argument.getName());
+ }
+ }
+ case dir :
+ {
+ argument.setDirection((String)argumentAttribute.getValue());
+ break;
+ }
+ case unit :
+ {
+ argument.setUnit((String)argumentAttribute.getValue());
+ break;
+
+ }
+ }
+ }
+ }
+
+ if (!_mandatoryAttributes.isEmpty())
+ {
+ throw new MissingFeatureAttributesException(_mandatoryAttributes);
+ }
+
+ _qpidFeature = argument;
+ _managementFeatureInfo = new MBeanParameterInfo(
+ argument.getName(),
+ argument.getJavaType().getName(),
+ argument.getDescription());
+ }
+ };
+
+ final State _methodBuilder = new State()
+ {
+ public void build () throws UnableToBuildFeatureException
+ {
+ Map<String,Object> definition = _methodOrEventDefinition.getDefinition();
+ String name = (String)definition.get(Attribute.name.name());
+ if (name == null)
+ {
+ throw new MissingFeatureAttributesException(_mandatoryAttributes);
+ }
+
+ QpidMethod method = new QpidMethod((String)definition.get(Attribute.name.name()),(String) definition.get(Attribute.desc.name()));
+
+ List<Map<String,Object>> args = _methodOrEventDefinition.getArgumentsDefinitions();
+
+ List<MBeanParameterInfo> signature = new LinkedList<MBeanParameterInfo>();
+
+ for (Map<String,Object> argumentDefinition : args)
+ {
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createArgumentBuilder(argumentDefinition);
+ builder.build();
+
+ QpidArgument argument = (QpidArgument) builder.getQpidFeature();
+ method.addArgument(argument);
+ if (argument.isInput())
+ {
+ signature.add((MBeanParameterInfo) builder.getManagementFeature());
+ }
+ }
+
+ _qpidFeature = method;
+ _managementFeatureInfo = new MBeanOperationInfo(
+ method.getName(),
+ method.getDescription(),
+ (MBeanParameterInfo[])signature.toArray(new MBeanParameterInfo[signature.size()]),
+ void.class.getName(),
+ MBeanOperationInfo.ACTION);
+ }
+ };
+
+ final State _eventBuilder = new State()
+ {
+ public void build () throws UnableToBuildFeatureException
+ {
+ }
+ };
+
+ private MBeanFeatureInfo _managementFeatureInfo;
+ private QpidFeature _qpidFeature;
+ private final Map <String, Object> _featureDefinition;
+ private final MethodOrEventDataTransferObject _methodOrEventDefinition;
+ private State _state;
+
+ static QpidFeatureBuilder createPropertyBuilder(Map<String, Object> propertyDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(propertyDefinition);
+ result._state = result._propertyBuilder;
+ result._mandatoryAttributes.add(Attribute.name);
+ result._mandatoryAttributes.add(Attribute.access);
+ result._mandatoryAttributes.add(Attribute.type);
+ result._mandatoryAttributes.add(Attribute.optional);
+ result._mandatoryAttributes.add(Attribute.index);
+ return result;
+ }
+
+ static QpidFeatureBuilder createStatisticBuilder(Map<String, Object> statisticDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(statisticDefinition);
+ result._state = result._statisticBuilder;
+ result._mandatoryAttributes.add(Attribute.name);
+ result._mandatoryAttributes.add(Attribute.type);
+ return result;
+ }
+
+ static QpidFeatureBuilder createEventBuilder(Map<String, Object> eventDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(eventDefinition);
+ result._state = result._eventBuilder;
+ return result;
+ }
+
+ static QpidFeatureBuilder createMethodBuilder(MethodOrEventDataTransferObject methodDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(methodDefinition);
+ result._state = result._methodBuilder;
+ result._mandatoryAttributes.add(Attribute.name);
+ return result;
+ }
+
+ private static QpidFeatureBuilder createArgumentBuilder(Map<String, Object> argumentDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(argumentDefinition);
+ result._state = result._argumentBuilder;
+ return result;
+ }
+
+
+ /**
+ * Builds new builder with the given data.
+ * This constructor is used for building properties, statistics and arguments.
+ *
+ * @param definition the feature definition data.
+ */
+ private QpidFeatureBuilder(Map<String, Object> definition)
+ {
+ this._featureDefinition = definition;
+ this._methodOrEventDefinition = null;
+ }
+
+ /**
+ * Builds new builder with the given data.
+ * This constructor is used for building properties, statistics and arguments.
+ *
+ * @param definition the feature definition data.
+ */
+ private QpidFeatureBuilder(MethodOrEventDataTransferObject definition)
+ {
+ this._featureDefinition = null;
+ this._methodOrEventDefinition = definition;
+ }
+
+ /**
+ * Returns the just built qpid feature.
+ *
+ * @return the qpid feature.
+ */
+ QpidFeature getQpidFeature()
+ {
+ return _qpidFeature;
+ }
+
+ /**
+ * Return the jmx metadata for the built feature.
+ *
+ * @return the jmx metadata for the built feature.
+ */
+ MBeanFeatureInfo getManagementFeature()
+ {
+ return _managementFeatureInfo;
+ }
+
+ void build() throws UnableToBuildFeatureException
+ {
+ try
+ {
+ _state.build();
+ } catch(UnableToBuildFeatureException exception)
+ {
+ throw exception;
+ } catch(Exception exception)
+ {
+ throw new UnableToBuildFeatureException(exception,"Feature name is not available for debugging.");
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java
new file mode 100644
index 0000000000..7824ecc9a4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.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.management.domain.model;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+
+/**
+ * Qpid method definition.
+ * An entity describing an invocation that can be made on a managed object instance.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidMethod extends QpidFeature
+{
+ /** Argument list */
+ List<QpidArgument> arguments = new LinkedList<QpidArgument>();
+
+ /**
+ * Builds a new qpid method definition with the given name and description.
+ *
+ * @param name the method name.
+ * @param description the method description.
+ */
+ QpidMethod(String name, String description)
+ {
+ this._name = name;
+ this._description = description;
+ }
+
+ /**
+ * Adds an argument to this method.
+ *
+ * @param argument the new argument to be added.
+ */
+ void addArgument(QpidArgument argument)
+ {
+ arguments.add(argument);
+ }
+
+ /**
+ * Returns a string representation of this method.
+ * The result format is <method name>(argType1 argName1 (Direction), argType2 argName2 (Direction), etc...)
+ *
+ * @return a string representation of this method.
+ */
+ @Override
+ public String toString ()
+ {
+ StringBuilder builder = new StringBuilder()
+ .append(_name)
+ .append('(');
+
+ for (QpidArgument argument : arguments)
+ {
+ builder.append(argument).append(',');
+ }
+
+ builder.append(')');
+ return builder.toString();
+ }
+
+ /**
+ * Encodes the given parameter values according to this method arguments definitions.
+ * Note that only Input/Output and Input parameters are encoded.
+ *
+ * @param parameters the parameters values.
+ * @param encoder the encoder used for encoding.
+ */
+ public void encodeParameters (Object[] parameters, Encoder encoder)
+ {
+ int index = 0;
+ for (QpidArgument argument : arguments)
+ {
+ if (argument.getDirection() != Direction.O)
+ {
+ argument.encode(parameters[index++],encoder);
+ }
+ }
+ }
+
+ /**
+ * Decodes the given input raw according to this method arguments definitions.
+ * Note that only Input/Output and Output parameters are encoded.
+ *
+ * @param parameters the parameters values.
+ * @param encoder the encoder used for encoding.
+ */
+ public Map<String, Object> decodeParameters (byte [] values)
+ {
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(ByteBuffer.wrap(values));
+ Map<String, Object> result = new HashMap<String, Object>();
+
+ for (QpidArgument argument : arguments)
+ {
+ if (argument.getDirection() != Direction.I)
+ {
+ result.put(argument.getName(),argument.decode(decoder));
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Validates the given array of parameters against the constraint defined on this method's arguments.
+ *
+ * @param parameters the parameters (values) to be validated.
+ * @throws ValidationException when one of the supplied values is violating some constraint.
+ */
+ public void validate (Object[] parameters) throws ValidationException
+ {
+ int index = 0;
+ for (QpidArgument argument : arguments)
+ {
+ if (argument.getDirection() != Direction.O)
+ {
+ argument.validate(parameters[index++]);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java
new file mode 100644
index 0000000000..c25a5d7d1c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java
@@ -0,0 +1,286 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.management.domain.handler.impl.IMethodInvocationListener;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Qpid package definition.
+ * A grouping of class definitions that are related to a single software component.
+ * The package concept is used to extend the management schema beyond just the QPID software components.
+ * The name is prefixed with "Qpid" for avoiding name conficts with java.lang.Package.
+ *
+ * @author Andrea Gazzarini
+ */
+final class QpidPackage
+{
+ /**
+ * Qpid class identity.
+ * Each qpid class is uniquely identifier by its name and schema-hash.
+ * The schema hash is an MD5 checksum of the schema for a class.
+ * It is there so we can support the case where two different versions of the same class are present at the same time.
+ *
+ * @author Andrea Gazzarini
+ */
+ class QpidClassIdentity {
+ final String name;
+ final Binary hash;
+
+ /**
+ * Builds a new class identity with the given name and hash.
+ *
+ * @param name the class name.
+ * @param hash is an MD5 checksum of the schema of this outer class.
+ */
+ QpidClassIdentity(String name,Binary hash) {
+ this.name = name;
+ this.hash = hash;
+ }
+
+ @Override
+ public int hashCode ()
+ {
+ return name.hashCode()+hash.hashCode();
+ }
+
+ @Override
+ public boolean equals (Object obj)
+ {
+ if(obj instanceof QpidClassIdentity)
+ {
+ QpidClassIdentity identity = (QpidClassIdentity) obj;
+ return name.equals(identity.name) && hash.equals(identity.hash);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ private String _name;
+ private DomainModel _parent;
+ private Map<QpidClassIdentity, QpidClass> _classes = new HashMap<QpidClassIdentity, QpidClass>();
+ private Map<QpidClassIdentity, QpidEvent> _events = new HashMap<QpidClassIdentity, QpidEvent>();
+
+ /**
+ * Builds a new package with the supplied name.
+ *
+ * @param name the name of the package.
+ */
+ QpidPackage(String name, DomainModel parent)
+ {
+ this._name = name;
+ this._parent = parent;
+ }
+
+ /**
+ * Returns the identifier of the broker which contains this package.
+ * @return
+ */
+ UUID getOwnerId()
+ {
+ return _parent.getBrokerId();
+ }
+
+ /**
+ * Returns the name of this package.
+ *
+ * @return the name of this package.
+ */
+ String getName ()
+ {
+ return _name;
+ }
+
+ /**
+ * Adds a class definition to this package.
+ * The class will be added only if its definition doesn't already exists.
+ *
+ * @param className the name of the class.
+ * @param classHash the class schema hash.
+ * @param properties the properties of the class.
+ * @param statistics the statistics of the class.
+ * @param methods the methods of the class.
+ * @param events the events of the class.
+ *
+ * @throws UnableToBuildFeatureException when the class definition cannot be built due to a feature build failure.
+ */
+ void addClassDefinition (
+ String className,
+ Binary classHash,
+ List<Map<String, Object>> properties,
+ List<Map<String, Object>> statistics,
+ List<MethodOrEventDataTransferObject> methods) throws UnableToBuildFeatureException
+ {
+ getQpidClass(className,classHash,true).setSchema(properties,statistics,methods);
+ }
+
+ void addEventDefinition (
+ String eventClassName,
+ Binary classHash,
+ List<Map<String, Object>> arguments) throws UnableToBuildFeatureException
+ {
+ getQpidEvent(eventClassName,classHash,true).setSchema(arguments);
+ }
+
+ /**
+ * Returns true if this package contains the given class definition.
+ *
+ * @param className the name of the class.
+ * @return true if this package contains the class definition, false otherwise.
+ */
+ boolean alreadyContainsClassDefinition (String className, Binary hash)
+ {
+ return _classes.containsKey(new QpidClassIdentity(className,hash));
+ }
+
+ /**
+ * Injects into a class the given object instance instrumentation data.
+ *
+ * @param className the of the class the injected object data belongs to.
+ * @param objectId the object identifier.
+ * @param rawData the instrumentation data (in raw format).
+ */
+ void setObjectInstanceInstrumentationRawData (String className, Binary classHash,Binary objectId, byte[] rawData)
+ {
+ getQpidClass(className, classHash,true).addInstrumentationData(objectId,rawData);
+ }
+
+ /**
+ * Injects into a class the given object instance configuration data.
+ *
+ * @param className the of the class the injected object data belongs to.
+ * @param objectId the object identifier.
+ * @param rawData the configuration data (in raw format).
+ */
+ void setObjectInstanceConfigurationRawData (String className,Binary classHash, Binary objectId, byte[] rawData)
+ {
+ getQpidClass(className,classHash,true).addConfigurationData(objectId,rawData);
+ }
+
+ void setEventInstanceRawData (String eventName,Binary eventHash, byte[] rawData,long currentTimestamp,int severity)
+ {
+ getQpidEvent(eventName,eventHash,true).addEventData(rawData, currentTimestamp, severity);
+ }
+
+ /**
+ * Returns the definition of the class with given name.
+ *
+ * @param className the name of the class.
+ * @param hash the class hash.
+ * @param store a flag indicating if a just created class must be stored or not.
+ * @return the definition of the class with given name.
+ */
+ QpidClass getQpidClass(String className, Binary hash, boolean store)
+ {
+ QpidClassIdentity identity = new QpidClassIdentity(className,hash);
+ QpidClass classDefinition = _classes.get(identity);
+ if (classDefinition == null)
+ {
+ classDefinition = new QpidClass(className, hash,this);
+ if (store)
+ {
+ _classes.put(identity,classDefinition);
+ }
+ }
+ return classDefinition;
+ }
+
+ /**
+ * Returns the definition of the class with given name.
+ *
+ * @param className the name of the class.
+ * @param hash the class hash.
+ * @param store a flag indicating if a just created class must be stored or not.
+ * @return the definition of the class with given name.
+ */
+ QpidEvent getQpidEvent(String className, Binary hash, boolean store)
+ {
+ QpidClassIdentity identity = new QpidClassIdentity(className,hash);
+ QpidEvent eventDefinition = _events.get(identity);
+ if (eventDefinition == null)
+ {
+ eventDefinition = new QpidEvent(className, hash,this);
+ if (store)
+ {
+ _events.put(identity,eventDefinition);
+ }
+ }
+ return eventDefinition;
+ }
+
+ /**
+ * Returns a string representation of this class.
+ * That is, this method returns the simple name (not FQN) of this class.
+ */
+ @Override
+ public String toString ()
+ {
+ return _name;
+ }
+
+ /**
+ * Removes the object instance associated to the given parameters.
+ *
+ * @param className the class definition of the object instance.
+ * @param classHash the class hash
+ * @param objectId the object identifier.
+ */
+ void removeObjectInstance (String className, Binary classHash, Binary objectId)
+ {
+ QpidClass qpidClass = getQpidClass(className,classHash,false);
+ qpidClass.removeObjectInstance(objectId);
+ }
+
+ /**
+ * Releases all previously acquired resources of this package.
+ */
+ void releaseResources ()
+ {
+ for (QpidClass qpidClass : _classes.values())
+ {
+ qpidClass.releaseResources();
+ }
+
+ for (QpidEvent qpidEvent: _events.values())
+ {
+ qpidEvent.releaseResources();
+ }
+ }
+
+ /**
+ * Returns the method invocation listener of the corresponing parent domain model.
+ *
+ * @return the method invocation listener of the corresponing parent domain model.
+ */
+ IMethodInvocationListener getMethodInvocationListener ()
+ {
+ return _parent.getMethodInvocationListener();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java
new file mode 100644
index 0000000000..089b00c71c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java
@@ -0,0 +1,295 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model;
+
+import java.lang.reflect.Constructor;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.domain.model.type.Type;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Qpid property definition.
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidProperty extends QpidAttribute
+{
+ private final static Logger LOGGER = Logger.get(QpidProperty.class);
+
+ private final static int [] MASKS = {1,2,4,8,16,32,64,128};
+
+ /**
+ * Decoder interface used for decoding incomng values for this property.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface Decoder
+ {
+ Object decodeValue(org.apache.qpid.transport.codec.Decoder decoder,byte [] presenceBitMasks);
+ }
+
+ /**
+ * Decoder used for decoding incoming values for this optional property.
+ */
+ final Decoder _optionalPropertyDecoder = new Decoder() {
+
+ public Object decodeValue (org.apache.qpid.transport.codec.Decoder decoder, byte[] presenceBitMasks)
+ {
+ return ((presenceBitMasks[_optionalIndex/8] & MASKS[_maskIndex]) != 0)
+ ? QpidProperty.this.decodeValue(decoder)
+ : null;
+ }
+ };
+
+ /**
+ * Decoder used for decoding incoming values for this mandatory property.
+ */
+ final Decoder _mandatoryPropertyDecoder = new Decoder() {
+
+ public Object decodeValue (org.apache.qpid.transport.codec.Decoder decoder, byte[] presenceBitMasks)
+ {
+ return QpidProperty.this.decodeValue(decoder);
+ }
+ };
+
+
+ /**
+ * Null object used to perform a dummy validation.
+ * This is the default validator installed at creation time.
+ */
+ final static IValidator EMPTY_VALIDATOR = new IValidator()
+ {
+ public void validate (Object value) throws ValidationException
+ {
+ // Nothing to do here.
+ }
+ };
+
+ /**
+ * Validator responsible for validating strings.
+ * At the moment the only constraint that should be applied to a string feature is the "max length"
+ */
+ class StringValidator implements IValidator
+ {
+ public void validate (Object value) throws ValidationException
+ {
+ if ((_maxLength != Integer.MIN_VALUE) && (value != null)){
+ int length = value.toString().length();
+ if (length > _maxLength) {
+ throw new ValidationException(
+ ValidationException.MAX_LENGTH,
+ _maxLength,
+ _name,
+ length);
+ }
+ }
+ }
+ };
+
+ /**
+ * Validator responsible for validating numbers.
+ */
+ class NumberValidator implements IValidator
+ {
+ public void validate (Object value) throws ValidationException
+ {
+ if (value != null) {
+ double numericValue = ((Number)value).doubleValue();
+ if (_minValue != Integer.MIN_VALUE && numericValue < _minValue) {
+ throw new ValidationException(
+ ValidationException.MIN_VALUE,
+ _minValue,
+ _name,
+ numericValue);
+ }
+
+ if (_maxValue != Integer.MIN_VALUE && numericValue > _maxValue) {
+ throw new ValidationException(
+ ValidationException.MAX_VALUE,
+ _maxValue,
+ _name,
+ numericValue);
+ }
+ }
+ }
+ };
+
+ private AccessMode _accessMode;
+ private int _minValue = Integer.MIN_VALUE;
+ private int _maxValue = Integer.MIN_VALUE;
+ private int _maxLength = Integer.MIN_VALUE;
+
+ private int _optionalIndex;
+ private int _maskIndex;
+
+ Decoder _decoder = _mandatoryPropertyDecoder;
+
+ private IValidator _validator = EMPTY_VALIDATOR;
+
+ /**
+ * Validates the given value according to the current validator.
+ * It delegates the validation to the current installed validator.
+ *
+ * @param value the value of this qpid property.
+ * @throws ValidationException when the given value is violating the current validator constraints.
+ */
+ void validate(Object value) throws ValidationException {
+ _validator.validate(value);
+ }
+
+ /**
+ * Sets the type of this property.
+ * In addition this method tries to detect if a validator has been associated with the type.
+ * If no validator is found then the default validator will be used; that is : no validator will be performed on this
+ * property.
+ *
+ * @param type the type of this property.
+ */
+ void setType (Type type)
+ {
+ super.setType(type);
+ try {
+ Class<?> validatorClass = Class.forName(Configuration.getInstance().getValidatorClassName(type));
+ Constructor<?> validatorConstructor = validatorClass.getDeclaredConstructor(QpidProperty.class);
+ _validator = (IValidator) validatorConstructor.newInstance(this);
+ LOGGER.debug(Messages.QMAN_200022_VALIDATOR_INSTALLED ,validatorClass.getName(), type);
+ } catch(Exception exception) {
+ _validator = EMPTY_VALIDATOR;
+ LOGGER.debug(Messages.QMAN_200023_VALIDATOR_NOT_FOUND , type);
+ }
+ }
+
+ /**
+ * Gets the value of this property according to its type definition.
+ *
+ * @param decoder the decoder used to extract the value.
+ * @return the value of this feature according to its type definition
+ */
+ Object decodeValue(org.apache.qpid.transport.codec.Decoder decoder,byte [] presenceBitMasks)
+ {
+ return _decoder.decodeValue(decoder, presenceBitMasks);
+ }
+
+ /**
+ * Sets access mode for this property.
+ *
+ * @param accessMode the access mode for this property.
+ */
+ void setAccessMode (AccessMode accessMode)
+ {
+ this._accessMode = accessMode;
+ }
+
+ /**
+ * Gets the minimum allowed value for this property.
+ *
+ * @return the minimum allowed value for this property.
+ */
+ int getMinValue ()
+ {
+ return _minValue;
+ }
+
+ /**
+ * Sets the minimum allowed value for this property.
+ *
+ * @param minValue the minimum allowed value for this property.
+ */
+ void setMinValue (int minValue)
+ {
+ this._minValue = minValue;
+ }
+
+ /**
+ * Gets the maximum allowed value for this property.
+ *
+ * @return the maximum allowed value for this property.
+ */
+ int getMaxValue ()
+ {
+ return _maxValue;
+ }
+
+ /**
+ * Sets the masimum allowed value for this property.
+ *
+ * @param maxValue the maximum allowed value for this property.
+ */
+ void setMaxValue (int maxValue)
+ {
+ this._maxValue = maxValue;
+ }
+
+ /**
+ * Gets the max length value for this property.
+ *
+ * @return the max length value for this property.
+ */
+ int getMaxLength ()
+ {
+ return _maxLength;
+ }
+
+ /**
+ * Sets the max length value for this property.
+ *
+ * @param maxLength the max length value for this property.
+ */
+ void setMaxLength (int maxLength)
+ {
+ this._maxLength = maxLength;
+ }
+
+ /**
+ * Gets the description of this property.
+ *
+ * @return the description of this property.
+ */
+ AccessMode getAccessMode ()
+ {
+ return _accessMode;
+ }
+
+ /**
+ * Marks this property as optional.
+ *
+ * @param optional the optional attribute value for this property.
+ * @param index the index of this optional property
+ */
+ void markAsOptional (int index)
+ {
+ this._optionalIndex = index;
+ this._maskIndex = (_optionalIndex >= 8) ? _optionalIndex-8 : _optionalIndex;
+ _decoder = _optionalPropertyDecoder;
+ }
+
+ /**
+ * Returns true if this property is marked as optional.
+ *
+ * @return true if this property is marked as optional, false otherwise.
+ */
+ boolean isOptional ()
+ {
+ return _decoder == _optionalPropertyDecoder;
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/OutgoingNetworkTransport.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java
index ff86ba481f..37a652c098 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/OutgoingNetworkTransport.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java
@@ -18,15 +18,17 @@
* under the License.
*
*/
-package org.apache.qpid.transport.network;
+package org.apache.qpid.management.domain.model;
-import java.nio.ByteBuffer;
-
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.transport.ConnectionSettings;
-import org.apache.qpid.transport.Receiver;
-
-public interface OutgoingNetworkTransport extends NetworkTransport
+/**
+ * Qpid statistic definition.
+ *
+ * A statistic is a typed member of a class which represents an instrumentation attribute of the class.
+ * Statistics are always read-only in nature and tend to change rapidly.
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidStatistic extends QpidAttribute
{
- public NetworkConnection connect(ConnectionSettings settings, Receiver<ByteBuffer> delegate, SSLContextFactory sslFactory);
+ // EMPTY CLASS : Statistic metadata are all defined in superclasses.
} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java
new file mode 100644
index 0000000000..fc4506779b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.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.management.domain.model;
+
+/**
+ * Thrown when a feature (property, statistic, method or event) definition cannot be built due to schema parsing errors.
+ *
+ * @author Andrea Gazzarini
+ */
+public class UnableToBuildFeatureException extends Exception
+{
+ private static final long serialVersionUID = 5180111828887602836L;
+
+ /**
+ * Builds a new UnableToBuildFeatureException with the specified cause.
+ *
+ * @param exception the exception cause.
+ */
+ UnableToBuildFeatureException(Exception exception, String featureName)
+ {
+ super( (featureName != null) ? featureName : "Feature name is not available for debugging purposes." ,exception);
+ }
+
+ /**
+ * Builds a new UnableToBuildFeatureException with the specified message.
+ *
+ * @param message the detail message.
+ */
+ UnableToBuildFeatureException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java
new file mode 100644
index 0000000000..3b117e5b9d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java
@@ -0,0 +1,105 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model;
+
+/**
+ * Thrown when an attempt is made in order to update / change the state of an object and a constraint on that state
+ * is violated.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ValidationException extends Exception
+{
+ private static final long serialVersionUID = -5218828669655586205L;
+
+ public final static String MAX_LENGTH = "Max Length";
+ public final static String MAX_VALUE = "Max Value";
+ public final static String MIN_VALUE = "Min Value";
+
+ private final String _featureName;
+ private final Object _featureValue;
+
+ private final Number _constraintValue;
+ private final String _constraintName;
+
+ /**
+ * Builds a new validation exception with the specified parameters.
+ *
+ * @param constraintName the name of the violated constraint.
+ * @param constraintValue the value of the violated constraint.
+ * @param featureName the name of the violating feature.
+ * @param featureValue the value of the violating feature.
+ */
+ ValidationException(String constraintName,Number constraintValue, String featureName,Object featureValue)
+ {
+ super(String.format(
+ "Property constraint violation : " +
+ "%s allowed for property %s is %s but received value was %s",
+ constraintName,
+ featureName,
+ constraintValue,
+ featureValue));
+ this._constraintName = constraintName;
+ this._constraintValue = constraintValue;
+ this._featureName = featureName;
+ this._featureValue = featureValue;
+ }
+
+ /**
+ * Returns the value of the violating feature.
+ *
+ * @return the value of the violating feature.
+ */
+ public Object getFeatureValue ()
+ {
+ return _featureValue;
+ }
+
+ /**
+ * Returns the name of the violating feature.
+ *
+ * @return the name of the violating feature.
+ */
+ public String getFeatureName()
+ {
+ return _featureName;
+ }
+
+ /**
+ * Returns the value of the violated constraint.
+ *
+ * @return the value of the violated constraint.
+ */
+ public Number getConstraintValue ()
+ {
+ return _constraintValue;
+ }
+
+ /**
+ * Returns the name of the violated constraint.
+ *
+ * @return the name of the violated constraint.
+ */
+ public String getConstraintName ()
+ {
+ return _constraintName;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/AbsTime.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/AbsTime.java
new file mode 100644
index 0000000000..28f5f70c04
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/AbsTime.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class AbsTime extends Type
+{
+ public AbsTime()
+ {
+ super(Long.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readInt64();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeInt64((Long)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java
new file mode 100644
index 0000000000..95cb03b04b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java
@@ -0,0 +1,169 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model.type;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.UUID;
+
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * It is a simple wrapper for a byte array (for example a 128bin).
+ * It is used to let QMan deal with an object instead of an array.
+ *
+ * @author Andrea Gazzarini
+ */
+public final class Binary implements Serializable
+{
+ private static final long serialVersionUID = -6865585077320637567L;
+
+ // Marker internal (empty) interface
+ private interface State extends Serializable{}
+
+ /**
+ * Internal state of this object used to denote the situation when the hashcode() method has never been called.
+ * After the hashcode has been computed this class switches the state of the outer object to the next state.
+ */
+ State hashCodeNotYetComputed = new State()
+ {
+ private static final long serialVersionUID = 221632033761266959L;
+
+ @Override
+ public int hashCode ()
+ {
+ hashCode = Arrays.hashCode(_bytes);
+ state = hashCodeAlreadyComputed;
+ return hashCode;
+ }
+ };
+
+ /**
+ * Internal state of this object used to denote the situation where the hashcode() method has already been computed.
+ * Simply it returns the just computed value for the hashcode.
+ */
+ State hashCodeAlreadyComputed = new State()
+ {
+ private static final long serialVersionUID = 221632033761266959L;
+
+ @Override
+ public int hashCode ()
+ {
+ return hashCode;
+ }
+ };
+
+ private final UUID uuid;
+ private final byte [] _bytes;
+ private long _first;
+ private int hashCode;
+
+ /** Current state (hashcode computation). */
+ State state = hashCodeNotYetComputed;
+
+ /**
+ * Builds a new binary with the given byte array.
+ *
+ * @param bytes the wrapped data.
+ */
+ public Binary(byte [] bytes)
+ {
+ this._bytes = bytes;
+ byte [] array = new byte [8];
+ System.arraycopy(_bytes, 0, array, 0, 8);
+ _first = unpack64(array);
+ uuid = UUID.randomUUID();
+ }
+
+ @Override
+ public int hashCode ()
+ {
+ return state.hashCode();
+ }
+
+ @Override
+ public boolean equals (Object obj)
+ {
+ if(obj instanceof Binary)
+ {
+ try
+ {
+ Binary binary = (Binary)obj;
+ return Arrays.equals(_bytes, binary._bytes);
+ } catch (Exception exception)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Encodes the content (wrapped byte array) of this instance using the given encoder.
+ *
+ * @param encoder the encoder used to encode instance content.
+ */
+ public void encode(Encoder encoder)
+ {
+ encoder.writeBin128(_bytes);
+ }
+
+ @Override
+ public String toString ()
+ {
+ return uuid.toString();
+ }
+
+ /**
+ * Returns the bank identifier derived from this object identifier.
+ *
+ * @return the bank identifier derived from this object identifier.
+ */
+ public long getBankId()
+ {
+ return _first & 0x000000000FFFFFFF;
+ }
+
+ /**
+ * Returns the broker identifier derived from this object identifier.
+ *
+ * @return the broker identifier derived from this object identifier.
+ */
+ public long getBrokerId()
+ {
+ return (_first & 281474708275200L) >> 28;
+ }
+
+ public final long unpack64(byte data[]) {
+ return (
+ ((long) (data[0] & 0xff) << 56) |
+ ((long)(data[1] & 0xff) << 48) |
+ ((long)(data[2] & 0xff) << 40) |
+ ((long)(data[3] & 0xff) << 32) |
+ ((long)(data[4] & 0xff) << 24) |
+ ((long)(data[5] & 0xff) << 16) |
+ ((long)(data[6] & 0xff) << 8) |
+ (long) data[7] & 0xff);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Boolean.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Boolean.java
new file mode 100644
index 0000000000..c339b870ac
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Boolean.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Boolean extends Type
+{
+ public Boolean()
+ {
+ super(java.lang.Boolean.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return (decoder.readUint8() == 1);
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeUint8( ((java.lang.Boolean)value) ? (short)1 : 0 );
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/DeltaTime.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/DeltaTime.java
new file mode 100644
index 0000000000..a788e2f8e1
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/DeltaTime.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class DeltaTime extends Type
+{
+ public DeltaTime()
+ {
+ super(Long.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readUint64();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeUint64((Long)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Double.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Double.java
new file mode 100644
index 0000000000..d36af3d3df
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Double.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Double extends Type
+{
+ public Double()
+ {
+ super(java.lang.Double.class);
+ }
+
+ @Override
+ public Object decode(Decoder decoder)
+ {
+ return decoder.readDouble();
+ }
+
+ @Override
+ public void encode(Object value, Encoder encoder)
+ {
+ encoder.writeDouble((java.lang.Double)value);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Float.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Float.java
new file mode 100644
index 0000000000..cb1f6e78a7
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Float.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Float extends Type
+{
+ public Float()
+ {
+ super(java.lang.Float.class);
+ }
+
+ @Override
+ public Object decode(Decoder decoder)
+ {
+ return decoder.readFloat();
+ }
+
+ @Override
+ public void encode(Object value, Encoder encoder)
+ {
+ encoder.writeFloat((java.lang.Float)value);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int16.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int16.java
new file mode 100644
index 0000000000..f4685f0295
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int16.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Int16 extends Type
+{
+ public Int16()
+ {
+ super(Short.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readInt16();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeInt16((Short)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int32.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int32.java
new file mode 100644
index 0000000000..ae5be90a2d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int32.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Int32 extends Type
+{
+ public Int32()
+ {
+ super(Integer.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readInt32();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeInt32((Integer)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int64.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int64.java
new file mode 100644
index 0000000000..f76818344e
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int64.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Int64 extends Type
+{
+ public Int64()
+ {
+ super(Long.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readInt64();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeInt64((Long)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int8.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int8.java
new file mode 100644
index 0000000000..6f7c3b24d0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int8.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Int8 extends Type
+{
+ public Int8()
+ {
+ super(Byte.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readInt8();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeInt8((Byte)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java
new file mode 100644
index 0000000000..ef5bc7a484
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java
@@ -0,0 +1,45 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Map extends Type
+{
+ public Map()
+ {
+ super(java.util.Map.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readMap();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeMap((java.util.Map<String, Object>)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/ObjectReference.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/ObjectReference.java
new file mode 100644
index 0000000000..13e1b68d26
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/ObjectReference.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class ObjectReference extends Type
+{
+ public ObjectReference()
+ {
+ super(byte[].class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readBin128();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ ((Binary)value).encode(encoder);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str16.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str16.java
new file mode 100644
index 0000000000..42829ce176
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str16.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Str16 extends Type
+{
+ public Str16()
+ {
+ super(String.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readStr16();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeStr16((String)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str8.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str8.java
new file mode 100644
index 0000000000..f9b747ce6d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str8.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Str8 extends Type
+{
+ public Str8()
+ {
+ super(String.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readStr8();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeStr8((String)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Type.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Type.java
new file mode 100644
index 0000000000..7f92ec82b0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Type.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Layer supertype for all management "types".
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class Type
+{
+ /** Java representation of this type. */
+ protected final Class<?> javaType;
+
+ /**
+ * Builds a new management type wiich wraps the given java type.
+ *
+ * @param javaType the java type.
+ */
+ Type(Class<?> javaType)
+ {
+ this.javaType = javaType;
+ }
+
+ /**
+ * Returns the wrapped java type.
+ *
+ * @return the wrapped java type.
+ */
+ public Class<?> getJavaType ()
+ {
+ return javaType;
+ }
+
+ /**
+ * Each concrete subclass must define here how to decode incoming data according.
+ *
+ * @param decoder the decoder used to extract data.
+ * @return the "typed" value.
+ *
+ */
+ public abstract Object decode(Decoder decoder);
+
+ /**
+ * Returns a string representation of this type.
+ *
+ * @return a string representation of this type.
+ */
+ @Override
+ public String toString ()
+ {
+ return new StringBuilder(getClass().getName())
+ .append(" (wraps ")
+ .append(javaType.getName())
+ .append(')').toString();
+ }
+
+ /**
+ * Identity for types is based on wrapped java type identity.
+ */
+ @Override
+ public boolean equals (Object obj)
+ {
+ return (obj instanceof Type) && getJavaType() == ((Type)obj).getJavaType();
+ }
+
+ @Override
+ public int hashCode ()
+ {
+ return getJavaType().hashCode();
+ }
+
+ /**
+ * Encodes the given values according to this type definition.
+ *
+ * @param value the value to be encoded.
+ * @param encoder the encoder.
+ */
+ public abstract void encode (Object value,Encoder encoder);
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint16.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint16.java
new file mode 100644
index 0000000000..2d3edd41ea
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint16.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Uint16 extends Type
+{
+ public Uint16()
+ {
+ super(Integer.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return new Integer(decoder.readUint16());
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeUint16((Integer)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint32.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint32.java
new file mode 100644
index 0000000000..c5fb981bb0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint32.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Uint32 extends Type
+{
+ public Uint32()
+ {
+ super(Long.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return new Long(decoder.readUint32());
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeUint32((Long)value);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint64.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint64.java
new file mode 100644
index 0000000000..9182f883bf
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint64.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Uint64 extends Type
+{
+ public Uint64()
+ {
+ super(Long.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return new Long(decoder.readUint64());
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeUint64((Long)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint8.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint8.java
new file mode 100644
index 0000000000..ab7e78856c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint8.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.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Uint8 extends Type
+{
+ public Uint8()
+ {
+ super(Short.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return new Short(decoder.readUint8());
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeUint8((Short)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uuid.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uuid.java
new file mode 100644
index 0000000000..1b3be954d6
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uuid.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model.type;
+
+import java.util.UUID;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Uuid extends Type
+{
+ public Uuid()
+ {
+ super(UUID.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readUuid();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeUuid((UUID)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java
new file mode 100644
index 0000000000..fc9819fce4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java
@@ -0,0 +1,183 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.services;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.qpid.api.Message;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.domain.handler.base.IMessageHandler;
+import org.apache.qpid.management.domain.model.DomainModel;
+import org.apache.qpid.nclient.util.MessageListener;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Message listener used for processing incoming messages.
+ * So it is installed as a consumer on a specific channel and when a new message arrives:
+ *
+ * 1) Performs a sanity check on the message (magic number, sequence number)
+ * 2) Extracts the opcode and looks for one message handler associated with that opcode.
+ * 3) If a message handler is found the delegates the message processing; otherwise a log message is written to indicate
+ * that the message will be skipped.
+ *
+ * @author Andrea Gazzarini
+ */
+class BrokerMessageListener implements MessageListener
+{
+ private final static Logger LOGGER = Logger.get(BrokerMessageListener.class);
+
+ private static class Log
+ {
+ // Debugs the content of the incoming message.
+ static void debugIncomingMessage(ByteBuffer message)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(Messages.QMAN_200001_INCOMING_MESSAGE_HAS_BEEN_RECEIVED, Arrays.toString(message.array()));
+ }
+ }
+
+ // Debugs all the configured handlers.
+ static void debugConfiguredHandlers (Map<Character, IMessageHandler> _handlers)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ for (Entry<Character, IMessageHandler> entry : _handlers.entrySet())
+ {
+ LOGGER.debug(Messages.QMAN_200002_OPCODE_HANDLER_ASSOCIATION,entry.getKey(),entry.getValue());
+ }
+ }
+ }
+ }
+
+ Map<Character, IMessageHandler> _handlers = new HashMap<Character, IMessageHandler>();
+ private DomainModel _domainModel;
+
+ /**
+ * Builds a new message listener with the given broker domain model.
+ *
+ * @param model the managed broker domain model.
+ */
+ BrokerMessageListener(DomainModel model)
+ {
+ this._domainModel = model;
+ }
+
+ /**
+ * When a new message arrives this method is called.
+ * 1) Performs a sanity check on the message (magic number, sequence number)
+ * 2) Extracts the opcode and looks for one message handler associated with that opcode.
+ * 3) If a message handler is found the delegates the message processing; otherwise a log message is written to indicate
+ * that the message will be skipped.
+ *
+ * @param message the incoming message.
+ */
+ public void onMessage (Message compoundMessage)
+ {
+ try
+ {
+ MessageTokenizer tokenizer = new MessageTokenizer(compoundMessage);
+ while (tokenizer.hasMoreElements())
+ {
+ dispatch(tokenizer.nextElement());
+ }
+ } catch(IOException exception)
+ {
+ LOGGER.error(exception,Messages.QMAN_100002_MESSAGE_READ_FAILURE);
+ } catch(Exception exception)
+ {
+ LOGGER.error(exception,Messages.QMAN_100003_MESSAGE_PROCESS_FAILURE);
+ }
+ }
+
+ /**
+ * Configures a new handler with this listener.
+ * After that, each time a message arrives with the specified opcode, this handler will be responsible for
+ * processing.
+ * Note that calling this method will switch this listener to a WORKING state.
+ *
+ * @param opcode the operation code.
+ * @param handler the message handler.
+ */
+ void setHandlers(Map<Character, IMessageHandler> handlers)
+ {
+ for (Entry<Character, IMessageHandler> entry : handlers.entrySet())
+ {
+ char opcode = entry.getKey();
+ IMessageHandler handler = entry.getValue();
+ try
+ {
+ handler.setDomainModel(_domainModel);
+ _handlers.put(opcode, handler);
+ } catch (Exception exception) {
+ LOGGER.error(exception,
+ Messages.QMAN_100004_HANDLER_INITIALIZATION_FAILURE,
+ opcode);
+ }
+ }
+ }
+
+
+
+ /**
+ * Dispatches the given message to the appropriate handler.
+ *
+ * @param message
+ * the incoming message.
+ * @throws IOException
+ * when the message content cannot be read.
+ */
+ private void dispatch(Message message) throws IOException
+ {
+ ByteBuffer buffer = message.readData();
+
+ String magicNumber = new String(new byte[] {buffer.get(),buffer.get(),buffer.get()});
+ if (!Protocol.MAGIC_NUMBER.equals(magicNumber))
+ {
+ LOGGER.error(Messages.QMAN_100001_BAD_MAGIC_NUMBER_FAILURE,magicNumber);
+ return;
+ }
+
+ char opcode = (char)buffer.get();
+
+ IMessageHandler handler = _handlers.get(opcode);
+ if (handler != null)
+ {
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(buffer);
+
+ LOGGER.debug(Messages.QMAN_200003_MESSAGE_FORWARDING,opcode,handler);
+
+ handler.process(decoder,decoder.readSequenceNo());
+ } else
+ {
+ LOGGER.warn(Messages.QMAN_300001_MESSAGE_DISCARDED,opcode);
+ Log.debugConfiguredHandlers(_handlers);
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.java
new file mode 100644
index 0000000000..a6f5ab90cc
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.java
@@ -0,0 +1,249 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.services;
+
+import java.util.UUID;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.configuration.BrokerConnectionData;
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.domain.model.DomainModel;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * This is the Object representation of a management client.
+ * According to specification : "A software component that is separate from the messaging broker, connected to the
+ * management broker via an AMQP connection, which allows any software component to be managed remotely by QPID."
+ *
+ * @author Andrea Gazzarini
+ */
+public final class ManagementClient
+{
+ private final static Logger LOGGER = Logger.get(ManagementClient.class);
+
+ private final String _managementQueueName;
+ private final String _methodReplyQueueName;
+
+ private DomainModel _domainModel;
+ private QpidService _service;
+
+ private final BrokerConnectionData _connectionData;
+
+ /**
+ * Builds a new <code>ManagementClient</code> with the given identifier and connection data.
+ *
+ * @param brokerId the broker identifier.
+ * @param connectionData the broker connection data (host, port, etc...)
+ */
+ ManagementClient(UUID brokerId,BrokerConnectionData connectionData)
+ {
+ _connectionData = connectionData;
+ _service = new QpidService(brokerId);
+ _domainModel = new DomainModel(brokerId);
+ _managementQueueName = Configuration.getInstance().getManagementQueueName();
+ _methodReplyQueueName = Configuration.getInstance().getMethodReplyQueueName();
+ }
+
+ @Override
+ public String toString()
+ {
+ return _connectionData.toString();
+ }
+
+ /**
+ * Returns the connection data associated with this management client.
+ *
+ * @return the connection data associated with this management client.
+ */
+ public BrokerConnectionData getBrokerConnectionData()
+ {
+ return _connectionData;
+ }
+
+ /**
+ * Establishing initial communication Between Client and Broker.
+ * According to specification :
+ * "Communication is established between the management client and management agent using normal AMQP procedures.
+ * The client creates a connection to the broker and then establishes a session with its corresponding channel.
+ * Two private queues are then declared.
+ * A management queue is declared and bound to the qpid.management exchange with "mgmt.#" as routing key; in that
+ * way all management-related messages sent to the exchange will be received by this client.
+ * When a client successfully binds to the qpid.management exchange, the management agent schedules a schema
+ * broadcast to be sent to the exchange.
+ * The agent will publish, via the exchange, a description of the schema for all manageable objects in its control. That
+ * schema is therefore received by this service and it will be part of service's domain model."
+ *
+ * @throws StartupFailureException when this management client cannot perform startup operations due to an error.
+ */
+ void estabilishFirstConnectionWithBroker() throws StartupFailureException{
+ try {
+ connectWithBroker();
+
+ createAndBindMethodReplyQueue();
+ createAndBindManagementQueue();
+
+ registerConsumerOnManagementQueue();
+ registerConsumerOnMethodReplyQueue();
+
+ synchronize();
+ } catch(Exception exception)
+ {
+ try {
+ _service.close();
+ } catch(Exception ignore)
+ {
+ }
+ throw new StartupFailureException(exception);
+ }
+ }
+
+ /**
+ * Shutdown procedure for this management client.
+ */
+ void shutdown ()
+ {
+ LOGGER.info(Messages.QMAN_000011_SHUTDOWN_INITIATED,_domainModel.getBrokerId());
+
+ removeMethodReplyConsumer();
+ destroyAndUnbingMethodReplyQueue();
+
+ removeManagementConsumer();
+ destroyAndUnbingManagementQueue();
+
+ _domainModel.releaseResources();
+
+ _service.close();
+
+ LOGGER.info(Messages.QMAN_000012_MANAGEMENT_CLIENT_SHUT_DOWN,_domainModel.getBrokerId());
+ }
+
+ /**
+ * Registers a consumer (that is, a listener) on the method-reply queue.
+ */
+ private void registerConsumerOnMethodReplyQueue ()
+ {
+ BrokerMessageListener methodReplyChannelListener = new BrokerMessageListener(_domainModel);
+ methodReplyChannelListener.setHandlers(Configuration.getInstance().getMethodReplyQueueHandlers());
+ _service.createSubscription(_methodReplyQueueName, _methodReplyQueueName, methodReplyChannelListener);
+
+ LOGGER.info(Messages.QMAN_000013_METHOD_REPLY_CONSUMER_INSTALLED, _domainModel.getBrokerId());
+ }
+
+ /**
+ * Registers a consumer (listener) on the management queue.
+ */
+ private void registerConsumerOnManagementQueue ()
+ {
+ BrokerMessageListener managementChannelListener = new BrokerMessageListener(_domainModel);
+ managementChannelListener.setHandlers(Configuration.getInstance().getManagementQueueHandlers());
+ _service.createSubscription(_managementQueueName, _managementQueueName, managementChannelListener);
+
+ LOGGER.info(Messages.QMAN_000014_MANAGEMENT_CONSUMER_INSTALLED, _domainModel.getBrokerId());
+ }
+
+ /**
+ * Declares a management queue and bound it to the "qpid.management" exchange with "mgmt.#" as routing key;
+ */
+ private void createAndBindManagementQueue ()
+ {
+ _service.declareQueue(_managementQueueName);
+ _service.declareBinding(
+ _managementQueueName,
+ Names.MANAGEMENT_EXCHANGE,
+ Names.MANAGEMENT_ROUTING_KEY);
+
+ LOGGER.info(Messages.QMAN_000015_MANAGEMENT_QUEUE_DECLARED,_managementQueueName,_domainModel.getBrokerId());
+ }
+
+ /**
+ * Declares a private queue for receiving method replies (after method invocations).
+ * This queue is bound to the amq.direct exchange using a routing key equal to the name of the queue.
+ */
+ private void createAndBindMethodReplyQueue ()
+ {
+ _service.declareQueue(_methodReplyQueueName);
+ _service.declareBinding(_methodReplyQueueName, Names.AMQ_DIRECT_QUEUE, _methodReplyQueueName);
+
+ LOGGER.info(Messages.QMAN_000016_METHOD_REPLY_QUEUE_DECLARED,_methodReplyQueueName, _domainModel.getBrokerId());
+ }
+
+ /**
+ * Removes the method-reply queue consumer.
+ */
+ private void removeMethodReplyConsumer()
+ {
+ _service.removeSubscription(_methodReplyQueueName);
+
+ LOGGER.info(Messages.QMAN_000017_CONSUMER_HAS_BEEN_REMOVED,_methodReplyQueueName,_domainModel.getBrokerId());
+ }
+
+ /**
+ * Unbind the method reply queue and after that destroy it from remote broker.
+ */
+ private void destroyAndUnbingMethodReplyQueue()
+ {
+ _service.declareUnbinding(_methodReplyQueueName, Names.AMQ_DIRECT_QUEUE, _methodReplyQueueName);
+ _service.deleteQueue(_methodReplyQueueName);
+
+ LOGGER.info(Messages.QMAN_000018_QUEUE_UNDECLARED,_methodReplyQueueName,_domainModel.getBrokerId());
+ }
+
+ /**
+ * Removes the management queue consumer.
+ */
+ private void removeManagementConsumer()
+ {
+ _service.removeSubscription(_managementQueueName);
+
+ LOGGER.info(Messages.QMAN_000017_CONSUMER_HAS_BEEN_REMOVED,_managementQueueName,_domainModel.getBrokerId());
+ }
+
+ /**
+ * Unbind the management queue and after that destroy it from remote broker.
+ */
+ private void destroyAndUnbingManagementQueue()
+ {
+ _service.declareUnbinding(_managementQueueName, Names.MANAGEMENT_EXCHANGE, Names.MANAGEMENT_ROUTING_KEY);
+ _service.deleteQueue(_managementQueueName);
+
+ LOGGER.info(Messages.QMAN_000018_QUEUE_UNDECLARED, _managementQueueName,_domainModel.getBrokerId());
+ }
+
+ /**
+ * Connects this client with the broker.
+ *
+ * @throws QpidException when it's not possibile to connect with the broker.
+ */
+ private void connectWithBroker() throws Exception
+ {
+ _service.connect();
+ }
+
+ /**
+ * All the Management client commands are asynchronous.
+ * Synchronous behavior is achieved through invoking the sync method.
+ */
+ private void synchronize()
+ {
+ _service.sync();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MessageTokenizer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MessageTokenizer.java
new file mode 100644
index 0000000000..9275255517
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MessageTokenizer.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.management.domain.services;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.apache.qpid.api.Message;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.nclient.util.ByteBufferMessage;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * The message tokenizer class allows a multi message listener to break a
+ * message into tokens where each token is itself a valid AMQP message.
+ *
+ * @author Andrea Gazzarini
+ * @see QPID-1368
+ */
+class MessageTokenizer implements Enumeration<Message>
+{
+ private final static Logger LOGGER = Logger.get(MessageTokenizer.class);
+
+ static byte [] MAGIC_NUMBER_BYTES;
+
+ private LinkedList<Message> _messages = new LinkedList<Message>();
+ private Iterator<Message> _iterator;
+
+ static
+ {
+ try
+ {
+ MAGIC_NUMBER_BYTES = Protocol.MAGIC_NUMBER.getBytes("UTF-8");
+ } catch(Exception exception)
+ {
+ throw new ExceptionInInitializerError(exception);
+ }
+ }
+
+ /**
+ * Builds a new Message tokenizer with the given message.
+ * Note that if the given message is not a "compound" message this tokenizer will producer only one token;
+ * That is, the token is a message equals to the given message.
+ *
+ * @param compoundMessage the compound message
+ * @throws IOException when it's not possible to read the given message content.
+ */
+ MessageTokenizer(Message compoundMessage) throws IOException
+ {
+ build(compoundMessage);
+ }
+
+ public boolean hasMoreElements()
+ {
+ return _iterator.hasNext();
+ }
+
+ public Message nextElement()
+ {
+ return _iterator.next();
+ }
+
+ /**
+ * Retruns the number of the tokens produced by this tokenizer.
+ *
+ * @return the number of the tokens produced by this tokenizer.
+ */
+ public int countTokens()
+ {
+ return _messages.size();
+ }
+
+ // Internal methods used for splitting the multi message byte array.
+ int indexOf(byte[] source, int startIndex)
+ {
+ int currentSourceIndex;
+ int currentExampleIndex;
+
+ if (startIndex + 3 > source.length)
+ return -1;
+
+ for (currentSourceIndex = startIndex; currentSourceIndex <= source.length - 3; currentSourceIndex++)
+ {
+ for (currentExampleIndex = 0; currentExampleIndex < 3; currentExampleIndex++)
+ {
+ if (source[currentSourceIndex + currentExampleIndex] != MAGIC_NUMBER_BYTES[currentExampleIndex])
+ break;
+ }
+
+ if (currentExampleIndex == 3)
+ return currentSourceIndex;
+ }
+ return -1;
+ }
+
+ // Internal method used for building the tokens.
+ private void build(Message compoundMessage) throws IOException
+ {
+ int startIndex = 0;
+ int indexOfMagicNumber = 0;
+
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(compoundMessage.readData());
+ byte [] source = decoder.readReaminingBytes();
+
+ int howManyTokens = 1;
+
+ while ((indexOfMagicNumber = indexOf(source, startIndex+1)) != -1)
+ {
+ addMessageToken(source, startIndex, (indexOfMagicNumber-startIndex));
+ startIndex = indexOfMagicNumber;
+ howManyTokens++;
+ }
+ addMessageToken(source, startIndex, (source.length-startIndex));
+ _iterator = _messages.iterator();
+
+ LOGGER.debug(Messages.QMAN_200031_COMPOUND_MESSAGE_CONTAINS,howManyTokens);
+ };
+
+ // Builds & adds a new "message" token
+ private void addMessageToken(byte [] source,int startIndex,int length) throws IOException
+ {
+ byte [] messageData = new byte[length];
+ System.arraycopy(source, startIndex, messageData, 0, messageData.length);
+ Message message = new ByteBufferMessage();
+ message.appendData(messageData);
+ _messages.add(message);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MethodInvocationException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MethodInvocationException.java
new file mode 100644
index 0000000000..26fd8eee24
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MethodInvocationException.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.services;
+
+public class MethodInvocationException extends Exception
+{
+ private static final long serialVersionUID = -7772343434879470351L;
+ private final long _returnCode;
+ private final String _statusText;
+
+ public MethodInvocationException(long code, String text)
+ {
+ this._returnCode = code;
+ this._statusText = text;
+ }
+
+ @Override
+ public String getMessage ()
+ {
+ return String.format("Return code : \"%s, reason : \"%s\"",_returnCode,_statusText);
+ }
+
+ public long getReturnCode ()
+ {
+ return _returnCode;
+ }
+
+ public String getStatusText ()
+ {
+ return _statusText;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java
new file mode 100644
index 0000000000..c4c0ce5e74
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java
@@ -0,0 +1,412 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.services;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.DynamicMBean;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationListener;
+import javax.management.ReflectionException;
+
+import org.apache.log4j.xml.DOMConfigurator;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.configuration.BrokerAlreadyConnectedException;
+import org.apache.qpid.management.configuration.BrokerConnectionData;
+import org.apache.qpid.management.configuration.BrokerConnectionException;
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.configuration.Configurator;
+import org.apache.qpid.management.domain.model.JmxService;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Main entry point for starting Q-Man application.
+ */
+public class QMan extends NotificationBroadcasterSupport implements DynamicMBean, NotificationListener
+{
+ private final static Logger LOGGER = Logger.get(QMan.class);
+ private final List<ManagementClient> managementClients = new ArrayList<ManagementClient>();
+
+ private Configurator _configurator = new Configurator();
+ private ThreadPoolExecutor _workManager;
+
+ /**
+ * Starts QMan.
+ * @throws StartupFailureException when it's not possible to proceed with startup.
+ */
+ public void start() throws StartupFailureException
+ {
+ LOGGER.info(Messages.QMAN_000001_STARTING_QMAN);
+ LOGGER.info(Messages.QMAN_000002_READING_CONFIGURATION);
+
+ try
+ {
+ registerQManService();
+
+ _configurator.configure();
+
+ configureWorkManager();
+
+ LOGGER.info(Messages.QMAN_000019_QMAN_STARTED);
+ } catch(Exception exception) {
+ LOGGER.error(exception,Messages.QMAN_100018_UNABLE_TO_STARTUP_CORRECTLY );
+ throw new StartupFailureException(exception);
+ }
+ }
+
+ /**
+ * Connects Q-Man with a broker defined by the given parameter.
+ *
+ * @param host the hostname where the broker is running.
+ * @param port the port where the broker is running.
+ * @param username the username for connecting with the broker.
+ * @param password the password for connecting with the broker.
+ * @param virtualHost the virtual host.
+ * @param initialPoolCapacity the number of the connection that must be immediately opened.
+ * @param maxPoolCapacity the maximum number of opened connection.
+ * @param maxWaitTimeout the maximum amount of time that a client will wait for obtaining a connection.
+ * @throws MBeanException when it's not possible to connect with the broker.
+ */
+ public void addBroker(
+ String host,
+ int port,
+ String username,
+ String password,
+ String virtualHost,
+ int initialPoolCapacity,
+ int maxPoolCapacity,
+ long maxWaitTimeout) throws BrokerAlreadyConnectedException, BrokerConnectionException
+ {
+ Configurator configurator = new Configurator();
+ try {
+ UUID brokerId = UUID.randomUUID();
+ BrokerConnectionData data = configurator.createAndReturnBrokerConnectionData(
+ brokerId,
+ host,
+ port,
+ username,
+ password,
+ virtualHost,
+ initialPoolCapacity,
+ maxPoolCapacity,
+ maxWaitTimeout);
+ createManagementClient(brokerId, data);
+ } catch (BrokerAlreadyConnectedException exception)
+ {
+ LOGGER.warn(Messages.QMAN_300003_BROKER_ALREADY_CONNECTED, exception.getBrokerConnectionData());
+ throw exception;
+ }
+ }
+
+ /**
+ * Stop Qman
+ */
+ public void stop()
+ {
+ LOGGER.info(Messages.QMAN_000020_SHUTTING_DOWN_QMAN);
+ try
+ {
+ for (ManagementClient client : managementClients)
+ {
+ client.shutdown();
+ }
+ } catch(Exception exception)
+ {
+ }
+ LOGGER.info(Messages.QMAN_000021_SHUT_DOWN);
+ }
+
+ /**
+ * Creates a management client using the given data.
+ *
+ * @param brokerId the broker identifier.
+ * @param data the broker connection data.
+ */
+ public void createManagementClient(UUID brokerId, BrokerConnectionData data)
+ {
+ try
+ {
+ ManagementClient client = new ManagementClient(brokerId,data);
+ client.estabilishFirstConnectionWithBroker();
+ managementClients.add(client);
+
+ LOGGER.info(Messages.QMAN_000004_MANAGEMENT_CLIENT_CONNECTED,brokerId);
+ } catch(StartupFailureException exception) {
+ LOGGER.error(exception, Messages.QMAN_100017_UNABLE_TO_CONNECT,brokerId,data);
+ }
+ }
+
+ /**
+ * Returns the list of management clients currently handled by QMan.
+ *
+ * @return the list of management clients currently handled by QMan.
+ */
+ public List<ManagementClient> getManagementClients()
+ {
+ return managementClients;
+ }
+
+ /**
+ * Injects the configurator on this QMan instance.
+ * That configutator later will be responsible to manage the configuration.
+ *
+ * @param configurator the configurator to be injected.
+ */
+ public void setConfigurator(Configurator configurator){
+ this._configurator = configurator;
+ }
+
+ /**
+ * Main method used for starting Q-Man.
+ *
+ * @param args the command line arguments.
+ */
+ public static void main (String[] args)
+ {
+ if (args.length == 1)
+ {
+ String logFileName = args[0];
+ DOMConfigurator.configureAndWatch(logFileName,5000);
+ }
+
+ final QMan qman = new QMan();
+
+ Thread hook = new Thread()
+ {
+ @Override
+ public void run ()
+ {
+ qman.stop();
+ }
+ };
+
+ Runtime.getRuntime().addShutdownHook(hook);
+ try
+ {
+ qman.start();
+
+ System.out.println("Type \"q\" to quit.");
+ BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+ while ( !"q".equals(reader.readLine()) )
+ {
+
+ }
+ Runtime.getRuntime().removeShutdownHook(hook);
+ qman.stop();
+ System.exit(-1);
+ } catch (StartupFailureException exception)
+ {
+ qman.stop();
+ System.exit(-1);
+ } catch (IOException exception)
+ {
+ System.exit(-1);
+ }
+ }
+
+ /**
+ * Not implemented for this MBean.
+ */
+ public Object getAttribute(String attribute)
+ {
+ return null;
+ }
+
+ /**
+ * Not implemented for this MBean.
+ */
+ public AttributeList getAttributes(String[] attributes)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the metadata for this MBean
+ *
+ * @return the metadata for this MBean
+ */
+ public MBeanInfo getMBeanInfo()
+ {
+ MBeanParameterInfo parameters [] = new MBeanParameterInfo[8];
+
+ parameters[0] = new MBeanParameterInfo(
+ "host",
+ String.class.getName(),
+ "The IP address or DNS name that Qpid Broker uses to listen for incoming connections.");
+ parameters[1] = new MBeanParameterInfo(
+ "port",
+ int.class.getName(),
+ "The port number that Qpid Broker uses to listen for incoming connections.");
+ parameters[2] = new MBeanParameterInfo(
+ "username",
+ String.class.getName(),
+ "The Qpid account name used in the physical connection.");
+ parameters[3] = new MBeanParameterInfo(
+ "password",
+ String.class.getName(),
+ "The Qpid account password used in the physical connection.");
+ parameters[4]= new MBeanParameterInfo(
+ "virtualHost",
+ String.class.getName(),
+ "The virtualHost name.");
+ parameters[5]= new MBeanParameterInfo(
+ "initialPoolCapacity",
+ int.class.getName(),
+ "The number of physical connections (between 0 and a positive 32-bit integer) to create when creating the (Qpid) connection pool.");
+ parameters[6]= new MBeanParameterInfo(
+ "maxPoolCapacity",
+ int.class.getName(),
+ "The maximum number of physical database connections (between 0 and a positive 32-bit integer) that the (Qpid) connection pool can contain. ");
+ parameters[7]= new MBeanParameterInfo(
+ "maxWaitTimeout",
+ long.class.getName(),
+ "The maximum amount of time to wait for an idle connection.A value of -1 indicates an illimted amount of time (i.e. forever)");
+
+ MBeanOperationInfo operation = new MBeanOperationInfo(
+ "addBroker",
+ "Connects QMan with a broker.",
+ parameters,
+ void.class.getName(),
+ MBeanOperationInfo.ACTION);
+
+ MBeanInfo mbean = new MBeanInfo(
+ QMan.class.getName(),
+ "QMan Management & Administration interface.",
+ null,
+ null,
+ new MBeanOperationInfo[]{operation},
+ null);
+
+ return mbean;
+ }
+
+ /**
+ * Invokes an operation on QMan (MBean).
+ *
+ * @param actionName the operation name.
+ * @param params the operation parameters.
+ * @param signature the operation signature.
+ * @return the result of the invocation (if the operation is not void);
+ * @exception MBeanException Wraps a <CODE>java.lang.Exception</CODE> thrown by the MBean's invoked method.
+ * @exception ReflectionException Wraps a <CODE>java.lang.Exception</CODE> thrown while trying to invoke the method
+ */
+ public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException
+ {
+ if (Names.ADD_BROKER_OPERATION_NAME.equals(actionName))
+ {
+ try
+ {
+ addBroker(
+ (String)params[0],
+ (Integer)params[1],
+ (String)params[2],
+ (String)params[3],
+ (String)params[4],
+ (Integer)params[5],
+ (Integer)params[6],
+ (Long)params[7]);
+ } catch(Exception exception)
+ {
+ throw new MBeanException(exception);
+ }
+ } else
+ {
+ throw new ReflectionException(new NoSuchMethodException(actionName));
+ }
+ return null;
+ }
+
+ /**
+ * Not implemented for this MBean.
+ */
+ public void setAttribute(Attribute attribute)
+ {
+ }
+
+ /**
+ * Not implemented for this MBean.
+ */
+ public AttributeList setAttributes(AttributeList attributes)
+ {
+ return null;
+ }
+
+ /**
+ * Simply dispatches the incoming notification to registered listeners.
+ * Consider that the notification is sent asynchronously so the QMan current thread is not
+ * waiting for completion of receiver task.
+ *
+ * @param notification the incoming notification.
+ * @param handback the context associated to this notification.
+ */
+ public void handleNotification(final Notification notification, Object handback)
+ {
+ _workManager.execute(new Runnable(){
+ public void run()
+ {
+ sendNotification(notification);
+ }
+ });
+ }
+
+ /**
+ * Registers QMan as an MBean on MBeanServer.
+ *
+ * @throws MBeanException when it's not possible to proceeed with registration.
+ */
+ private void registerQManService() throws MBeanException
+ {
+ JmxService service = new JmxService();
+ service.registerQManService(this);
+
+ LOGGER.info(Messages.QMAN_000023_QMAN_REGISTERED_AS_MBEAN);
+ }
+
+ /**
+ * Configures work manager component.
+ */
+ private void configureWorkManager()
+ {
+ Configuration configuration = Configuration.getInstance();
+ _workManager = new ThreadPoolExecutor(
+ configuration.getWorkerManagerPoolSize(),
+ configuration.getWorkerManagerMaxPoolSize(),
+ configuration.getWorkerManagerKeepAliveTime(),
+ TimeUnit.MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(30));
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java
new file mode 100644
index 0000000000..bd7d305184
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.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.management.domain.services;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.qpid.api.Message;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.configuration.QpidDatasource;
+import org.apache.qpid.management.domain.model.QpidMethod;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.management.messages.MethodInvocationRequestMessage;
+import org.apache.qpid.management.messages.SchemaRequestMessage;
+import org.apache.qpid.nclient.util.MessageListener;
+import org.apache.qpid.nclient.util.MessagePartListenerAdapter;
+import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.MessageAcceptMode;
+import org.apache.qpid.transport.MessageAcquireMode;
+import org.apache.qpid.transport.MessageCreditUnit;
+import org.apache.qpid.transport.MessageTransfer;
+import org.apache.qpid.transport.Option;
+import org.apache.qpid.transport.Session;
+import org.apache.qpid.transport.SessionException;
+import org.apache.qpid.transport.SessionListener;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Qpid Broker facade.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidService implements SessionListener
+{
+ private final static Logger LOGGER = Logger.get(QpidService.class);
+
+ private UUID _brokerId;
+ private Connection _connection;
+ private Session _session;
+ private Map<String,MessagePartListenerAdapter> _listeners;
+
+ /**
+ * Builds a new service with the given connection data.
+ *
+ * @param connectionData the connection data of the broker.
+ */
+ public QpidService(UUID brokerId)
+ {
+ this._brokerId = brokerId;
+ }
+
+ /**
+ * Estabilishes a connection with the broker.
+ *
+ * @throws QpidException in case of connection failure.
+ */
+ public void connect() throws Exception
+ {
+ _connection = QpidDatasource.getInstance().getConnection(_brokerId);
+ _listeners = new ConcurrentHashMap<String,MessagePartListenerAdapter>();
+ _session = _connection.createSession(0);
+ _session.setSessionListener(this);
+ }
+
+ public void opened(Session ssn) {}
+
+ public void resumed(Session ssn) {}
+
+ public void message(Session ssn, MessageTransfer xfr)
+ {
+ MessagePartListenerAdapter l = _listeners.get(xfr.getDestination());
+ if (l == null)
+ {
+ LOGGER.error("unhandled message: %s", xfr);
+ }
+ else
+ {
+ l.messageTransfer(xfr);
+ }
+ }
+
+
+ public void exception(Session ssn, SessionException exc)
+ {
+
+ }
+
+ public void closed(Session ssn) {}
+
+ /**
+ * All the previously entered outstanding commands are asynchronous.
+ * Synchronous behavior is achieved through invoking this method.
+ */
+ public void sync()
+ {
+ _session.sync();
+ }
+
+ /**
+ * Closes communication with broker.
+ */
+ public void close()
+ {
+ try
+ {
+ _session.close();
+ _session = null;
+ _listeners = null;
+ } catch (Exception e)
+ {
+ }
+ try
+ {
+ _connection.close();
+ _connection = null;
+ } catch (Exception e)
+ {
+ }
+ }
+
+ /**
+ * Associate a message listener with a destination therefore creating a new subscription.
+ *
+ * @param queueName The name of the queue that the subscriber is receiving messages from.
+ * @param destinationName the name of the destination, or delivery tag, for the subscriber.
+ * @param listener the listener for this destination.
+ *
+ * @see Session#messageSubscribe(String, String, short, short, org.apache.qpid.nclient.MessagePartListener, java.util.Map, org.apache.qpid.transport.Option...)
+ */
+ public void createSubscription(String queueName, String destinationName, MessageListener listener)
+ {
+ _listeners.put(destinationName, new MessagePartListenerAdapter(listener));
+ _session.messageSubscribe
+ (queueName,
+ destinationName,
+ MessageAcceptMode.NONE,
+ MessageAcquireMode.PRE_ACQUIRED,
+ null, 0, null);
+
+ _session.messageFlow(destinationName, MessageCreditUnit.BYTE, Session.UNLIMITED_CREDIT);
+ _session.messageFlow(destinationName, MessageCreditUnit.MESSAGE, Session.UNLIMITED_CREDIT);
+
+ LOGGER.debug(Messages.QMAN_200025_SUBSCRIPTION_DECLARED,queueName,destinationName);
+ }
+
+ /**
+ * Removes a previously declared consumer from the broker.
+ *
+ * @param destinationName the name of the destination, or delivery tag, for the subscriber.
+ * @see Session#messageCancel(String, Option...)
+ */
+ public void removeSubscription(String destinationName)
+ {
+ _session.messageCancel(destinationName);
+ LOGGER.debug(Messages.QMAN_200026_SUBSCRIPTION_REMOVED,destinationName);
+ }
+
+ /**
+ * Declares a queue on the broker with the given name.
+ *
+ * @param queueName the name of the declared queue.
+ * @see Session#queueDeclare(String, String, java.util.Map, Option...)
+ */
+ public void declareQueue(String queueName)
+ {
+ _session.queueDeclare(queueName, null, null);
+ LOGGER.debug(Messages.QMAN_200027_QUEUE_DECLARED,queueName);
+ }
+
+ /**
+ * Removes the queue with the given name from the broker.
+ *
+ * @param queueName the name of the queue.
+ * @see Session#queueDelete(String, Option...)
+ */
+ public void deleteQueue(String queueName)
+ {
+ _session.queueDelete(queueName);
+ LOGGER.debug(Messages.QMAN_200028_QUEUE_REMOVED,queueName);
+ }
+
+ /**
+ * Binds (on the broker) a queue with an exchange.
+ *
+ * @param queueName the name of the queue to bind.
+ * @param exchangeName the exchange name.
+ * @param routingKey the routing key used for the binding.
+ * @see Session#exchangeBind(String, String, String, java.util.Map, Option...)
+ */
+ public void declareBinding(String queueName, String exchangeName, String routingKey)
+ {
+ _session.exchangeBind(queueName, exchangeName, routingKey, null);
+ LOGGER.debug(Messages.QMAN_200029_BINDING_DECLARED,routingKey,queueName,exchangeName);
+ }
+
+ /**
+ * Removes a previously declare binding between an exchange and a queue.
+ *
+ * @param queueName the name of the queue.
+ * @param exchangeName the name of the exchange.
+ * @param routingKey the routing key used for binding.
+ */
+ public void declareUnbinding(String queueName, String exchangeName, String routingKey)
+ {
+ _session.exchangeUnbind(queueName, exchangeName, routingKey);
+ LOGGER.debug(Messages.QMAN_200030_BINDING_REMOVED,routingKey,queueName,exchangeName);
+ }
+
+ /**
+ * Sends a command message with the given data on the management queue.
+ *
+ * @param messageData the command message content.
+ */
+
+ /**
+ * Requests a schema for the given package.class.hash.
+ *
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param schemaHash the schema hash.
+ * @throws IOException when the schema request cannot be sent.
+ */
+ public void requestSchema(final String packageName, final String className, final Binary schemaHash) throws IOException
+ {
+ Message message = new SchemaRequestMessage()
+ {
+ @Override
+ protected String className ()
+ {
+ return className;
+ }
+
+ @Override
+ protected String packageName ()
+ {
+ return packageName;
+ }
+
+ @Override
+ protected Binary schemaHash ()
+ {
+ return schemaHash;
+ }
+ };
+
+ sendMessage(message);
+ }
+
+ /**
+ * Invokes an operation on a broker object instance.
+ *
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param schemaHash the schema hash of the corresponding class.
+ * @param objectId the object instance identifier.
+ * @param parameters the parameters for this invocation.
+ * @param method the method (definition) invoked.
+ * @param bankId the object bank identifier.
+ * @param brokerId the broker identifier.
+ * @return the sequence number used for this message.
+ * @throws MethodInvocationException when the invoked method returns an error code.
+ * @throws UnableToComplyException when it wasn't possibile to invoke the requested operation.
+ */
+ public void invoke(
+ final String packageName,
+ final String className,
+ final Binary schemaHash,
+ final Binary objectId,
+ final Object[] parameters,
+ final QpidMethod method,
+ final int sequenceNumber,
+ final long bankId,
+ final long brokerId) throws MethodInvocationException, UnableToComplyException
+ {
+ Message message = new MethodInvocationRequestMessage(bankId, brokerId)
+ {
+
+ @Override
+ protected int sequenceNumber ()
+ {
+ return sequenceNumber;
+ }
+
+ protected Binary objectId() {
+ return objectId;
+ }
+
+ protected String packageName()
+ {
+ return packageName;
+ }
+
+ protected String className()
+ {
+ return className;
+ }
+
+ @Override
+ protected QpidMethod method ()
+ {
+ return method;
+ }
+
+ @Override
+ protected Object[] parameters ()
+ {
+ return parameters;
+ }
+
+ @Override
+ protected Binary schemaHash ()
+ {
+ return schemaHash;
+ }
+ };
+
+ try {
+ sendMessage(message);
+ sync();
+ } catch(Exception exception) {
+ throw new UnableToComplyException(exception);
+ }
+ }
+
+ /**
+ * Sends a command message.
+ *
+ * @param message the command message.
+ * @throws IOException when the message cannot be sent.
+ */
+ public void sendMessage(Message message) throws IOException
+ {
+ _session.messageTransfer(
+ Names.MANAGEMENT_EXCHANGE,
+ MessageAcceptMode.EXPLICIT,
+ MessageAcquireMode.PRE_ACQUIRED,
+ message.getHeader(),
+ message.readData());
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/SequenceNumberGenerator.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/SequenceNumberGenerator.java
new file mode 100644
index 0000000000..e6d99971cd
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/SequenceNumberGenerator.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.management.domain.services;
+
+/**
+ * Sequence number generator utility class.
+ *
+ * @author Andrea Gazzarini
+ */
+public class SequenceNumberGenerator
+{
+ private static int sequenceNumber;
+
+ /**
+ * Returns a valid sequence number.
+ *
+ * @return a sequence number.
+ */
+ public static synchronized int getNextSequenceNumber()
+ {
+ return sequenceNumber++;
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/StartupFailureException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/StartupFailureException.java
new file mode 100644
index 0000000000..9da8832624
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/StartupFailureException.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.management.domain.services;
+
+/**
+ * Thrown in case of service startup failure.
+ * For example the configuration file couldn't be read because is not well-formed.
+ *
+ * @author Andrea Gazzarini.
+ */
+public class StartupFailureException extends Exception
+{
+ private static final long serialVersionUID = -4102037574602857703L;
+
+ /**
+ * Builds a new StartupFailureException with the given exception.
+ *
+ * @param exception the exception cause.
+ */
+ public StartupFailureException(Exception exception)
+ {
+ super(exception);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/UnableToComplyException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/UnableToComplyException.java
new file mode 100644
index 0000000000..2ab9a41e75
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/UnableToComplyException.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.management.domain.services;
+
+public class UnableToComplyException extends Exception
+{
+ public UnableToComplyException(Exception exception)
+ {
+ super(exception);
+ }
+
+ private static final long serialVersionUID = -3071434478559509435L;
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/EntityLifecycleNotification.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/EntityLifecycleNotification.java
new file mode 100644
index 0000000000..d7f9d8d6f0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/EntityLifecycleNotification.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.management.jmx;
+
+import javax.management.Notification;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.services.SequenceNumberGenerator;
+
+/**
+ * Q-Man JMX entity lifecycle notification.
+ * A notification is sent to interested listener by Q-Man on the following scenarios :
+ *
+ * <br> - A schema (class / event) has been requested (Schema request);
+ * <br> - A schema (class / event) has been injected (Schema response);
+ * <br> - A schema cannot be parsed (probably it is malformed);
+ * <br> - An object instance has been created (Instrumentation / Configuration response);
+ * <br> - An event instance has been created (Instrumentation / Configuration response);
+ * <br> - An object instance has been removed (Instrumentation / Configuration response);
+ *
+ * @author Andrea Gazzarini
+ */
+public class EntityLifecycleNotification extends Notification
+{
+ private static final long serialVersionUID = -7755773156742412161L;
+
+ public static final String SCHEMA_INJECTED_NOTIFICATION_TYPE = "org.apache.qpid.management.lifecycle.entity.schema.injected";
+ public static final String SCHEMA_REQUESTED_NOTIFICATION_TYPE = "org.apache.qpid.management.lifecycle.entity.schema.requested";
+ public static final String MALFORMED_SCHEMA_NOTIFICATION_TYPE = "org.apache.qpid.management.lifecycle.error.schema";
+
+ public static final String INSTANCE_ADDED_NOTIFICATION_TYPE = "qman.lifecycle.entity.instance.created";
+ public static final String INSTANCE_REMOVED_NOTIFICATION_TYPE = "qman.lifecycle.entity.instance.removed";
+
+ private String _packageName = Names.NOT_AVAILABLE;
+ private String _className = Names.NOT_AVAILABLE;
+ private String _classKind = Names.NOT_AVAILABLE;
+
+ private ObjectName _objectName;
+
+ /**
+ * Builds a new notification with the given parameters.
+ *
+ * @param type the notification type.
+ * @param sequenceNumber the sequence number.
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param classKind the class kind (i.e. class or event)
+ * @param objectName the object name of the affected mbean.
+ */
+ public EntityLifecycleNotification(
+ String type,
+ String packageName,
+ String className,
+ String classKind,
+ ObjectName objectName)
+ {
+ super(
+ type,
+ Names.APPLICATION_NAME,
+ SequenceNumberGenerator.getNextSequenceNumber());
+
+ this._className = className;
+ this._packageName = packageName;
+ this._classKind = classKind;
+ this._objectName = objectName;
+ }
+
+ /**
+ * Returns the package name of object contained in this notification.
+ *
+ * @return the package name of object contained in this notification.
+ */
+ public String getPackageName()
+ {
+ return _packageName;
+ }
+
+ /**
+ * Returns the class name of object contained in this notification.
+ *
+ * @return the class name of object contained in this notification.
+ */
+ public String getClassName()
+ {
+ return _className;
+ }
+
+ /**
+ * Returns the class kind of object contained in this notification.
+ *
+ * @return the class kind of object contained in this notification.
+ * @see Names#CLASS
+ * @see Names#EVENT
+ */
+ public String getClassKind()
+ {
+ return _classKind;
+ }
+
+ /**
+ * Returns the object name of object contained in this notification.
+ *
+ * @return the object name of object contained in this notification.
+ */
+ public ObjectName getObjectName()
+ {
+ return _objectName;
+ }
+
+ /**
+ * Returns a string representation of this notification.
+ *
+ * @return a string representation of this notification.
+ */
+ @Override
+ public String toString()
+ {
+ return new StringBuilder()
+ .append(getType())
+ .append(':')
+ .append(_packageName)
+ .append('.')
+ .append(_className)
+ .append('@')
+ .append(_objectName)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/OperationHasBeenInvokedNotification.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/OperationHasBeenInvokedNotification.java
new file mode 100644
index 0000000000..dec29c1b93
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/OperationHasBeenInvokedNotification.java
@@ -0,0 +1,168 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.jmx;
+
+import javax.management.Notification;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.handler.impl.InvocationResult;
+import org.apache.qpid.management.domain.services.SequenceNumberGenerator;
+
+/**
+ * Q-Man JMX method invocation notification.
+ * This kind of notification is sent to interested listener by Q-Man when
+ * a method has been invoked (Method invocation request)
+ *
+ * @author Andrea Gazzarini
+ */
+public class OperationHasBeenInvokedNotification extends Notification
+{
+ private static final long serialVersionUID = -7755773156742412161L;
+ public static final String NOTIFICATION_TYPE = "org.apache.qpid.management.operation.invoked";
+
+ private final String _operationName;
+ private final Object [] _parameters;
+ private final String [] _signature;
+ private final Exception _exception;
+ private final InvocationResult _result;
+
+ /**
+ * Builds a new notification with the given parameters.
+ *
+ * @param type the notification type.
+ * @param operationName the operation name.
+ * @param params the operation parameters.
+ * @param signature the operation signature.
+ * @param exception the exception raised by the invocation.
+ */
+ public OperationHasBeenInvokedNotification(
+ String operationName,
+ Object[] parameters,
+ String [] signature,
+ Exception exception)
+ {
+ super(
+ NOTIFICATION_TYPE,
+ Names.APPLICATION_NAME,
+ SequenceNumberGenerator.getNextSequenceNumber());
+
+ this._operationName= operationName;
+ this._parameters = parameters;
+ this._signature = signature;
+ this._result = null;
+ this._exception = exception;
+ }
+
+ /**
+ * Builds a new notification with the given parameters.
+ *
+ * @param type the notification type.
+ * @param operationName the operation name.
+ * @param params the operation parameters.
+ * @param signature the operation signature.
+ * @param objectName the target mbean object name.
+ * @param result the invocation result.
+ */
+ public OperationHasBeenInvokedNotification(
+ String operationName,
+ Object[] parameters,
+ String [] signature,
+ InvocationResult result)
+ {
+ super(
+ NOTIFICATION_TYPE,
+ Names.APPLICATION_NAME,
+ SequenceNumberGenerator.getNextSequenceNumber());
+
+ this._operationName= operationName;
+ this._parameters = parameters;
+ this._signature = signature;
+ this._result = result;
+ this._exception = null;
+ }
+
+ /**
+ * Returns the exception raised by this notification
+ * referred operation.
+ *
+ * @return the exception raised by this notification referred operation.
+ */
+ public Exception getException()
+ {
+ return _exception;
+ }
+
+ /**
+ * Returns the exception raised by this notification
+ * referred operation.
+ *
+ * @return the exception raised by this notification referred operation.
+ */
+ public InvocationResult getResult()
+ {
+ return _result;
+ }
+
+ /**
+ * Returns the operation name.
+ *
+ * @return the operation name.
+ */
+ public String getOperationName()
+ {
+ return _operationName;
+ }
+
+ /**
+ * Returns the parameters used in method invocation.
+ *
+ * @return the parameters used in method invocation.
+ */
+ public Object [] getParameters()
+ {
+ return _parameters;
+ }
+
+ /**
+ * Returns the signature of the invoked operation.
+ *
+ * @return the signature of the invoked operation.
+ */
+ public String [] getSignature()
+ {
+ return _signature;
+ }
+
+ /**
+ * Returns a string representation of this notification.
+ *
+ * @return a string representation of this notification.
+ */
+ @Override
+ public String toString()
+ {
+ return new StringBuilder()
+ .append(getType())
+ .append(':')
+ .append(_operationName)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/ManagementMessage.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/ManagementMessage.java
new file mode 100644
index 0000000000..2fa20fb456
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/ManagementMessage.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.management.messages;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.api.Message;
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.domain.services.SequenceNumberGenerator;
+import org.apache.qpid.transport.DeliveryProperties;
+import org.apache.qpid.transport.Header;
+import org.apache.qpid.transport.MessageProperties;
+import org.apache.qpid.transport.codec.BBEncoder;
+
+/**
+ * Message implementation used for specific management purposes.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class ManagementMessage implements Message
+{
+ /**
+ * Strategy interface for building / getting data.
+ *
+ * @author Andrea Gazzarini
+ */
+ private interface IDataBuilderStrategy
+ {
+ ByteBuffer getData();
+ };
+
+ /**
+ * Strategy used for retrieving raw data from this message when it has been already encoded.
+ */
+ IDataBuilderStrategy READING = new IDataBuilderStrategy()
+ {
+ public ByteBuffer getData() {
+ return _data;
+ };
+ };
+
+ /**
+ * Strategy used for retrieving raw data from this message when it hasn't been already encoded.
+ */
+ IDataBuilderStrategy ACCUMULATING = new IDataBuilderStrategy()
+ {
+ public ByteBuffer getData() {
+ _codec.writeInt8((byte)opcode());
+ _codec.writeSequenceNo(sequenceNumber());
+
+ specificMessageEncoding();
+
+ _data =_codec.segment();
+ _reader = READING;
+ return _data;
+ }
+ };
+
+ protected BBEncoder _codec;
+ protected ByteBuffer _data;
+ private int _messageTransferId;
+ private IDataBuilderStrategy _reader = ACCUMULATING;
+
+ /**
+ * Builds an empty management message.
+ */
+ ManagementMessage()
+ {
+ _codec = new BBEncoder(100);
+ _codec.writeMagicNumber();
+ }
+
+ /**
+ * Returns the sequence number that will be used for this message.
+ *
+ * @return the sequence number that will be used for this message.
+ */
+ protected int sequenceNumber ()
+ {
+ return SequenceNumberGenerator.getNextSequenceNumber();
+ }
+
+ /**
+ * Returns the opcode that will be used for this message.
+ *
+ * @return the opcode that will be used for this message.
+ */
+ abstract char opcode ();
+
+ /**
+ * Returns the delivery properties of this message.
+ *
+ * @return the delivery properties of this message.
+ */
+ public DeliveryProperties getDeliveryProperties ()
+ {
+ return Configuration.getInstance().getCommandDeliveryProperties();
+ }
+
+ /**
+ * Returns the header of this message.
+ *
+ * @return the header of this message.
+ */
+ public Header getHeader ()
+ {
+ return Configuration.getInstance().getCommandMessageHeader();
+ }
+
+ /**
+ * Returns the messages header properties of this message.
+ *
+ * @return the message header properties of this message.
+ */
+ public MessageProperties getMessageProperties ()
+ {
+ return Configuration.getInstance().getCommandMessageProperties();
+ }
+
+ /**
+ * Returns the transfer Id of this message.
+ *
+ * @return the transfer Id of this message.
+ */
+ public int getMessageTransferId ()
+ {
+ return _messageTransferId;
+ }
+
+ /**
+ * Returns the encoded data of this message.
+ *
+ * @return the encoded data of this message.
+ */
+ public ByteBuffer readData () throws IOException
+ {
+ return _reader.getData();
+ }
+
+ /**
+ * Sets the header for this message.
+ *
+ * @param header the new message header.
+ */
+ public void setHeader (Header header)
+ {
+ // N.A. at the moment.
+ }
+
+ public void appendData (byte[] src) throws IOException
+ {
+ }
+
+ public void appendData (ByteBuffer src) throws IOException
+ {
+ }
+
+ public void clearData ()
+ {
+ }
+
+ public void readData (byte[] target) throws IOException
+ {
+ }
+
+ /**
+ * Concrete subclasses (message implementations) must define here their specific data encoding.
+ */
+ abstract void specificMessageEncoding();
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/MethodInvocationRequestMessage.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/MethodInvocationRequestMessage.java
new file mode 100644
index 0000000000..99916085d6
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/MethodInvocationRequestMessage.java
@@ -0,0 +1,161 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.messages;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.domain.model.QpidMethod;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.transport.DeliveryProperties;
+import org.apache.qpid.transport.Header;
+import org.apache.qpid.transport.MessageProperties;
+import org.apache.qpid.transport.ReplyTo;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Abstract representation of a method invocation request message.
+ * Concrete subclasses must supply the values needed to build & encode the message.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class MethodInvocationRequestMessage extends ManagementMessage
+{
+ private final static Logger LOGGER = Logger.get(MethodInvocationRequestMessage.class);
+
+ private DeliveryProperties _deliveryProperties;
+ private MessageProperties _messageProperties;
+ private Header _header;
+
+ /**
+ * Builds a new method invocation request message with the given target identifiers.
+ *
+ * @param bankId the bank identifier.
+ * @param brokerId the broker identifier.
+ */
+ public MethodInvocationRequestMessage(long bankId, long brokerId)
+ {
+ ReplyTo replyTo=new ReplyTo();
+ replyTo.setRoutingKey(Configuration.getInstance().getMethodReplyQueueName());
+ _messageProperties = new MessageProperties();
+ _messageProperties.setReplyTo(replyTo);
+
+ String routingKey = String.format(Names.AGENT_ROUTING_KEY_PREFIX+"%s.%s", brokerId,bankId);
+
+ LOGGER.debug(Messages.QMAN_200032_COMMAND_MESSAGE_ROUTING_KEY, routingKey);
+
+ _deliveryProperties = new DeliveryProperties();
+ _deliveryProperties.setRoutingKey(routingKey);
+ _header = new Header(_deliveryProperties, _messageProperties);
+ }
+
+ @Override
+ char opcode ()
+ {
+ return Protocol.OPERATION_INVOCATION_REQUEST_OPCODE;
+ }
+
+ /**
+ * Returns the package name.
+ *
+ * @return the package name.
+ */
+ protected abstract String packageName();
+
+ /**
+ * Returns the class name.
+ *
+ * @return the class name.
+ */
+ protected abstract String className();
+
+ /**
+ * Returns the schema hash.
+ *
+ * @return the schema hash.
+ */
+ protected abstract Binary schemaHash();
+
+ /**
+ * Returns the object identifier.
+ *
+ * @return the object identifier.
+ */
+ protected abstract Binary objectId();
+
+ /**
+ * Returns the method to be invoked.
+ *
+ * @return the method to be invoked.
+ */
+ protected abstract QpidMethod method();
+
+ /**
+ * Returns the parameters used for method invocation.
+ *
+ * @return the parameters used for method invocation.
+ */
+ protected abstract Object[] parameters();
+
+ /**
+ * Returns the delivery properties of this message.
+ *
+ * @return the delivery properties of this message.
+ */
+ public DeliveryProperties getDeliveryProperties ()
+ {
+ return _deliveryProperties;
+ }
+
+ /**
+ * Returns the header of this message.
+ *
+ * @return the header of this message.
+ */
+ public Header getHeader ()
+ {
+ return _header;
+ }
+
+ /**
+ * Returns the messages header properties of this message.
+ *
+ * @return the message header properties of this message.
+ */
+ public MessageProperties getMessageProperties ()
+ {
+ return _messageProperties;
+ }
+
+ @Override
+ void specificMessageEncoding ()
+ {
+ objectId().encode(_codec);
+ _codec.writeStr8(packageName());
+ _codec.writeStr8(className());
+ schemaHash().encode(_codec);
+
+ QpidMethod method = method();
+ _codec.writeStr8(method.getName());
+ method.encodeParameters(parameters(), _codec);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/SchemaRequestMessage.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/SchemaRequestMessage.java
new file mode 100644
index 0000000000..9df1733649
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/SchemaRequestMessage.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.management.messages;
+
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Abstract representation of a schema request message.
+ * Concrete subclasses must supply the values needed to build & encode the message.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class SchemaRequestMessage extends ManagementMessage
+{
+ @Override
+ char opcode ()
+ {
+ return Protocol.SCHEMA_REQUEST_OPCODE;
+ }
+
+ /**
+ * Returns the package name.
+ *
+ * @return the package name.
+ */
+ protected abstract String packageName();
+
+ /**
+ * Returns the class name.
+ *
+ * @return the class name.
+ */
+ protected abstract String className();
+
+ /**
+ * Returns the schema hash.
+ *
+ * @return the schema hash.
+ */
+ protected abstract Binary schemaHash();
+
+ @Override
+ final void specificMessageEncoding ()
+ {
+ _codec.writeStr8(packageName());
+ _codec.writeStr8(className());
+ schemaHash().encode(_codec);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/ConnectQManToBroker.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/ConnectQManToBroker.java
new file mode 100644
index 0000000000..8f73098e20
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/ConnectQManToBroker.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.management.servlet;
+
+import java.util.UUID;
+import java.util.Map.Entry;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.muse.core.platform.mini.MiniServlet;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.configuration.BrokerConnectionData;
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.domain.services.QMan;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * When QMan is started and a configuration file is given
+ * (via system property) with initial broker connection data(s),
+ * this servlet simply sends connect command(s) to QMan in order
+ * to estabilish the connection(s) to the requested broker(s).
+ *
+ * @author Andrea Gazzarini
+ */
+public class ConnectQManToBroker extends MiniServlet
+{
+ private static final long serialVersionUID = 6149614872902682208L;
+ private final static Logger LOGGER = Logger.get(ConnectQManToBroker.class);
+
+ /**
+ * Send one or more initial "connect" command(s) to QMan in order
+ * to estabilish a connection with broker found on the configuration file..
+ * Note that this is done only if that configuration file is given (via system
+ * property) and it is valid.
+ */
+ public void init()
+ {
+ Configuration configuration = Configuration.getInstance();
+ if (configuration.hasOneOrMoreBrokersDefined())
+ {
+ QMan qman = (QMan)getServletContext().getAttribute(Names.APPLICATION_NAME);
+
+ LOGGER.info(Messages.QMAN_000003_CREATING_MANAGEMENT_CLIENTS);
+ for (Entry<UUID, BrokerConnectionData> entry : Configuration.getInstance().getConnectionInfos())
+ {
+ qman.createManagementClient(entry.getKey(), entry.getValue());
+ }
+ } else
+ {
+ LOGGER.info(Messages.QMAN_000022_NO_BROKER_CONFIGURED);
+ }
+ }
+
+ /**
+ * This is a startup module only so an override of the default servlet
+ * behaviour must be done in order to prevent incoming http
+ * requests processing.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException each time this method is called.
+ */
+ @Override
+ public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException
+ {
+ throw new ServletException();
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManLifeCycleManager.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManLifeCycleManager.java
new file mode 100644
index 0000000000..edd6804e68
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManLifeCycleManager.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.management.servlet;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.services.QMan;
+import org.apache.qpid.management.domain.services.StartupFailureException;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * QMan JMX lifecycle manager.
+ * Provides lifecycle management of QMan JMX core including startup and shutdown.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QManLifeCycleManager implements ServletContextListener
+{
+ private final static Logger LOGGER = Logger.get(QManLifeCycleManager.class);
+
+ /**
+ * Starts QMan JMX Core.
+ *
+ * @param event the application context event.
+ */
+ public void contextInitialized(ServletContextEvent event)
+ {
+ try
+ {
+ QMan qman = new QMan();
+ qman.start();
+ event.getServletContext().setAttribute(
+ Names.APPLICATION_NAME,
+ qman);
+ } catch (StartupFailureException exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100030_JMX_CORE_STARTUP_FAILURE);
+ }
+ }
+
+ /**
+ * Sutdown QMan JMX Core.
+ *
+ * @param event the application context event.
+ */
+ public void contextDestroyed(ServletContextEvent event)
+ {
+ ServletContext context = event.getServletContext();
+
+ QMan qman = (QMan) context.getAttribute(Names.APPLICATION_NAME);
+ qman.stop();
+
+ context.removeAttribute(Names.APPLICATION_NAME);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/WSDMAdapter.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/WSDMAdapter.java
new file mode 100644
index 0000000000..c6fcde08c4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/WSDMAdapter.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.management.servlet;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.wsdm.muse.engine.WSDMAdapterIsolationLayer;
+import org.apache.qpid.qman.debug.XmlDebugger;
+import org.apache.qpid.transport.util.Logger;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * QMan Adapter facade.
+ * This is the main requestor entry point of the WS-DM connector / adapter.
+ * All WSDM requests will be handled (at higher level) by this servlet.
+ *
+ * @author Andrea Gazzarini
+ */
+public class WSDMAdapter extends HttpServlet
+{
+ private static final long serialVersionUID = 6149614872902682208L;
+ private final static Logger LOGGER = Logger.get(WSDMAdapter.class);
+ private WSDMAdapterIsolationLayer _isolationLayer;
+
+ @Override
+ public void init() throws ServletException {
+ LOGGER.debug(Messages.QMAN_000026_WSDM_ADAPTER_STARTS);
+
+ _isolationLayer = new WSDMAdapterIsolationLayer(getServletContext());
+ _isolationLayer.initialize();
+
+ LOGGER.debug(Messages.QMAN_000027_WSDM_ADAPTER_STARTED);
+
+ }
+
+ /**
+ * Accepts http requests containing a soap envelope (request) and therefore
+ * acts as the main entry point of whole WS process.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException in case of application failure.
+ * @throws IOException in case of generic I/O failure.
+ */
+ @Override
+ protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException
+ {
+ PrintWriter writer = response.getWriter();
+
+ Document soapEnvelopeRequest = null;
+ String soapEnvelopeResposeAsString = null;
+
+ try
+ {
+ soapEnvelopeRequest = XmlUtils.createDocument(request.getInputStream());
+
+ Document soapEnvelopeResponse = _isolationLayer.handleRequest(soapEnvelopeRequest);
+ soapEnvelopeResposeAsString = XmlUtils.toString(soapEnvelopeResponse,false,true);
+
+ response.setContentType("text/xml");
+
+ writer.write(soapEnvelopeResposeAsString);
+ } catch (SAXException exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100019_REQ_OR_RES_MALFORMED);
+ throw new ServletException(exception);
+ } finally {
+ writer.flush();
+
+ XmlDebugger.debug(soapEnvelopeRequest);
+ try {
+ XmlDebugger.debug(soapEnvelopeResposeAsString);
+ } catch(Exception exception) {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100019_REQ_OR_RES_MALFORMED);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.java
new file mode 100644
index 0000000000..09b7309b96
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.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.management.web.action;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.Names;
+
+/**
+ * Value Object encapsulating a broker management domain model.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BrokerModel
+{
+ private Map<String, List<ObjectName>> _objectsByType = new HashMap<String, List<ObjectName>>();
+ private String _id;
+
+ /**
+ * Adds a new object to this domain model.
+ *
+ * @param name the object name of the JMX entity.
+ */
+ void addObject(ObjectName name)
+ {
+ String packageName = name.getKeyProperty(Names.PACKAGE);
+ String className = name.getKeyProperty(Names.CLASS);
+ if (className != null)
+ {
+ String fqn = packageName+"."+className;
+
+ List<ObjectName> objects = _objectsByType.get(fqn);
+ if (objects == null)
+ {
+ objects = new ArrayList<ObjectName>();
+ _objectsByType.put(fqn,objects);
+ }
+ objects.add(name);
+ }
+ }
+
+ /**
+ * Gets the identifier of the owner of this model.
+ *
+ * @return the identifier of the owner of this model.
+ */
+ public String getId()
+ {
+ return _id;
+ }
+
+ /**
+ * Sets the identifier of the owner of this model.
+ *
+ * @param id the identifier of the owner of this model.
+ */
+ public void setId(String id)
+ {
+ this._id = id;
+ }
+
+ public Set<String> getCategoryNames()
+ {
+ return _objectsByType.keySet();
+ }
+
+ public List<ObjectName> getCategory(String name)
+ {
+ return _objectsByType.get(name);
+ }
+
+ public int getCategoryCount()
+ {
+ return _objectsByType.keySet().size();
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java
new file mode 100644
index 0000000000..509c86c08b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java
@@ -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.
+ *
+ */
+package org.apache.qpid.management.web.action;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.configuration.BrokerAlreadyConnectedException;
+import org.apache.qpid.management.configuration.BrokerConnectionData;
+import org.apache.qpid.management.configuration.BrokerConnectionException;
+import org.apache.qpid.management.domain.services.ManagementClient;
+import org.apache.qpid.management.domain.services.QMan;
+
+/**
+ * This controller is responsible to :
+ *
+ * <ul>
+ * <li> prepare data for the page that is showing all connected brokers.</li>.
+ * </li> connect QMan with a broker on demand.
+ * </ul>
+ *
+ * @author Andrea Gazzarini
+ */
+public class BrokersManagementAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+
+ /**
+ * Retrieves all connected brokers (their connection data) and prepare the model that
+ * is then forwarded to the appropriate view page.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException in case of failure while forwarding to the view component.
+ * @throws IOException in case of failure while forwarding to the view component.
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ try
+ {
+ QMan qman = (QMan)getServletContext().getAttribute(Names.APPLICATION_NAME);
+ List<ManagementClient> managementClients = qman.getManagementClients();
+
+ List<BrokerConnectionData> brokers = new ArrayList<BrokerConnectionData>(managementClients.size());
+
+ if (!managementClients.isEmpty())
+ {
+ for (ManagementClient managementClient : managementClients)
+ {
+ brokers.add(managementClient.getBrokerConnectionData());
+ }
+ request.setAttribute("model", brokers);
+ }
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/brokers_management.jsp");
+ dispatcher.forward(request,response);
+ } catch(Exception exception)
+ {
+ request.setAttribute("errorMessage","Unable to detect the exact cause Please look at the reported stack trace below.");
+ request.setAttribute("exception",exception);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/error_page.jsp");
+ dispatcher.forward(request,response);
+ }
+ }
+
+ /**
+ * Connects QMan with a new broker and forwards to
+ * the brokers list view page.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException in case of failure while forwarding to the view component.
+ * @throws IOException in case of failure while forwarding to the view component.
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ try
+ {
+ QMan qman = (QMan)getServletContext().getAttribute(Names.APPLICATION_NAME);
+
+ String host = request.getParameter("host");
+ String portString = request.getParameter("port");
+ String virtualHost = request.getParameter("virtualHost");
+ String username = request.getParameter("username");
+ String password = request.getParameter("password");
+
+ String initialCapacityString = request.getParameter("initialCapacity");
+ String maxCapacityString = request.getParameter("maxCapacity");
+ String maxWaitTimeoutString = request.getParameter("maxWaitTimeout");
+
+ List<String> errors = new LinkedList<String>();
+ int port = 0;
+ int initialPoolCapacity = 0;
+ int maxPoolCapacity = 0;
+ long maxWaitTimeout = 0;
+
+ if(host== null || host.trim().length()==0)
+ {
+ errors.add("Invalid value for \"host\" attribute. Must be not null.");
+ }
+
+ if(virtualHost == null || virtualHost.trim().length()==0)
+ {
+ errors.add("Invalid value for \"virtualHost\" attribute. Must be not null.");
+ }
+
+ try
+ {
+ port = Integer.parseInt(portString);
+ } catch(Exception exception)
+ {
+ errors.add("Invalid value for \"port\" attribute. Must be not null and must be a number.");
+ }
+
+ try
+ {
+ initialPoolCapacity = Integer.parseInt(initialCapacityString);
+ } catch(Exception exception)
+ {
+ errors.add("Invalid value for \"Initial Pool Capacity\" attribute. Must be not null and must be a number.");
+ }
+
+ try
+ {
+ maxPoolCapacity = Integer.parseInt(maxCapacityString);
+ } catch(Exception exception)
+ {
+ errors.add("Invalid value for \"Max Pool Capacity\" attribute. Must be not null and must be a number.");
+ }
+
+ try
+ {
+ maxWaitTimeout = Long.parseLong(maxWaitTimeoutString);
+ } catch(Exception exception)
+ {
+ errors.add("Invalid value for \"Max Wait Timeout\" attribute. Must be not null and must be a number.");
+ }
+
+ request.setAttribute("errors", errors);
+
+ if (errors.isEmpty())
+ {
+ qman.addBroker(
+ host,
+ port,
+ username,
+ password,
+ virtualHost,
+ initialPoolCapacity,
+ maxPoolCapacity,
+ maxWaitTimeout);
+ }
+ doGet(request, response);
+ }catch(BrokerAlreadyConnectedException exception)
+ {
+ request.setAttribute("errorMessage","Supplied data refers to an already connected broker...");
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/brokers_management.jsp");
+ dispatcher.forward(request,response);
+ }
+ catch(BrokerConnectionException exception)
+ {
+ request.setAttribute("errorMessage","Unable to connect with the requested broker...");
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/brokers_management.jsp");
+ dispatcher.forward(request,response);
+ } catch(Exception exception)
+ {
+ request.setAttribute("errorMessage","Unable to detect the exact cause Please look at the reported stack trace below.");
+ request.setAttribute("exception",exception);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/error_page.jsp");
+ dispatcher.forward(request,response);
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleAction.java
new file mode 100644
index 0000000000..ee098882f1
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleAction.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.management.web.action;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.RuntimeMXBean;
+import java.util.Date;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * This action is the controller responsible to prepare data for the home
+ * page (System Overview) of QMan admin console.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ConsoleAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+
+ private static final Logger LOGGER = Logger.get(ConsoleAction.class);
+
+ private Date _startDate;
+
+ /**
+ * Initializes this controller.
+ * Simply it computes the start date of the application.
+ */
+ @Override
+ public void init()
+ {
+ _startDate = new Date();
+ }
+
+ /**
+ * Prepares data for System Overview admin console page and forward that data to that page.
+ *
+ * @throws ServletException when this controller is not able to forward to the appropriate view page.
+ * @throws IOException when this controller is not able to forward to the appropriate view page.
+ */
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ ConsoleModel model = new ConsoleModel();
+ model.setVersion("1.0");
+ model.setVersionName("Sofia");
+ model.setStartDate(_startDate);
+ model.setHost(System.getProperty(Names.ADAPTER_HOST_PROPERTY_NAME, "localhost"));
+ model.setPort(Integer.parseInt(System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME, "8080")));
+
+ try
+ {
+ OperatingSystemMXBean operatingSystem = ManagementFactory.getOperatingSystemMXBean();
+ model.setOsName(operatingSystem.getName());
+ model.setProcessors(operatingSystem.getAvailableProcessors());
+ model.setOsVersion(operatingSystem.getVersion());
+ model.setArchName(operatingSystem.getArch());
+ } catch(Exception exception)
+ {
+ LOGGER.warn(exception,Messages.QMAN_300006_OS_MBEAN_FAILURE);
+ model.setOsName("N.A.");
+ model.setProcessors(null);
+ model.setOsVersion("N.A.");
+ model.setArchName("N.A.");
+ }
+
+ try
+ {
+ RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
+
+ String bootClasspath = runtime.getBootClassPath();
+ model.setBootClasspath(bootClasspath.split(File.pathSeparator));
+
+ String classpath = runtime.getClassPath();
+ model.setClasspath(classpath.split(File.pathSeparator));
+
+ model.setInputArguments(runtime.getInputArguments().toArray(new String[]{}));
+ } catch(Exception exception)
+ {
+ LOGGER.warn(exception,Messages.QMAN_300007_RUNTIME_MBEAN_FAILURE);
+ }
+
+ request.setAttribute("model", model);
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/console.jsp");
+ dispatcher.forward(request,response);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleModel.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleModel.java
new file mode 100644
index 0000000000..ac0e1d2bbd
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleModel.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.management.web.action;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Console Model.
+ * It is a simple Data Transfer Object encapsulating all information about QMan
+ * console (System Overview)
+ *
+ * @author Andrea Gazzarini
+ */
+public class ConsoleModel implements Serializable
+{
+ private static final long serialVersionUID = -7676132151242738376L;
+ private String _version;
+ private String _versionName;
+ private Date _startDate;
+ private String _host;
+ private int _port;
+
+ private String _osName;
+ private String _osVersion;
+ private String _archName;
+ private Integer _processors;
+
+ private String [] _bootClasspath;
+ private String [] _classpath;
+ private String [] _inputArguments;
+ private String [] _systemProperties;
+
+ public String getVersion()
+ {
+ return _version;
+ }
+ public void setVersion(String version)
+ {
+ this._version = version;
+ }
+ public String getVersionName()
+ {
+ return _versionName;
+ }
+ public void setVersionName(String versionName)
+ {
+ this._versionName = versionName;
+ }
+ public Date getStartDate()
+ {
+ return _startDate;
+ }
+ public void setStartDate(Date startDate)
+ {
+ this._startDate = startDate;
+ }
+ public String getHost()
+ {
+ return _host;
+ }
+ public void setHost(String host)
+ {
+ this._host = host;
+ }
+ public int getPort()
+ {
+ return _port;
+ }
+ public void setPort(int port)
+ {
+ this._port = port;
+ }
+ public String getOsName()
+ {
+ return _osName;
+ }
+ public void setOsName(String osName)
+ {
+ this._osName = osName;
+ }
+ public String getOsVersion()
+ {
+ return _osVersion;
+ }
+ public void setOsVersion(String osVersion)
+ {
+ this._osVersion = osVersion;
+ }
+ public String getArchName()
+ {
+ return _archName;
+ }
+ public void setArchName(String archName)
+ {
+ this._archName = archName;
+ }
+ public Integer getProcessors()
+ {
+ return _processors;
+ }
+ public void setProcessors(Integer processors)
+ {
+ this._processors = processors;
+ }
+ public List<String> getBootClasspath()
+ {
+ return Arrays.asList(_bootClasspath);
+ }
+ public void setBootClasspath(String [] bootClasspath)
+ {
+ this._bootClasspath = bootClasspath;
+ }
+ public String [] getClasspath()
+ {
+ return _classpath;
+ }
+ public void setClasspath(String [] classpath)
+ {
+ this._classpath = classpath;
+ }
+ public String [] getInputArguments()
+ {
+ return _inputArguments;
+ }
+ public void setInputArguments(String [] inputArguments)
+ {
+ this._inputArguments = inputArguments;
+ }
+ public String [] getSystemProperties()
+ {
+ return _systemProperties;
+ }
+ public void setSystemProperties(String [] systemProperties)
+ {
+ this._systemProperties = systemProperties;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/JmxPerspectiveAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/JmxPerspectiveAction.java
new file mode 100644
index 0000000000..59777cc9c8
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/JmxPerspectiveAction.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.management.web.action;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Map.Entry;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * This controller is responsible to provide a jmx perspective of a specific resource.
+ * That means that this controller is querying the Platform MBean server in order to
+ * get metadata for the requested mbean.
+ *
+ * After that metadata will be forwarded to the appropriate view page and therefore
+ * will be shown on the Admin console.
+ *
+ * @author Andrea Gazzarini
+ */
+public class JmxPerspectiveAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+
+ /**
+ * Adapter interface for converting objects on html strings.
+ *
+ * @author Andrea Gazzarini.
+ */
+ interface JavaToHtmlAdapter
+ {
+ /**
+ * Returns an HTML string representation of the given object.
+ *
+ * @param javaObject the object that needs to be converted.
+ * @return an html string containing value of the given object.
+ */
+ String toHtml(Object javaObject);
+ }
+
+ /**
+ * Adapter implementation for Map (and subclasses).
+ */
+ private JavaToHtmlAdapter mapAdapter = new JavaToHtmlAdapter()
+ {
+ @SuppressWarnings("unchecked")
+ public String toHtml(Object javaObject)
+ {
+ Map<String,Object> value = (Map<String, Object>) javaObject;
+
+ // Sanity check : if the map is empty or null there's no need to
+ // do any convertion
+ if (value == null || value.isEmpty())
+ {
+ return "(empty)";
+ }
+
+ StringBuilder builder = new StringBuilder("<ul>");
+ for (Entry<String, Object> entry : value.entrySet())
+ {
+ builder
+ .append("<li>")
+ .append(entry.getKey())
+ .append(" = ")
+ .append(entry.getValue());
+ }
+ builder.append("</ul>");
+ return builder.toString();
+ }
+ };
+
+ private Map<String, JavaToHtmlAdapter> _adapters = new HashMap<String, JavaToHtmlAdapter>();
+
+ @Override
+ public void init() throws ServletException
+ {
+ _adapters.put(Map.class.getName(), mapAdapter);
+ _adapters.put(HashMap.class.getName(),mapAdapter);
+ _adapters.put(Properties.class.getName(),mapAdapter);
+ _adapters.put(Hashtable.class.getName(),mapAdapter);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ String resourceId = null;
+ try
+ {
+ resourceId = request.getParameter("resourceId");
+
+ ObjectName objectName = new ObjectName(resourceId);
+ String [] keyProperties = objectName.getKeyPropertyListString().split(",");
+
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+ MBeanInfo metadata = server.getMBeanInfo(objectName);
+
+ Map<String, String> attributes = getAttributes(server, objectName,metadata.getAttributes());
+
+ request.setAttribute("resourceId", objectName);
+ request.setAttribute("metadata",metadata);
+ request.setAttribute("nameAttributes",keyProperties);
+ request.setAttribute("attributes",attributes);
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/jmx_perspective.jsp");
+ dispatcher.forward(request,response);
+ } catch(MalformedObjectNameException exception)
+ {
+ request.setAttribute("errorMessage","Malformed Resource ID : supplied value is "+resourceId);
+ request.setAttribute("exception",exception);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/error_page.jsp");
+ dispatcher.forward(request,response);
+
+ }
+ catch(Exception exception)
+ {
+ request.setAttribute("errorMessage","Unable to detect the exact cause Please look at the reported stack trace below.");
+ request.setAttribute("exception",exception);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/error_page.jsp");
+ dispatcher.forward(request,response);
+ }
+ }
+
+ /**
+ * Starting from an mbean metadata, this method retrieves all the attributes
+ * from the corresponding MBean Server.
+ *
+ * @param server the mbean server where the target mbean is registered.
+ * @param name the name of the target mbean.
+ * @param metadata the metadata of mbean.
+ * @return a map containing all attributes of the given mbean.
+ * @throws Exception when it's not possible to retrieve attributes.
+ */
+ private Map<String, String> getAttributes(MBeanServer server, ObjectName name, MBeanAttributeInfo [] metadata) throws Exception
+ {
+ Map<String,String> result = new HashMap<String, String>(metadata.length);
+ for (MBeanAttributeInfo attribute : metadata)
+ {
+ Object value = server.getAttribute(name, attribute.getName());
+ result.put(attribute.getName(),getAdaptedValue(attribute.getType(), value));
+ }
+ return result;
+ }
+
+ /**
+ * Converts the given attribute value in a html string format.
+ *
+ * @param type the java type of the given attribute value.
+ * @param value the attribute value.
+ * @return a html string format of the given value.
+ */
+ private String getAdaptedValue(String type, Object value)
+ {
+ JavaToHtmlAdapter adapter = _adapters.get(type);
+ return (adapter != null) ? adapter.toHtml(value) : String.valueOf(value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/LoggingConfigurationAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/LoggingConfigurationAction.java
new file mode 100644
index 0000000000..aefd4ca8dd
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/LoggingConfigurationAction.java
@@ -0,0 +1,114 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.web.action;
+
+import java.io.IOException;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.qpid.qman.debug.WsdlDebugger;
+import org.apache.qpid.qman.debug.XmlDebugger;
+
+/**
+ * Logging configuration controller.
+ * Accepts input parameters from admin console and configure the underlying
+ * logging subsystem at runtime.
+ *
+ * @author Andrea Gazzarini
+ */
+public class LoggingConfigurationAction extends HttpServlet
+{
+ private static final long serialVersionUID = 633352305870632824L;
+
+ private final static String WSDL_DEBUG_ENABLED_PARAM = "wsdlDebugEnabled";
+ private final static String SOAP_DEBUG_ENABLED_PARAM = "soapDebugEnabled";
+ private final static String WEB_SERVER_LOG_LEVEL_PARAM = "webServerLogLevel";
+ private final static String QMAN_LOG_LEVEL_PARAM = "qmanLogLevel";
+
+ private final static String WEB_SERVER_PACKAGE = "org.mortbay";
+ private final static String QMAN_PACKAGE = "org.qpid.apache.management";
+
+ /**
+ * Retrieves current logging configuration and forward those data to the logging configuration view page.
+ * In this way that page will be able to display the current logging settings.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException when this controller is not able to forward to the appropriate view page.
+ * @throws IOException when this controller is not able to forward to the appropriate view page.
+ */
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ Level messageDebuggerLogLevel = Logger.getLogger(XmlDebugger.class).getEffectiveLevel();
+ Level wsdlDebuggerLogLevel = Logger.getLogger(WsdlDebugger.class).getEffectiveLevel();
+ Level webServerLogLevel = Logger.getLogger(WEB_SERVER_PACKAGE).getEffectiveLevel();
+ Level qmanLogLevel = Logger.getLogger(QMAN_PACKAGE).getEffectiveLevel();
+
+ request.setAttribute(WSDL_DEBUG_ENABLED_PARAM,wsdlDebuggerLogLevel.equals(Level.DEBUG));
+ request.setAttribute(SOAP_DEBUG_ENABLED_PARAM,messageDebuggerLogLevel.equals(Level.DEBUG));
+ request.setAttribute(WEB_SERVER_LOG_LEVEL_PARAM,webServerLogLevel);
+ request.setAttribute(QMAN_LOG_LEVEL_PARAM,qmanLogLevel);
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/logging_configuration.jsp");
+ dispatcher.forward(request, response);
+ }
+
+ /**
+ * Accepts user data coming from admin console and use it for configure the underlying logging
+ * subsystem.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException when this controller is not able to forward to the appropriate view page.
+ * @throws IOException when this controller is not able to forward to the appropriate view page.
+ */
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ String wsdlDebugEnabled = request.getParameter(WSDL_DEBUG_ENABLED_PARAM);
+ String soapDebugEnabled = request.getParameter(SOAP_DEBUG_ENABLED_PARAM);
+
+ String qmanLevel = request.getParameter(QMAN_LOG_LEVEL_PARAM);
+ String serverLevel = request.getParameter(WEB_SERVER_LOG_LEVEL_PARAM);
+
+ Logger.getLogger(WEB_SERVER_PACKAGE).setLevel(Level.toLevel(serverLevel));
+ Logger.getLogger(QMAN_PACKAGE).setLevel(Level.toLevel(qmanLevel));
+
+ Logger.getLogger(WsdlDebugger.class).setLevel(
+ "on".equals(wsdlDebugEnabled)
+ ? Level.DEBUG
+ : Level.INFO);
+
+ Logger.getLogger(XmlDebugger.class).setLevel(
+ "on".equals(soapDebugEnabled)
+ ? Level.DEBUG
+ : Level.INFO);
+
+ doGet(request, response);
+ }
+}
+ \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ResourcesManagementAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ResourcesManagementAction.java
new file mode 100644
index 0000000000..f1a55be6bf
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ResourcesManagementAction.java
@@ -0,0 +1,91 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.web.action;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.List;
+import java.util.Set;
+
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.services.ManagementClient;
+import org.apache.qpid.management.domain.services.QMan;
+
+/**
+ * This controller retrieves from QMan all the registered resources and organize
+ * that data in a model that is then forwarded to the appropriate view page.
+ *
+ * TODO : In the corresponding view page only one broker is displayed.
+ * A query should be made on QMan mbean in order to retrieve all connected broker and therefore
+ * a model for each of them should be created.
+ * In the corresponding weg page there should be a "tab" for each broker. Each tab should show only
+ * the objects belonging to that broker.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ResourcesManagementAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ try
+ {
+ QMan qman = (QMan)getServletContext().getAttribute(Names.APPLICATION_NAME);
+ List<ManagementClient> managementClient = qman.getManagementClients();
+
+ if (!managementClient.isEmpty())
+ {
+ BrokerModel model = new BrokerModel();
+ model.setId(managementClient.toString());
+
+ MBeanServer mxServer = ManagementFactory.getPlatformMBeanServer();
+ Set<ObjectName> objectNames = mxServer.queryNames(new ObjectName("Q-MAN:*"), null);
+ for (ObjectName objectName : objectNames)
+ {
+ model.addObject(objectName);
+ }
+
+ request.setAttribute("model", model);
+ }
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/resources_management.jsp");
+ dispatcher.forward(request,response);
+ } catch(MalformedObjectNameException exception)
+ {
+ request.setAttribute("errorMessage","Unable to detect the exact cause Please look at the reported stack trace below.");
+ request.setAttribute("exception",exception);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/error_page.jsp");
+ dispatcher.forward(request,response);
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmOperationsPerspectiveAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmOperationsPerspectiveAction.java
new file mode 100644
index 0000000000..ca5b3285b0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmOperationsPerspectiveAction.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.management.web.action;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Map.Entry;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+
+/**
+ * This controller is responsible to retirve operations metadata from a WS-Resource.
+ * That metadat will be forwarded and used by the corresponding view page.
+ *
+ * TODO : This is not really showing WS metadata. Insted JMX metadata is used here.
+ *
+ * @author Andrea Gazzarini
+ *
+ */
+public class WsdmOperationsPerspectiveAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+
+ private ProxyHandler proxyHandler;
+
+ interface JavaToHtmlAdapter
+ {
+ String toHtml(Object javaObject);
+ }
+
+ private URI resourceUri;
+
+ private JavaToHtmlAdapter mapAdapter = new JavaToHtmlAdapter()
+ {
+ @SuppressWarnings("unchecked")
+ public String toHtml(Object javaObject)
+ {
+ Map<String,Object> value = (Map<String, Object>) javaObject;
+
+ if (value == null || value.isEmpty())
+ {
+ return "(empty)";
+ }
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("<ul>");
+ for (Entry<String, Object> entry : value.entrySet())
+ {
+ builder
+ .append("<li>")
+ .append(entry.getKey())
+ .append(" = ")
+ .append(entry.getValue());
+ }
+ builder.append("</ul>");
+ return builder.toString();
+ }
+ };
+
+ private Map<String, JavaToHtmlAdapter> adapters = new HashMap<String, JavaToHtmlAdapter>();
+
+ @Override
+ public void init() throws ServletException
+ {
+ adapters.put(Map.class.getName(), mapAdapter);
+ adapters.put(HashMap.class.getName(),mapAdapter);
+ adapters.put(Properties.class.getName(),mapAdapter);
+ adapters.put(Hashtable.class.getName(),mapAdapter);
+
+ proxyHandler = new ReflectionProxyHandler();
+ proxyHandler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ proxyHandler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", Names.PREFIX));
+ proxyHandler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", Names.PREFIX)});
+ proxyHandler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", Names.PREFIX));
+ proxyHandler.setReturnType(Element[].class);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ try
+ {
+ String resourceId = request.getParameter("resourceId");
+ ObjectName objectName = new ObjectName(resourceId);
+ String wsdmResourceId = objectName.getKeyProperty(Names.OBJECT_ID);
+
+ EndpointReference resourceEndpointReference = new EndpointReference(getURI(request));
+ resourceEndpointReference.addParameter(
+ Names.RESOURCE_ID_QNAME,
+ wsdmResourceId);
+
+// WsResourceClient resourceClient = new WsResourceClient(resourceEndpointReference);
+// Element wsdl = ((Element[])resourceClient.invoke(proxyHandler,WSDL_DIALECT))[0];
+// Element rmd = ((Element[])resourceClient.invoke(proxyHandler,RMD_DIALECT))[0];
+
+ String [] keyProperties = objectName.getKeyPropertyListString().split(",");
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+ MBeanInfo metadata = server.getMBeanInfo(objectName);
+
+ Map<String, String> attributes = getAttributes(server, objectName,metadata.getAttributes());
+
+ request.setAttribute("resourceId", resourceId);
+ request.setAttribute("metadata",metadata);
+ request.setAttribute("nameAttributes",keyProperties);
+ request.setAttribute("attributes",attributes);
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/wsdm_operations_perspective.jsp");
+ dispatcher.forward(request,response);
+ } catch(Exception exception)
+ {
+ request.setAttribute("errorMessage","Unable to detect the exact cause Please look at the reported stack trace below.");
+ request.setAttribute("exception",exception);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/error_page.jsp");
+ dispatcher.forward(request,response);
+ }
+ }
+
+ private URI getURI(HttpServletRequest request)
+ {
+ if (resourceUri == null)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder
+ .append(request.getProtocol())
+ .append("//")
+ .append(request.getServerName())
+ .append(":")
+ .append(request.getServerPort())
+ .append("/qman/services/QManWsResource");
+ resourceUri = URI.create(builder.toString());
+ }
+ return resourceUri;
+ }
+
+ private Map<String, String> getAttributes(MBeanServer server, ObjectName name, MBeanAttributeInfo [] metadata) throws Exception
+ {
+ Map<String,String> result = new HashMap<String, String>(metadata.length);
+ for (MBeanAttributeInfo attribute : metadata)
+ {
+ Object value = server.getAttribute(name, attribute.getName());
+ result.put(attribute.getName(),getAdaptedValue(attribute.getType(), value));
+ }
+ return result;
+ }
+
+ private String getAdaptedValue(String type, Object value)
+ {
+ JavaToHtmlAdapter adapter = adapters.get(type);
+ return (adapter != null) ? adapter.toHtml(value) : String.valueOf(value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java
new file mode 100644
index 0000000000..e3a8eb50d7
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java
@@ -0,0 +1,185 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.web.action;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Map.Entry;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+
+public class WsdmPropertiesPerspectiveAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+
+ private ProxyHandler proxyHandler;
+
+ interface JavaToHtmlAdapter
+ {
+ String toHtml(Object javaObject);
+ }
+
+ private URI resourceUri;
+
+ private JavaToHtmlAdapter mapAdapter = new JavaToHtmlAdapter()
+ {
+ @SuppressWarnings("unchecked")
+ public String toHtml(Object javaObject)
+ {
+ Map<String,Object> value = (Map<String, Object>) javaObject;
+
+ if (value == null || value.isEmpty())
+ {
+ return "(empty)";
+ }
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("<ul>");
+ for (Entry<String, Object> entry : value.entrySet())
+ {
+ builder
+ .append("<li>")
+ .append(entry.getKey())
+ .append(" = ")
+ .append(entry.getValue());
+ }
+ builder.append("</ul>");
+ return builder.toString();
+ }
+ };
+
+ private Map<String, JavaToHtmlAdapter> adapters = new HashMap<String, JavaToHtmlAdapter>();
+
+ @Override
+ public void init() throws ServletException
+ {
+ adapters.put(Map.class.getName(), mapAdapter);
+ adapters.put(HashMap.class.getName(),mapAdapter);
+ adapters.put(Properties.class.getName(),mapAdapter);
+ adapters.put(Hashtable.class.getName(),mapAdapter);
+
+ proxyHandler = new ReflectionProxyHandler();
+ proxyHandler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ proxyHandler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", Names.PREFIX));
+ proxyHandler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", Names.PREFIX)});
+ proxyHandler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", Names.PREFIX));
+ proxyHandler.setReturnType(Element[].class);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ try
+ {
+ String resourceId = request.getParameter("resourceId");
+ ObjectName objectName = new ObjectName(resourceId);
+
+ String wsresourceid = objectName.getKeyProperty(Names.OBJECT_ID);
+
+ EndpointReference resourceEndpointReference = new EndpointReference(getURI(request));
+ resourceEndpointReference.addParameter(
+ Names.RESOURCE_ID_QNAME,
+ wsresourceid);
+
+// WsResourceClient resourceClient = new WsResourceClient(resourceEndpointReference);
+// Element wsdl = ((Element[])resourceClient.invoke(proxyHandler,WSDL_DIALECT))[0];
+// Element rmd = ((Element[])resourceClient.invoke(proxyHandler,RMD_DIALECT))[0];
+
+ String [] keyProperties = objectName.getKeyPropertyListString().split(",");
+
+
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+ MBeanInfo metadata = server.getMBeanInfo(objectName);
+
+ Map<String, String> attributes = getAttributes(server, objectName,metadata.getAttributes());
+
+ request.setAttribute("resourceId", resourceId);
+ request.setAttribute("metadata",metadata);
+ request.setAttribute("nameAttributes",keyProperties);
+ request.setAttribute("attributes",attributes);
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/wsdm_properties_perspective.jsp");
+ dispatcher.forward(request,response);
+ } catch(Exception exception)
+ {
+ request.setAttribute("errorMessage","Unable to detect the exact cause Please look at the reported stack trace below.");
+ request.setAttribute("exception",exception);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/error_page.jsp");
+ dispatcher.forward(request,response);
+ }
+ }
+
+ private URI getURI(HttpServletRequest request)
+ {
+ if (resourceUri == null)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder
+ .append(request.getProtocol())
+ .append("//")
+ .append(request.getServerName())
+ .append(":")
+ .append(request.getServerPort())
+ .append("/qman/services/QManWsResource");
+ resourceUri = URI.create(builder.toString());
+ }
+ return resourceUri;
+ }
+
+ private Map<String, String> getAttributes(MBeanServer server, ObjectName name, MBeanAttributeInfo [] metadata) throws Exception
+ {
+ Map<String,String> result = new HashMap<String, String>(metadata.length);
+ for (MBeanAttributeInfo attribute : metadata)
+ {
+ Object value = server.getAttribute(name, attribute.getName());
+ result.put(attribute.getName(),getAdaptedValue(attribute.getType(), value));
+ }
+ return result;
+ }
+
+ private String getAdaptedValue(String type, Object value)
+ {
+ JavaToHtmlAdapter adapter = adapters.get(type);
+ return (adapter != null) ? adapter.toHtml(value) : String.valueOf(value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java
new file mode 100644
index 0000000000..b4c488e97c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java
@@ -0,0 +1,139 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.web.action;
+
+import java.io.IOException;
+import java.net.URI;
+
+import javax.management.ObjectName;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.metadata.WsxConstants;
+import org.apache.muse.ws.resource.metadata.WsrmdConstants;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+
+public class WsdmRmdPerspectiveAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+ private static final Object [] RMD_DIALECT = new Object[]{WsrmdConstants.NAMESPACE_URI};
+
+ private ProxyHandler proxyHandler;
+
+ private URI resourceUri;
+
+ @Override
+ public void init() throws ServletException
+ {
+ proxyHandler = new ReflectionProxyHandler();
+ proxyHandler.setAction(WsxConstants.GET_METADATA_URI);
+ proxyHandler.setRequestName(WsxConstants.GET_METADATA_QNAME);
+ proxyHandler.setRequestParameterNames(new QName[]{
+ new QName(
+ WsxConstants.NAMESPACE_URI,
+ WsxConstants.DIALECT,
+ WsxConstants.PREFIX)});
+ proxyHandler.setResponseName(WsxConstants.METADATA_QNAME);
+ proxyHandler.setReturnType(Element[].class);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ try
+ {
+ String resourceId = request.getParameter("resourceId");
+ ObjectName objectName = new ObjectName(resourceId);
+
+ String wsresourceid = objectName.getKeyProperty(Names.OBJECT_ID);
+ EndpointReference resourceEndpointReference = new EndpointReference(getURI(request));
+
+ resourceEndpointReference.addParameter(
+ Names.RESOURCE_ID_QNAME,
+ wsresourceid);
+
+ WsResourceClient resourceClient = new WsResourceClient(resourceEndpointReference);
+ Element rmd = ((Element[])resourceClient.invoke(proxyHandler,RMD_DIALECT))[0];
+
+// NodeList nodelist = wsdl.getChildNodes();
+// Element definitions = null;
+// for (int i = 0; i < nodelist.getLength(); i++)
+// {
+// Node node = nodelist.item(i);
+// switch (node.getNodeType())
+// {
+// case Node.ELEMENT_NODE:
+// {
+// Element element = (Element) node;
+// if (element.getNodeName().indexOf("definitions") != -1)
+// {
+// definitions = element;
+// break;
+// }
+// }
+// }
+// }
+
+ String output = XmlUtils.toString(rmd);
+
+ String [] keyProperties = objectName.getKeyPropertyListString().split(",");
+
+ request.setAttribute("resourceId", resourceId);
+ request.setAttribute("nameAttributes",keyProperties);
+ request.setAttribute("rmd",output);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/wsdm_rmd_perspective.jsp");
+ dispatcher.forward(request,response);
+ } catch(Exception exception)
+ {
+ request.setAttribute("errorMessage","Unable to detect the exact cause Please look at the reported stack trace below.");
+ request.setAttribute("exception",exception);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/error_page.jsp");
+ dispatcher.forward(request,response);
+ }
+ }
+
+ private URI getURI(HttpServletRequest request)
+ {
+ if (resourceUri == null)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder
+ .append("http://")
+ .append(request.getServerName())
+ .append(":")
+ .append(request.getServerPort())
+ .append("/qman/services/QManWsResource");
+ resourceUri = URI.create(builder.toString());
+ }
+ return resourceUri;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.java
new file mode 100644
index 0000000000..77a5237037
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.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.management.web.action;
+
+import java.io.IOException;
+import java.net.URI;
+
+import javax.management.ObjectName;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.metadata.WsxConstants;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class WsdmWsdlPerspectiveAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+ private static final Object [] WSDL_DIALECT = new Object[]{WsxConstants.WSDL_DIALECT};
+
+ private ProxyHandler proxyHandler;
+
+ private URI resourceUri;
+
+ @Override
+ public void init() throws ServletException
+ {
+ proxyHandler = new ReflectionProxyHandler();
+ proxyHandler.setAction(WsxConstants.GET_METADATA_URI);
+ proxyHandler.setRequestName(WsxConstants.GET_METADATA_QNAME);
+ proxyHandler.setRequestParameterNames(new QName[]{
+ new QName(
+ WsxConstants.NAMESPACE_URI,
+ WsxConstants.DIALECT,
+ WsxConstants.PREFIX)});
+ proxyHandler.setResponseName(WsxConstants.METADATA_QNAME);
+ proxyHandler.setReturnType(Element[].class);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ try
+ {
+ String resourceId = request.getParameter("resourceId");
+ ObjectName objectName = new ObjectName(resourceId);
+
+ String wsresourceid = objectName.getKeyProperty(Names.OBJECT_ID);
+ EndpointReference resourceEndpointReference = new EndpointReference(getURI(request));
+
+ resourceEndpointReference.addParameter(
+ Names.RESOURCE_ID_QNAME,
+ wsresourceid);
+
+ WsResourceClient resourceClient = new WsResourceClient(resourceEndpointReference);
+ Element wsdl = ((Element[])resourceClient.invoke(proxyHandler,WSDL_DIALECT))[0];
+
+ NodeList nodelist = wsdl.getChildNodes();
+ Element definitions = null;
+ for (int i = 0; i < nodelist.getLength(); i++)
+ {
+ Node node = nodelist.item(i);
+ switch (node.getNodeType())
+ {
+ case Node.ELEMENT_NODE:
+ {
+ Element element = (Element) node;
+ if (element.getNodeName().indexOf("definitions") != -1)
+ {
+ definitions = element;
+ break;
+ }
+ }
+ }
+ }
+
+ String output = XmlUtils.toString(definitions);
+
+ String [] keyProperties = objectName.getKeyPropertyListString().split(",");
+
+ request.setAttribute("resourceId", resourceId);
+ request.setAttribute("nameAttributes",keyProperties);
+ request.setAttribute("wsdl",output);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/wsdm_wsdl_perspective.jsp");
+ dispatcher.forward(request,response);
+ } catch(Exception exception)
+ {
+ request.setAttribute("errorMessage","Unable to detect the exact cause Please look at the reported stack trace below.");
+ request.setAttribute("exception",exception);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/error_page.jsp");
+ dispatcher.forward(request,response);
+ }
+ }
+
+ private URI getURI(HttpServletRequest request)
+ {
+ if (resourceUri == null)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder
+ .append("http://")
+ .append(request.getServerName())
+ .append(":")
+ .append(request.getServerPort())
+ .append("/qman/services/QManWsResource");
+ resourceUri = URI.create(builder.toString());
+ }
+ return resourceUri;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmu.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmu.java
new file mode 100644
index 0000000000..79a387e80c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmu.java
@@ -0,0 +1,130 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm;
+
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObject;
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObjectMBean;
+import org.apache.qpid.management.jmx.EntityLifecycleNotification;
+
+/**
+ * QEmu is basically an instance creator that is installed separately
+ * as part of QMan test cases & examples.
+ * Reason for that is to emulate object creation (queues, exchanges, etc...)
+ * without having Qpid broker connected and therefore controlling the
+ * total number of the instances that are created.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QEmu extends NotificationBroadcasterSupport implements QEmuMBean, MBeanRegistration{
+
+ private MBeanServer _mxServer;
+ private final static String PACKAGE_NAME= "org.apache.qpid";
+ private final static String QUEUE = "queue";
+
+ /**
+ * Unregisters a Queue MBean with MBeanServer.
+ *
+ * @param objectName the name of the MBean that must unregistered.
+ * @throws Exception when the creation or the registration fails.
+ */
+ public void unregister(ObjectName objectName) throws Exception
+ {
+ _mxServer.unregisterMBean(objectName);
+
+ sendNotification(
+ EntityLifecycleNotification.INSTANCE_REMOVED_NOTIFICATION_TYPE,
+ objectName);
+ }
+
+ /**
+ * Creates and registers a Queue MBean with MBeanServer.
+ *
+ * @param objectName the name of the queue MBean.
+ * @throws Exception when the creation or the registration fails.
+ */
+ public void createQueue(ObjectName objectName) throws Exception
+ {
+ QpidDomainObjectMBean queue = new QpidDomainObject();
+ _mxServer.registerMBean(queue, objectName);
+
+ sendNotification(
+ EntityLifecycleNotification.INSTANCE_ADDED_NOTIFICATION_TYPE,
+ objectName);
+ }
+
+ /**
+ * Sends a notification about a lifecycle event of the mbean associated
+ * with the given object.
+ *
+ * @param type the event (notification) type.
+ * @param name the name of the event source.
+ */
+ private void sendNotification(String type,ObjectName name)
+ {
+ sendNotification(
+ new EntityLifecycleNotification(
+ type,
+ PACKAGE_NAME,
+ QUEUE,
+ Names.CLASS,
+ name));
+ }
+
+ /**
+ * Not implemented for this class.
+ */
+ public void postDeregister()
+ {
+ // N.A.
+ }
+
+ /**
+ * Not implemented for this class.
+ */
+ public void postRegister(Boolean registrationDone)
+ {
+ // N.A.
+ }
+
+ /**
+ * Not implemented for this class.
+ */
+ public void preDeregister()
+ {
+ // N.A.
+ }
+
+ /**
+ * MBean server callback.
+ * Stores the value of the owner MBeanServer.
+ */
+ public ObjectName preRegister(MBeanServer server, ObjectName name)
+ {
+ this._mxServer = server;
+ return name;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java
new file mode 100644
index 0000000000..47aa4ea681
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.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.management.wsdm;
+
+import java.lang.management.ManagementFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * QPid Emulator Initializer.
+ * This component is basically responsible to create and initialize
+ * an emulator module used for simulate object instances creation.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QEmuInitializer extends HttpServlet
+{
+ private static final long serialVersionUID = 6149614872902682208L;
+ private final static Logger LOGGER = Logger.get(QEmuInitializer.class);
+
+ /**
+ * QEmu initialization method.
+ *
+ * @throws ServletException when the module cannot be initialized.
+ */
+ public void init() throws ServletException
+ {
+ try
+ {
+ ManagementFactory.getPlatformMBeanServer().registerMBean(
+ new QEmu(),
+ Names.QPID_EMULATOR_OBJECT_NAME);
+ } catch(Exception exception)
+ {
+ LOGGER.warn(
+ exception,
+ Messages.QMAN_300005_QEMU_INITIALIZATION_FAILURE);
+ throw new ServletException(exception);
+ }
+ }
+
+ /**
+ * This is a startup module only so an override of the
+ * default servlet behaviour must be done in order to
+ * prevent incoming http requests processing.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException each time this method is called.
+ */
+ @Override
+ public void service(HttpServletRequest request,HttpServletResponse response) throws ServletException
+ {
+ throw new ServletException();
+ }
+
+ /**
+ * Unregister QPid emulator.
+ */
+ public void destroy()
+ {
+ try
+ {
+ ManagementFactory.getPlatformMBeanServer().unregisterMBean(
+ Names.QPID_EMULATOR_OBJECT_NAME);
+ } catch (Exception exception)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuMBean.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuMBean.java
new file mode 100644
index 0000000000..f22e7ff12d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuMBean.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.management.wsdm;
+
+import javax.management.ObjectName;
+
+/**
+ * Management interface for QEmu.
+ *
+ * @author Andrea Gazzarini
+ * @see QEmu
+ */
+public interface QEmuMBean
+{
+ /**
+ * Creates and registers a Queue MBean with MBeanServer.
+ *
+ * @param objectName the name of the queue MBean.
+ * @throws Exception when the creation or the registration fails.
+ */
+ void createQueue(ObjectName name) throws Exception;
+
+ /**
+ * Unregisters a Queue MBean with MBeanServer.
+ *
+ * @param objectName the name of the MBean that must unregistered.
+ * @throws Exception when the creation or the registration fails.
+ */
+ void unregister(ObjectName name) throws Exception;
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ArtifactsNotAvailableException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ArtifactsNotAvailableException.java
new file mode 100644
index 0000000000..eef70b5544
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ArtifactsNotAvailableException.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.management.wsdm.capabilities;
+
+import javax.management.ObjectName;
+
+/**
+ * Thrown when the artifacts related to a specific resource cannot be built.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ArtifactsNotAvailableException extends Exception
+{
+ private static final long serialVersionUID = -9010460152421791926L;
+
+ private final WsArtifacts _artifacts;
+ private final ObjectName _objectName;
+
+ /**
+ * Builds a new exception with the given arguments.
+ *
+ * @param artifacts the artifacts built.
+ * @param cause the exception cause.
+ * @param objectName the object name of the corresponding JMX entity.
+ */
+ public ArtifactsNotAvailableException(
+ WsArtifacts artifacts,
+ Throwable cause,
+ ObjectName objectName)
+ {
+ super(cause);
+ this._artifacts = artifacts;
+ this._objectName = objectName;
+ }
+
+ /**
+ * Returns a message that indicates which artifacts were built.
+ *
+ * @return a message that indicates which artifacts were built.
+ */
+ @Override
+ public String getMessage()
+ {
+ StringBuilder builder = new StringBuilder();
+ if (_artifacts == null)
+ {
+ return super.getMessage();
+ }
+
+ builder.append("Built artifacts for ")
+ .append(_objectName)
+ .append(" : ")
+ .append( (_artifacts.getWsdl() != null) ? "WSDL," : "")
+ .append( (_artifacts.getCapabilityClass() != null) ? "Capability Class," : "")
+ .append( (_artifacts.getResourceMetadataDescriptor() != null) ? "Resource Metadata Descriptor," : "");
+ return builder.toString();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/BuilderException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/BuilderException.java
new file mode 100644
index 0000000000..f3c8077d46
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/BuilderException.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.management.wsdm.capabilities;
+
+/**
+ * Thrown when a WSRF artifact (either WSDL or capability) cannot be built.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BuilderException extends Exception
+{
+ private static final long serialVersionUID = -8267818907567906262L;
+
+ /**
+ * Builds a new exception with the given cause.
+ *
+ * @param cause the exception cause.
+ */
+ public BuilderException(Exception cause)
+ {
+ super(cause);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Constants.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Constants.java
new file mode 100644
index 0000000000..59a5801505
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Constants.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.management.wsdm.capabilities;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+public interface Constants
+{
+ String WSRP_PROPERTIES_XPATH = "/wsdl:definitions/wsdl:types/xsd:schema[" +
+ "@targetNamespace='http://amqp.apache.org/qpid/management/qman']" +
+ "/xsd:element[@name='QManWsResourceProperties']/xsd:complexType/xsd:sequence";
+
+ String SERVICE_LOCATION_XPATH = "/wsdl:definitions/wsdl:service/wsdl:port/wsdl-soap:address/@location";
+ String QMAN_SCHEMA_XPATH = "/wsdl:definitions/wsdl:types/xsd:schema[@targetNamespace='http://amqp.apache.org/qpid/management/qman']";
+
+ String MIN_OCCURS = "minOccurs";
+ String REF_ATTRIBUTE = "ref";
+ String NAME_ATTRIBUTE = "name";
+ String TYPE_ATTRIBUTE ="type";
+
+ QName XSD_ELEMENT_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"element","xsd");
+ QName XSD_COMPLEX_TYPE_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"complexType","xsd");
+ QName XSD_SEQUENCE_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"sequence","xsd");
+
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.java
new file mode 100644
index 0000000000..bde98092a0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.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.management.wsdm.capabilities;
+
+import org.apache.muse.core.AbstractCapability;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.notification.NotificationConsumer;
+import org.apache.muse.ws.notification.NotificationMessage;
+import org.apache.muse.ws.notification.NotificationMessageListener;
+import org.apache.muse.ws.notification.WsnConstants;
+
+/**
+ * WS-Notifications consumer capability.
+ * At the moment QMan is not a consumer of itself so this capability is here only
+ * for test purposes.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ConsumerCapability extends AbstractCapability implements NotificationMessageListener
+{
+ /**
+ * Initializes this capability and register itself as message listener.
+ *
+ * @throws SoapFault when the initialization fails.
+ */
+ public void initializeCompleted() throws SoapFault
+ {
+ super.initializeCompleted();
+
+ NotificationConsumer wsn = (NotificationConsumer)getResource().getCapability(WsnConstants.CONSUMER_URI);
+ wsn.addMessageListener(this);
+ }
+
+ /**
+ * Returns true if this consumer can accepts the message.
+ *
+ * @return true;
+ */
+ public boolean accepts(NotificationMessage message)
+ {
+ return true;
+ }
+
+ /**
+ * On Message callback.
+ */
+ public void process(NotificationMessage message)
+ {
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java
new file mode 100644
index 0000000000..370cf3086d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.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.management.wsdm.capabilities;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.ObjectName;
+
+import org.apache.muse.core.Environment;
+
+/**
+ * Dummy capability builder used for avoid duplicated builds for the
+ * same class.
+ * Basically it acts likes a Null Object when the target capability class has been
+ * already built.
+ *
+ * @author Andrea Gazzarini
+ */
+public class DummyCapabilityBuilder implements IArtifactBuilder
+{
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void begin(ObjectName objectName)
+ {
+ }
+
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void endAttributes()
+ {
+ }
+
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void endOperations()
+ {
+ }
+
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void onAttribute(MBeanAttributeInfo attributeMetadata)
+ {
+ }
+
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void onOperation(MBeanOperationInfo operationMetadata)
+ {
+ }
+
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void setEnvironment(Environment environment)
+ {
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/IArtifactBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/IArtifactBuilder.java
new file mode 100644
index 0000000000..70b9b0e009
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/IArtifactBuilder.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm.capabilities;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.ObjectName;
+
+import org.apache.muse.core.Environment;
+
+/**
+ * Defines behaviour needed by WS-DM artifact builders.
+ * Each concrete implementor must provide its own parser
+ * implementation of the given JMX data.
+ *
+ * @author Andrea Gazzarini
+ */
+public interface IArtifactBuilder
+{
+ /**
+ * The build process begin and the given parameter is the
+ * object name of the corresponding JMX entity.
+ *
+ * @throws BuilderException when the initialization fails.
+ */
+ void begin(ObjectName objectName) throws BuilderException;
+
+ /**
+ * Processes an attribute (its metadata) of the current MBean.
+ *
+ * @param attributeMetadata the attribute metadata.
+ * @throws BuilderException when the builder cannot parse the given metadata.
+ */
+ void onAttribute(MBeanAttributeInfo attributeMetadata) throws BuilderException;
+
+ /**
+ * Processes an operation (its metadata) of the current MBean.
+ *
+ * @param operationMetadata the operation metadata.
+ * @throws BuilderException when the builder cannot parse the given metadata.
+ */
+ void onOperation(MBeanOperationInfo operationMetadata) throws BuilderException;
+
+ /**
+ * Ends of the attributes section.
+ *
+ * @throws BuilderException when the builder encounter a problem during this phase..
+ */
+ void endAttributes() throws BuilderException;
+
+ /**
+ * Ends of the operations section.
+ *
+ * @throws BuilderException when the builder encounter a problem during this phase..
+ */
+ void endOperations() throws BuilderException;
+
+ /**
+ * Injects the adapter enviroment on this builder.
+ *
+ * @param environment the adapter environment.
+ */
+ void setEnvironment(Environment environment);
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java
new file mode 100644
index 0000000000..37ecc0c031
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.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.management.wsdm.capabilities;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.Attribute;
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.muse.ws.resource.impl.AbstractWsResourceCapability;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.domain.handler.impl.InvocationResult;
+import org.apache.qpid.management.domain.services.MethodInvocationException;
+import org.apache.qpid.management.wsdm.common.EntityInstanceNotFoundFault;
+import org.apache.qpid.management.wsdm.common.MethodInvocationFault;
+import org.apache.qpid.management.wsdm.common.NoSuchAttributeFault;
+import org.apache.qpid.management.wsdm.common.QManFault;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Abstract capability used for centralize common
+ * behaviour of the QMan resource(s) related capabilities.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class MBeanCapability extends AbstractWsResourceCapability
+{
+ private static final Logger LOGGER = Logger.get(MBeanCapability.class);
+
+ protected final MBeanServer _mxServer;
+ protected ObjectName _objectName;
+
+ /**
+ * Builds a new capability related to the given object name.
+ *
+ * @param objectName the name of the target object of this capability.
+ */
+ public MBeanCapability()
+ {
+ _mxServer = ManagementFactory.getPlatformMBeanServer();
+ }
+
+ /**
+ * Injects on this capability the object name of the target mbean.
+ *
+ * @param objectName the object name of the target mbean.
+ */
+ void setResourceObjectName(ObjectName objectName)
+ {
+ this._objectName = objectName;
+ }
+
+ /**
+ * Returns the attribute value of a QMan managed object instance.
+ *
+ * @param attributeName the name of the attribute to be requested.
+ * @return the value for the requested attribute.
+ * @throws NoSuchAttributeFault when the requested attribute cannot be found
+ * on the given entity instance.
+ * @throws EntityInstanceNotFoundFault when the requested entity instance cannot
+ * be found.
+ * @throws QManFault in case of internal system failure.
+ */
+ Object getAttribute(String attributeName) throws NoSuchAttributeFault, EntityInstanceNotFoundFault, QManFault
+ {
+ try
+ {
+ return _mxServer.getAttribute(_objectName, attributeName);
+ } catch (AttributeNotFoundException exception)
+ {
+ throw new NoSuchAttributeFault(
+ getWsResource().getEndpointReference(),
+ attributeName);
+ } catch (InstanceNotFoundException exception)
+ {
+ throw new EntityInstanceNotFoundFault(
+ getWsResource().getEndpointReference(),
+ _objectName);
+ } catch (Exception exception)
+ {
+ LOGGER.error(
+ Messages.QMAN_100035_GET_ATTRIBUTE_FAILURE,
+ attributeName,
+ _objectName);
+ throw new QManFault(
+ getWsResource().getEndpointReference(),
+ exception);
+ }
+ }
+
+ /**
+ * Sets the value for the given attribute on this MBean (proxy).
+ *
+ * @param objectName
+ * the object name of the target instance (excluding the domain
+ * name).
+ * @param attributeName
+ * the name of the attribute to be requested.
+ * @param value
+ * the value for the requested attribute.
+ * @throws NoSuchAttributeFault
+ * when the requested attribute cannot be found on the given
+ * entity instance.
+ * @throws EntityInstanceNotFoundFault
+ * when the requested entity instance cannot be found.
+ * @throws QManFault
+ * in case of internal system failure.
+ */
+ void setAttribute(String attributeName, Object value) throws NoSuchAttributeFault, EntityInstanceNotFoundFault, QManFault
+ {
+ try
+ {
+ _mxServer.setAttribute(_objectName, new Attribute(attributeName,value));
+ } catch (AttributeNotFoundException exception)
+ {
+ throw new NoSuchAttributeFault(
+ getWsResource().getEndpointReference(),
+ attributeName);
+ } catch (InstanceNotFoundException exception)
+ {
+ throw new EntityInstanceNotFoundFault(
+ getWsResource().getEndpointReference(),
+ _objectName);
+ } catch (Exception exception)
+ {
+ LOGGER.error(
+ Messages.QMAN_100036_SET_ATTRIBUTE_FAILURE,
+ attributeName,
+ _objectName);
+ throw new QManFault(
+ getWsResource().getEndpointReference(),
+ exception);
+ }
+ }
+
+ /**
+ * Invokes the requested operation on target JMX resource.
+ *
+ * @param operationName the name of the operation to be invoked.
+ * @param params parameters used for operation invocation.
+ * @param signature the operation / method signature.
+ * @throws EntityInstanceNotFoundFault
+ * when the target MBean doesn't exist on Management server.
+ * @throws MethodInvocationFault
+ * when the invocation of the requested operation raises an exception.
+ * @throws QManFault
+ * in case of not-well known failure.
+ */
+ Result invoke(String operationName, Object [] params, String [] signature) throws EntityInstanceNotFoundFault, MethodInvocationFault,QManFault
+ {
+ try
+ {
+ InvocationResult output = (InvocationResult) _mxServer
+ .invoke(
+ _objectName,
+ operationName,
+ params,
+ signature);
+
+ return new Result(output.getOutputSection());
+
+ } catch (InstanceNotFoundException exception)
+ {
+ throw new EntityInstanceNotFoundFault(
+ getWsResource().getEndpointReference(),
+ _objectName);
+ } catch (MBeanException exception)
+ {
+ if (exception.getTargetException() instanceof MethodInvocationException)
+ {
+ MethodInvocationException failure = (MethodInvocationException) exception.getTargetException();
+ throw new MethodInvocationFault(
+ getWsResource().getEndpointReference(),
+ operationName,
+ failure.getStatusText(),
+ failure.getReturnCode());
+ } else {
+ LOGGER.error(
+ Messages.QMAN_100037_INVOKE_OPERATION_FAILURE,
+ operationName,
+ _objectName);
+ throw new QManFault(
+ getWsResource().getEndpointReference(),
+ exception);
+ }
+ }catch(Exception exception)
+ {
+ LOGGER.error(
+ Messages.QMAN_100037_INVOKE_OPERATION_FAILURE,
+ operationName,
+ _objectName);
+ throw new QManFault(
+ getWsResource().getEndpointReference(),
+ exception);
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java
new file mode 100644
index 0000000000..ea67bdf9e1
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java
@@ -0,0 +1,549 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.capabilities;
+
+import javassist.CannotCompileException;
+import javassist.ClassClassPath;
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.CtField;
+import javassist.CtMethod;
+import javassist.CtNewMethod;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.ObjectName;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.Environment;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.wsdm.common.EntityInstanceNotFoundFault;
+import org.apache.qpid.management.wsdm.common.MethodInvocationFault;
+import org.apache.qpid.management.wsdm.common.NoSuchAttributeFault;
+import org.apache.qpid.management.wsdm.common.QManFault;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Builder for capability class that will implements the interface
+ * and the behaviour of the underlying JMX Entity.
+ * The product of this builder (capability class) will be used for create a new instance
+ * of the corresponding capability. It will be the "adapter" between WS-Resource and
+ * JMX MBean.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MBeanCapabilityBuilder implements IArtifactBuilder{
+
+ private final static String GET_PROPERTY_NAMES_METHOD_COMMON_PART = "public QName[] getPropertyNames() { return ";
+ private final static String GET_PROPERTY_NAMES_METHOD_WITH_ARRAY = GET_PROPERTY_NAMES_METHOD_COMMON_PART+" PROPERTIES;}";
+ private final static String GET_PROPERTY_NAMES_METHOD_WITH_EMPTY_ARRAY = GET_PROPERTY_NAMES_METHOD_COMMON_PART+" new QName[0];}";
+ private final static Logger LOGGER = Logger.get(MBeanCapabilityBuilder.class);
+
+ /**
+ * Handler interface definining operation needed to be
+ * peformed (by a concrete implementor) when the "endAttributes"
+ * director callback happens.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface EndAttributesHandler {
+
+ /**
+ * Concrete implementor must define in this method what
+ * needs to be done when the corresponding director callback
+ * happens (@see {@link MBeanCapabilityBuilder#endAttributes()}
+ *
+ * @throws BuilderException when a failure is raised inside the concrete implementation.
+ */
+ void endAttributes() throws BuilderException;
+ };
+
+ /**
+ * This is the concrete implementation of the internal interface EndAttributesHandler
+ * that is activated when this builder detects the presence of at least one property on the
+ * capability class.
+ */
+ final EndAttributesHandler _atLeastThereIsOneProperty = new EndAttributesHandler() {
+
+ /**
+ * Creates the QName array instance member and the corresponding
+ * accessor getPropertyNames().
+ *
+ * @throws BuilderException when the member above cannot be added to the capability class.
+ */
+ public void endAttributes() throws BuilderException
+ {
+ try
+ {
+ _properties.deleteCharAt(_properties.length()-1);
+ _properties.append("};");
+
+ CtField properties = CtField.make(_properties.toString(), _capabilityClassDefinition);
+
+ _capabilityClassDefinition.addField(properties);
+
+ CtMethod getPropertyNames = CtNewMethod.make(
+ GET_PROPERTY_NAMES_METHOD_WITH_ARRAY,
+ _capabilityClassDefinition);
+ _capabilityClassDefinition.addMethod(getPropertyNames);
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+ };
+
+ /**
+ * This is the concrete implementation of the internal interface EndAttributesHandler
+ * that is activated when this builder detects that there are no properties defined for
+ * the capability class.
+ */
+ final EndAttributesHandler _noPropertyHasBeenDefined= new EndAttributesHandler()
+ {
+ /**
+ * Creates the getPropertyNames() that simply returns an empty QName array.
+ *
+ * @throws BuilderException when the member above cannot be added to the capability class.
+ */
+ public void endAttributes() throws BuilderException
+ {
+ try
+ {
+ CtMethod getPropertyNames = CtNewMethod.make(
+ GET_PROPERTY_NAMES_METHOD_WITH_EMPTY_ARRAY,
+ _capabilityClassDefinition);
+ _capabilityClassDefinition.addMethod(getPropertyNames);
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+ };
+
+ /**
+ * This is the active state for this builder when the requested class has never been
+ * built.
+ */
+ IArtifactBuilder _classNotAvailable = new IArtifactBuilder()
+ {
+
+ /**
+ * Build process begins.
+ * The given object name is used to build a minimal definition of the product class.
+ *
+ * @param objectName the name of the JMX entity.
+ * @throws BuilderException when the initial definiton of the capability cannot be created.
+ */
+ public void begin(ObjectName objectName) throws BuilderException
+ {
+ String className = objectName.getKeyProperty(Names.CLASS);
+ ClassPool pool = ClassPool.getDefault();
+ pool.insertClassPath(new ClassClassPath(MBeanCapabilityBuilder.class));
+ pool.importPackage(QName.class.getPackage().getName());
+ pool.importPackage(ObjectName.class.getPackage().getName());
+ pool.importPackage(QManFault.class.getPackage().getName());
+ pool.importPackage(Names.class.getPackage().getName());
+ pool.importPackage(Result.class.getPackage().getName());
+ pool.importPackage(NoSuchAttributeFault.class.getPackage().getName());
+ pool.importPackage(EntityInstanceNotFoundFault.class.getPackage().getName());
+ pool.importPackage(MethodInvocationFault.class.getPackage().getName());
+
+ _capabilityClassDefinition = pool.makeClass("org.apache.qpid.management.wsdm.capabilities."+className);
+ try
+ {
+ _capabilityClassDefinition.setSuperclass(pool.get(MBeanCapability.class.getName()));
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+
+ /**
+ * Director callback.
+ * All attributes have been notified.
+ *
+ * This builder is using this callback in order to create the initial
+ * properties QNames declaration.
+ *
+ */
+ public void endAttributes() throws BuilderException
+ {
+ _endAttributeHandler.endAttributes();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void endOperations() throws BuilderException
+ {
+ try
+ {
+ _capabilityClass = _capabilityClassDefinition.toClass(
+ QManAdapterCapability.class.getClassLoader(),
+ QManAdapterCapability.class.getProtectionDomain());
+ } catch (Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+
+ /**
+ * Director callback.
+ * Attrbute metadata notification. With this callback the director informs this builder that the
+ * currently processed MBean has an attribute with the given metadata.
+ * This builder uses this information in order to add a property and the corresponding accessors
+ * to the capability class that is going to be built.
+ *
+ * @throws BuilderException bytecode manipulation / creation failure.
+ */
+ public void onAttribute(MBeanAttributeInfo attribute) throws BuilderException
+ {
+ String name = attribute.getName();
+ String type = attribute.getType();
+
+ try
+ {
+ type = Class.forName(type).getCanonicalName();
+
+ addPropertyMemberInstance(type, name);
+
+ String nameForAccessors = getNameForAccessors(name);
+
+ if (attribute.isReadable())
+ {
+ String accessor = generateGetter(type, nameForAccessors,name);
+ CtMethod getter = CtNewMethod.make(accessor,_capabilityClassDefinition);
+ _capabilityClassDefinition.addMethod(getter);
+ appendToPropertiesArray(name);
+
+ LOGGER.debug(
+ Messages.QMAN_200043_GENERATED_ACCESSOR_METHOD,
+ _objectName,
+ accessor);
+ }
+
+ if (attribute.isWritable())
+ {
+ String accessor = generateSetter(type, nameForAccessors,name);
+ CtMethod setter = CtNewMethod.make(accessor,_capabilityClassDefinition);
+ _capabilityClassDefinition.addMethod(setter);
+
+ LOGGER.debug(
+ Messages.QMAN_200043_GENERATED_ACCESSOR_METHOD,
+ _objectName,
+ accessor);
+ }
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+
+ public void onOperation(MBeanOperationInfo operation) throws BuilderException
+ {
+ StringBuilder method = new StringBuilder();
+ try
+ {
+ method
+ .append("public Result ")
+ .append(operation.getName())
+ .append("( ");
+
+ for (MBeanParameterInfo parameter: operation.getSignature())
+ {
+ method
+ .append(Class.forName(parameter.getType()).getCanonicalName())
+ .append(' ')
+ .append(parameter.getName())
+ .append(',');
+ }
+
+ method.deleteCharAt(method.length()-1);
+ method.append(") throws EntityInstanceNotFoundFault, MethodInvocationFault,QManFault { return invoke(")
+ .append("\"").append(operation.getName()).append("\"")
+ .append(", new Object[]{ ");
+
+ for (MBeanParameterInfo parameter: operation.getSignature())
+ {
+ method.append(parameter.getName())
+ .append(',');
+ }
+
+ method.deleteCharAt(method.length()-1);
+ method.append("}, new String[]{ ");
+
+ for (MBeanParameterInfo parameter: operation.getSignature())
+ {
+ method
+ .append("\"")
+ .append(parameter.getType())
+ .append("\",");
+ }
+ method.deleteCharAt(method.length()-1);
+ method.append("}); }");
+
+ String methodAsString = method.toString();
+ methodAsString = methodAsString.replace("new Object[]{}","null");
+ methodAsString = methodAsString.replace("new String[]{}","null");
+
+ CtMethod definition = CtNewMethod.make(methodAsString,_capabilityClassDefinition);
+ _capabilityClassDefinition.addMethod(definition);
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ } finally {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(
+ Messages.QMAN_200044_GENERATED_METHOD,
+ _objectName,
+ method.toString());
+ }
+ }
+ }
+
+ public void setEnvironment(Environment environment)
+ {
+ // Nothing to do here...
+ }
+ };
+
+ StringBuilder _properties = new StringBuilder("private static final QName[] PROPERTIES = new QName[]{ ");
+ private Class<MBeanCapability> _capabilityClass;
+ CtClass _capabilityClassDefinition;
+ EndAttributesHandler _endAttributeHandler = _noPropertyHasBeenDefined;
+
+ private ObjectName _objectName;
+
+ IArtifactBuilder _state;
+
+ /**
+ * Director callback.
+ * Attrbute metadata notification. With this callback the director informs this builder that the
+ * currently processed MBean has an attribute with the given metadata.
+ * This builder uses this information in order to add a property and the corresponding accessors
+ * to the capability class that is going to be built.
+ *
+ * @throws BuilderException bytecode manipulation / creation failure.
+ */
+ public void onAttribute(MBeanAttributeInfo attribute) throws BuilderException
+ {
+ _state.onAttribute(attribute);
+ }
+
+ /**
+ * First callback : this method is called at the begin of the director process.
+ * Contains builder initialization code.
+ *
+ * @param objectName the name of the target JMX entity of this capability.
+ * @throws BuilderException when the initialization fails.
+ */
+ @SuppressWarnings("unchecked")
+ public void begin(ObjectName objectName) throws BuilderException
+ {
+ try
+ {
+ this._objectName = objectName;
+ String className = objectName.getKeyProperty(Names.CLASS);
+ _capabilityClass = (Class<MBeanCapability>) Class.forName("org.apache.qpid.management.wsdm.capabilities."+className);
+ _state = new DummyCapabilityBuilder();
+ } catch (ClassNotFoundException exception)
+ {
+ _state = _classNotAvailable;
+ }
+
+ _state.begin(objectName);
+ }
+
+ /**
+ * Director callback.
+ * Operation metadata notification. With this callback the director informs this builder that the
+ * currently processed MBean has an operation with the given metadata.
+ * This builder uses this information in order to add a method to the capability class that is
+ * going to be built.
+ *
+ * For example, let's suppose that an operation like that is detected on the MBean :
+ *
+ * public void purge(int request)
+ *
+ * then the capability will be enrichied with the following method :
+ *
+ * public void purge(int request) throws QManFault {
+ * invoke(
+ * "purge",
+ * new Object[]{request},
+ * new String[]{int.class.getName()});
+ * }
+ *
+ * @throws BuilderException bytecode manipulation / creation failure.
+ */
+ public void onOperation(MBeanOperationInfo operation) throws BuilderException
+ {
+ _state.onOperation(operation);
+ }
+
+ /**
+ * Returns the capability class (the product of this builder).
+ *
+ * @return the capability class (the product of this builder).
+ */
+ Class<MBeanCapability> getCapabilityClass()
+ {
+ return _capabilityClass;
+ }
+
+ /**
+ * Determines what needs to be done when all attributes
+ * metadata has been notified to this builder.
+ * Capability class must have an array member with all defined
+ * properties and a getter method that returns it.
+ * In this method those two members are declared (obviously only
+ * if this capability has at least one property).
+ *
+ * @throws BuilderException when something fails during this phase.
+ */
+ public void endAttributes() throws BuilderException
+ {
+ _state.endAttributes();
+ }
+
+ /**
+ * Director callback.
+ * This method is notified when all operations metadata has been
+ * notified to this builder.
+ * This is the place where the capability class is created, defined and loaded by the JVM.
+ *
+ * @throws BuilderException issues on this method are basically class loading related.
+ */
+ @SuppressWarnings("unchecked")
+ public void endOperations() throws BuilderException
+ {
+ _state.endOperations();
+ }
+
+ /**
+ * Injects the module environment on this builder.
+ *
+ * @param environment the module environment.
+ */
+ public void setEnvironment(Environment environment)
+ {
+ // Nothing to do here...
+ }
+
+ /**
+ * Generates the get accessor method for the given property.
+ *
+ * @param type the type of the property.
+ * @param name the name of the property with the first letter capitalized.
+ * @param plainName the plain name of the property.
+ * @return the getter method (as a string).
+ */
+ String generateGetter(String type, String name,String plainName)
+ {
+ return new StringBuilder()
+ .append("public ")
+ .append(type)
+ .append(' ')
+ .append("get")
+ .append(name)
+ .append("() throws NoSuchAttributeFault,EntityInstanceNotFoundFault,QManFault { return (")
+ .append(type)
+ .append(") getAttribute(\"")
+ .append(plainName)
+ .append("\"); }")
+ .toString();
+ }
+
+ /**
+ * Generates the set accessor method for the given property.
+ *
+ * @param type the type of the property.
+ * @param name the name of the property with the first letter capitalized.
+ * @param plainName the plain name of the property.
+ * @return the setter method (as a string).
+ */
+ String generateSetter(String type, String name, String plainName)
+ {
+ return new StringBuilder()
+ .append("public void ")
+ .append("set")
+ .append(name)
+ .append("(")
+ .append(type)
+ .append(" newValue) throws NoSuchAttributeFault,EntityInstanceNotFoundFault,QManFault {")
+ .append(" setAttribute(\"")
+ .append(plainName)
+ .append("\", newValue); }")
+ .toString();
+ }
+
+ /**
+ * Appends the given attribute name to the properties array declared as an
+ * instance member of the capability class.
+ *
+ * @param attributeName the name of the attribute.
+ */
+ private void appendToPropertiesArray(String attributeName)
+ {
+ _properties.append("new QName(Names.NAMESPACE_URI, \"")
+ .append(attributeName)
+ .append("\", Names.PREFIX),");
+
+ _endAttributeHandler = _atLeastThereIsOneProperty;
+ }
+
+ /**
+ * Adds a new property member instance to the capability class.
+ *
+ * @param type the type of the property.
+ * @param name the name of the property.
+ * @throws CannotCompileException when the property cannot be added.
+ */
+ private void addPropertyMemberInstance(String type, String name) throws CannotCompileException
+ {
+ StringBuilder buffer = new StringBuilder()
+ .append("private ")
+ .append(type)
+ .append(' ')
+ .append(name)
+ .append(';');
+
+ CtField field= CtField.make(buffer.toString(),_capabilityClassDefinition);
+ _capabilityClassDefinition.addField(field);
+ }
+
+ /**
+ * Returns a name that will be used in accessor methods.
+ * That name will differ from the given one because the first letter will be capitalized.
+ * For example, if the given name is "name" the return value will be "Name".
+ *
+ * @param name the plain name of the attribute.
+ * @return a capitalized version of the given name to be used in accessors.
+ */
+ String getNameForAccessors(String name)
+ {
+ return
+ Character.toUpperCase(name.charAt(0)) +
+ name.substring(1);
+ }
+
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java
new file mode 100644
index 0000000000..414f37a746
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java
@@ -0,0 +1,557 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.capabilities;
+
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanServer;
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.AbstractCapability;
+import org.apache.muse.core.Resource;
+import org.apache.muse.core.ResourceManager;
+import org.apache.muse.core.routing.MessageHandler;
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.notification.NotificationProducer;
+import org.apache.muse.ws.notification.WsnConstants;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.jmx.EntityLifecycleNotification;
+import org.apache.qpid.management.wsdm.common.ThreadSessionManager;
+import org.apache.qpid.management.wsdm.common.UnableToConnectWithBrokerFault;
+import org.apache.qpid.management.wsdm.muse.engine.WSDMAdapterEnvironment;
+import org.apache.qpid.management.wsdm.muse.serializer.ByteArraySerializer;
+import org.apache.qpid.management.wsdm.notifications.LifeCycleEvent;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * QMan Adapter capability.
+ * Basically it acts as a lifecycle manager of all ws resource that correspond to entities on JMX side.
+ *
+ * @author Andrea Gazzarini
+*/
+@SuppressWarnings("serial")
+public class QManAdapterCapability extends AbstractCapability
+{
+ private final static Logger LOGGER = Logger.get(QManAdapterCapability.class);
+
+ private MBeanServer _mxServer;
+ private WsArtifactsFactory _artifactsFactory;
+ private URI _resourceURI;
+ private NotificationProducer _publisherCapability;
+ private ThreadPoolExecutor _workManager;
+ private Map<String, QName> _lifeCycleTopics = new HashMap<String, QName>();
+
+ /**
+ * Runnable wrapper used for sending asynchronous
+ * notifications.
+ *
+ * @author Andrea Gazzarini
+ */
+ private final class AsynchNotificationTask implements Runnable
+ {
+ private final QName topicName;
+ private final LifeCycleEvent event;
+
+ AsynchNotificationTask(QName tName, LifeCycleEvent evt)
+ {
+ topicName = tName;
+ event = evt;
+ }
+
+ public void run()
+ {
+ try
+ {
+ _publisherCapability.publish(topicName,event);
+ } catch (SoapFault exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100038_UNABLE_TO_SEND_WS_NOTIFICATION);
+ }
+ }
+ };
+
+ /**
+ * NotificationFilter for "create" only events.
+ */
+ private final NotificationFilter _filterForNewInstances = new NotificationFilter(){
+
+ /**
+ * Returns true when the notification is related to a creation of a new instance.
+ *
+ * @return true when the notification is related to a creation of a new instance.
+ */
+ public boolean isNotificationEnabled(Notification notification)
+ {
+ return EntityLifecycleNotification.INSTANCE_ADDED_NOTIFICATION_TYPE.equals(notification.getType());
+ }
+
+ };
+
+ /**
+ * NotificationFilter for "remove" only events.
+ */
+ private final NotificationFilter _filterForRemovedInstances = new NotificationFilter(){
+
+ /**
+ * Returns true when the notification is related to a deletion of an existing instance.
+ *
+ * @return true when the notification is related to a deletion of an existing instance.
+ */
+ public boolean isNotificationEnabled(Notification notification)
+ {
+ return EntityLifecycleNotification.INSTANCE_REMOVED_NOTIFICATION_TYPE.equals(notification.getType());
+ }
+ };
+
+ /**
+ * This listener handles "create" mbean events and therefore provides procedure to create and initialize
+ * corresponding ws resources.
+ */
+ private final NotificationListener _listenerForNewInstances = new NotificationListener()
+ {
+ /**
+ * Handles JMX "create" notification type.
+ *
+ * @param notification the entity lifecycle notification.
+ * @param data user data associated with the incoming notifiication : it is not used at the moment.
+ */
+ public void handleNotification(Notification notification, Object data)
+ {
+ ObjectName eventSourceName = null;
+ try
+ {
+ EntityLifecycleNotification lifecycleNotification = (EntityLifecycleNotification) notification;
+ eventSourceName = lifecycleNotification.getObjectName();
+
+ ThreadSessionManager.getInstance().getSession().setObjectName(eventSourceName);
+
+ LOGGER.debug(Messages.QMAN_200039_DEBUG_JMX_NOTIFICATION, notification);
+
+ ResourceManager resourceManager = getResource().getResourceManager();
+ Resource resource = resourceManager.createResource(Names.QMAN_RESOURCE_NAME);
+
+ WsArtifacts artifacts = _artifactsFactory.getArtifactsFor(resource,eventSourceName);
+ MBeanCapability capability = _artifactsFactory.createCapability(
+ artifacts.getCapabilityClass(),
+ eventSourceName);
+
+ ThreadSessionManager.getInstance().getSession().setWsdlDocument(artifacts.getWsdl());
+ ThreadSessionManager.getInstance().getSession().setResourceMetadataDescriptor(artifacts.getResourceMetadataDescriptor());
+
+ resource.setWsdlPortType(Names.QMAN_RESOURCE_PORT_TYPE_NAME);
+ capability.setCapabilityURI(Names.NAMESPACE_URI+"/"+capability.getClass().getSimpleName());
+ capability.setMessageHandlers(createMessageHandlers(capability));
+
+ resource.addCapability(capability);
+ resource.initialize();
+ resourceManager.addResource(resource.getEndpointReference(), resource);
+
+ LOGGER.info(
+ Messages.QMAN_000030_RESOURCE_HAS_BEEN_CREATED,
+ eventSourceName);
+
+ AsynchNotificationTask asynchNotificationTask = new AsynchNotificationTask(
+ getTopicName(lifecycleNotification.getClassKind()),
+ LifeCycleEvent.newCreateEvent(
+ eventSourceName.getKeyProperty(Names.OBJECT_ID),
+ lifecycleNotification.getPackageName(),
+ lifecycleNotification.getClassName()));
+
+ _workManager.execute(asynchNotificationTask);
+
+ } catch (ArtifactsNotAvailableException exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100023_BUILD_WS_ARTIFACTS_FAILURE);
+ } catch (IllegalAccessException exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100024_CAPABILITY_INSTANTIATION_FAILURE,
+ eventSourceName);
+ } catch (InstantiationException exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100024_CAPABILITY_INSTANTIATION_FAILURE,
+ eventSourceName);
+ } catch (SoapFault exception)
+ {
+ LOGGER.error(
+ exception,Messages.QMAN_100025_WSRF_FAILURE,
+ eventSourceName);
+ } catch (Exception exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100025_WSRF_FAILURE,
+ eventSourceName);
+ }
+ }
+ };
+
+ /**
+ * This listener handles "remove" mbean events and therefore provides procedure to shutdown and remove
+ * corresponding ws resources.
+ */
+ private final NotificationListener _listenerForRemovedInstances = new NotificationListener()
+ {
+ /**
+ * Handles JMX "remove" notification type.
+ *
+ * @param notification the entity lifecycle notification.
+ * @param data user data associated with the incoming notifiication : it is not used at the moment.
+ */
+ public void handleNotification(Notification notification, Object data)
+ {
+ EntityLifecycleNotification lifecycleNotification = (EntityLifecycleNotification) notification;
+ ObjectName eventSourceName = lifecycleNotification.getObjectName();
+
+ LOGGER.debug(Messages.QMAN_200042_REMOVING_RESOURCE, eventSourceName);
+
+ EndpointReference endpointPointReference = new EndpointReference(_resourceURI);
+ endpointPointReference.addParameter(
+ Names.RESOURCE_ID_QNAME,
+ eventSourceName.getKeyProperty(Names.OBJECT_ID));
+
+ ResourceManager resourceManager = getResource().getResourceManager();
+ try
+ {
+ Resource resource = resourceManager.getResource(endpointPointReference);
+ resource.shutdown();
+
+ LOGGER.info(
+ Messages.QMAN_000031_RESOURCE_HAS_BEEN_REMOVED,
+ eventSourceName);
+
+ AsynchNotificationTask asynchNotificationTask = new AsynchNotificationTask(
+ getTopicName(lifecycleNotification.getClassKind()),
+ LifeCycleEvent.newRemoveEvent(
+ eventSourceName.getKeyProperty(Names.OBJECT_ID),
+ lifecycleNotification.getPackageName(),
+ lifecycleNotification.getClassName()));
+
+ _workManager.execute(asynchNotificationTask);
+
+ }
+ catch(Exception exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100027_RESOURCE_SHUTDOWN_FAILURE,
+ eventSourceName);
+ }
+ }
+ };
+
+ /**
+ * Initializes this capability.
+ *
+ * @throws SoapFault when the initialization fails..
+ */
+ @Override
+ public void initialize() throws SoapFault
+ {
+ super.initialize();
+
+ registerByteArraySerializer();
+
+ createLifeCycleTopics();
+
+ initializeWorkManager();
+
+ createQManResourceURI();
+
+ _mxServer = ManagementFactory.getPlatformMBeanServer();
+ _artifactsFactory = new WsArtifactsFactory(getEnvironment(),_mxServer);
+
+ registerQManLifecycleListeners();
+ }
+
+ /**
+ * Connects QMan with a broker with the given connection data.
+ *
+ * @param host the host where the broker is running.
+ * @param port the port number where the broker is running.
+ * @param username username for estabilshing connection.
+ * @param password password for estabilshing connection.
+ * @param virtualHost the virtualHost name.
+ * @param initialPoolCapacity the initial size of broker connection pool.
+ * @param maxPoolCapacity the max allowed size of broker connection pool.
+ * @param maxWaitTimeout the max wait timeout for retrieving connections.
+ * @throws SoapFault when the connection with broker cannot be estabilished.
+ */
+ @SuppressWarnings("unchecked")
+ public void connect(
+ String host,
+ int port,
+ String username,
+ String password,
+ String virtualHost,
+ int initialPoolCapacity,
+ int maxPoolCapacity,
+ long maxWaitTimeout) throws SoapFault
+ {
+ try
+ {
+ _mxServer.invoke(
+ Names.QMAN_OBJECT_NAME,
+ "addBroker",
+ new Object[]{host,port,username,password,virtualHost,initialPoolCapacity,maxPoolCapacity,maxWaitTimeout},
+ new String[]{
+ String.class.getName(),
+ int.class.getName(),
+ String.class.getName(),
+ String.class.getName(),
+ String.class.getName(),
+ int.class.getName(),
+ int.class.getName(),
+ long.class.getName()});
+ } catch(Exception exception)
+ {
+ LOGGER.error(Messages.QMAN_100017_UNABLE_TO_CONNECT,host,port);
+ throw new UnableToConnectWithBrokerFault(
+ getResource().getEndpointReference(),
+ host,
+ port,
+ username,
+ virtualHost,
+ exception.getMessage());
+ }
+ }
+
+ /**
+ * Creates the message handlers for the given capability.
+ *
+ * @param capability the QMan capability.
+ * @return a collection with message handlers for the given capability.
+ */
+ protected Collection<MessageHandler> createMessageHandlers(MBeanCapability capability)
+ {
+ Collection<MessageHandler> handlers = new ArrayList<MessageHandler>();
+
+ for (Method method : capability.getClass().getDeclaredMethods())
+ {
+ String name = method.getName();
+
+ QName requestName = new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX);
+
+ QName returnValueName = new QName(
+ Names.NAMESPACE_URI,
+ name+"Response",
+ Names.PREFIX);
+
+ String actionURI = Names.NAMESPACE_URI+"/"+name;
+
+ MessageHandler handler = new QManMessageHandler(
+ actionURI,
+ requestName,
+ returnValueName);
+
+ handler.setMethod(method);
+ handlers.add(handler);
+ }
+ return handlers;
+ }
+
+ /**
+ * Returns the publisher capability associated with the owner resource.
+ *
+ * @return the publisher capability associated with the owner resource.
+ */
+ NotificationProducer getPublisherCapability()
+ {
+ return (NotificationProducer) getResource().getCapability(WsnConstants.PRODUCER_URI);
+ }
+
+ /**
+ * Creates events & objects lifecycle topic that will be used to publish lifecycle event
+ * messages..
+ */
+ void createLifeCycleTopics()
+ {
+ try
+ {
+ _publisherCapability = getPublisherCapability();
+
+ _publisherCapability.addTopic(Names.EVENTS_LIFECYLE_TOPIC_NAME);
+ _lifeCycleTopics.put(Names.EVENT,Names.EVENTS_LIFECYLE_TOPIC_NAME);
+
+ LOGGER.info(
+ Messages.QMAN_000032_EVENTS_LIFECYCLE_TOPIC_HAS_BEEN_CREATED,
+ Names.OBJECTS_LIFECYLE_TOPIC_NAME);
+
+ _publisherCapability.addTopic(Names.OBJECTS_LIFECYLE_TOPIC_NAME);
+ _lifeCycleTopics.put(Names.CLASS,Names.OBJECTS_LIFECYLE_TOPIC_NAME);
+
+ LOGGER.info(
+ Messages.QMAN_000033_OBJECTS_LIFECYCLE_TOPIC_HAS_BEEN_CREATED,
+ Names.OBJECTS_LIFECYLE_TOPIC_NAME);
+
+ _publisherCapability.addTopic(Names.UNKNOWN_OBJECT_TYPE_LIFECYLE_TOPIC_NAME);
+ LOGGER.info(
+ Messages.QMAN_000034_UNCLASSIFIED_LIFECYCLE_TOPIC_HAS_BEEN_CREATED,
+ Names.OBJECTS_LIFECYLE_TOPIC_NAME);
+ } catch(Exception exception)
+ {
+ LOGGER.error(exception, Messages.QMAN_100036_TOPIC_DECLARATION_FAILURE);
+ }
+ }
+
+ /**
+ * Starting from an object type (i.e. event or class) returns the name of the
+ * corresponding topic where the lifecycle message must be published.
+ * Note that if the given object type is unknown then the "Unclassified Object Types" topic
+ * will be returned (and therefore the message will be published there).
+ *
+ * @param objectType the type of the object.
+ * @return the name of the topic associated with the given object type.
+ */
+ QName getTopicName(String objectType)
+ {
+ QName topicName = _lifeCycleTopics.get(objectType);
+ return (topicName != null)
+ ? topicName
+ : Names.UNKNOWN_OBJECT_TYPE_LIFECYLE_TOPIC_NAME;
+ }
+
+ /**
+ * Workaround : it seems that is not possibile to declare a serializer
+ * for a byte array using muse descriptor...
+ * What is the stringified name of the class?
+ * byte[].getClass().getName() is [B but is not working (ClassNotFound).
+ * So, at the end, this is hard-coded here!
+ */
+ private void registerByteArraySerializer()
+ {
+ SerializerRegistry.getInstance().registerSerializer(
+ byte[].class,
+ new ByteArraySerializer());
+ }
+
+ /**
+ * Creates the URI that will be later used to identify a QMan WS-Resource.
+ * Note that the resources that will be created are identified also with their resource id.
+ * Briefly we could say that this is the soap:address of the WS-Resource definition.
+ *
+ * @throws SoapFault when the URI cannot be built (probably it is malformed).
+ */
+ private void createQManResourceURI() throws SoapFault
+ {
+ WSDMAdapterEnvironment environment = (WSDMAdapterEnvironment) getEnvironment();
+ String resourceURI = environment.getDefaultURIPrefix()+Names.QMAN_RESOURCE_NAME;
+ try
+ {
+ _resourceURI = URI.create(resourceURI);
+
+ } catch(IllegalArgumentException exception)
+ {
+ LOGGER.info(
+ exception,
+ Messages.QMAN_100029_MALFORMED_RESOURCE_URI_FAILURE,
+ resourceURI);
+ throw new SoapFault(exception);
+ }
+ }
+
+ /**
+ * Initializes the work manager used for asynchronous notifications.
+ */
+ private void initializeWorkManager()
+ {
+ Configuration configuration = Configuration.getInstance();
+ _workManager = new ThreadPoolExecutor(
+ configuration.getWorkerManagerPoolSize(),
+ configuration.getWorkerManagerMaxPoolSize(),
+ configuration.getWorkerManagerKeepAliveTime(),
+ TimeUnit.MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(30));
+ }
+
+ /**
+ * This adapter capability needs to be an event listener of QMan JMX core
+ * in order to detect relevant lifecycle events and therefore create WS artifacts & notification(s).
+ *
+ * @throws SoapFault when it's not possible to register event listener : is QMan running?
+ */
+ @SuppressWarnings("serial")
+ private void registerQManLifecycleListeners() throws SoapFault
+ {
+ try
+ {
+ _mxServer.addNotificationListener(
+ Names.QMAN_OBJECT_NAME,
+ _listenerForNewInstances,
+ _filterForNewInstances,
+ null);
+
+ _mxServer.addNotificationListener(
+ Names.QMAN_OBJECT_NAME,
+ _listenerForRemovedInstances,
+ _filterForRemovedInstances,
+ null);
+
+ try
+ {
+ _mxServer.addNotificationListener(
+ Names.QPID_EMULATOR_OBJECT_NAME,
+ _listenerForNewInstances,
+ _filterForNewInstances, null);
+
+ _mxServer.addNotificationListener(
+ Names.QPID_EMULATOR_OBJECT_NAME,
+ _listenerForRemovedInstances,
+ _filterForRemovedInstances, null);
+
+ } catch (Exception exception)
+ {
+ LOGGER.info(Messages.QMAN_000028_TEST_MODULE_NOT_FOUND);
+ }
+ } catch(InstanceNotFoundException exception)
+ {
+ throw new SoapFault(exception);
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMessageHandler.java
new file mode 100644
index 0000000000..95f54ef5b5
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMessageHandler.java
@@ -0,0 +1,104 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.capabilities;
+
+import java.lang.reflect.Method;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.routing.ReflectionMessageHandler;
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.wsdm.muse.serializer.ByteArraySerializer;
+import org.w3c.dom.Element;
+
+/**
+ * JMXConnectionListener_example custom implementation of Muse message handler to properly deal with
+ * byte arrays.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QManMessageHandler extends ReflectionMessageHandler
+{
+
+ /**
+ * Builds a new message handler with the given arguments.
+ *
+ * @param actionURI the action URI.
+ * @param requestQName the qname of the incoming request.
+ * @param returnValueName the qname of the result value.
+ */
+ public QManMessageHandler(String actionURI, QName requestQName,
+ QName returnValueName)
+ {
+ super(actionURI, requestQName, returnValueName);
+ }
+
+ /**
+ * Transforms the given xml element in the corresponding
+ * object representation.
+ *
+ * @throws SoapFaul when unmarshal operation fails.
+ */
+ @SuppressWarnings("unchecked")
+ public Object[] fromXML(Element xml) throws SoapFault
+ {
+ Method method = getMethod();
+
+ if (xml == null )
+ {
+ return EMPTY_REQUEST;
+ }
+
+ Class[] parameters = method.getParameterTypes();
+ Object[] objects = new Object[parameters.length];
+
+ Element[] elements = XmlUtils.getAllElements(xml);
+
+ if (parameters.length == 1 && elements.length == 0)
+ {
+ elements = new Element[]{ xml };
+ }
+
+ if (elements.length != parameters.length)
+ {
+ throw new SoapFault("IncorrectParams");
+ }
+
+ SerializerRegistry registry = SerializerRegistry.getInstance();
+
+ for (int i = 0; i < elements.length; ++i)
+ {
+ Class clazz = parameters[i];
+ if (clazz == byte[].class)
+ {
+ objects[i] = new ByteArraySerializer().fromXML(elements[i]);
+ } else
+ {
+ Serializer ser = registry.getSerializer(parameters[i]);
+ objects[i] = ser.fromXML(elements[i]);
+ }
+ }
+ return objects;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java
new file mode 100644
index 0000000000..d6255d0bed
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.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.management.wsdm.capabilities;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.metadata.WsxConstants;
+import org.apache.muse.ws.resource.WsResource;
+import org.apache.muse.ws.resource.metadata.MetadataDescriptor;
+import org.apache.muse.ws.resource.metadata.WsrmdConstants;
+import org.apache.muse.ws.resource.metadata.ext.WsrfMetadataExchange;
+import org.apache.muse.ws.wsdl.WsdlUtils;
+import org.apache.qpid.management.wsdm.muse.resources.QManWsResource;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * QMan resource metadata exchange.
+ * We cannot resuse the preexisting classes directly because the wsdl of the service instance
+ * is retrieved using a file path.
+ * Since the owner resource (QManWsResource) is dynamic (I mean, its interface is dynamic), the corresponding
+ * WSDL cannot defined at compile time but needs some changes when the resource is created.
+ * As part of that, the WSDL template found under wsdl folder is modified with the additional properties of the given
+ * resource. The metadata exchange capability must include those properties too.
+ *
+ * Note that this capability is appliable only to a QManWsResource.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QManMetadataExchangeCapability extends WsrfMetadataExchange
+{
+ /**
+ * Returns the WSDL associated with the owner of this capability.
+ *
+ * @return the WSDL associated with the owner of this capability.
+ */
+ @Override
+ protected Element getWSDL()
+ {
+ QManWsResource resource = (QManWsResource) getResource();
+
+ Document wsdlDoc = resource.getWsdl();
+ Element wsdl = XmlUtils.getFirstElement(wsdlDoc);
+
+ WsdlUtils.removeWsdlReferences(wsdl);
+ WsdlUtils.removeSchemaReferences(wsdl);
+
+ return wsdl;
+ }
+
+ /**
+ * Returns the resource metadata descriptor associated with the owenr
+ * resource of thi capability.
+ *
+ * @return the resource metadata descriptor.
+ */
+ protected Element getResourceMetadataDescriptor()
+ {
+ WsResource resource = (WsResource)getResource();
+ MetadataDescriptor metadataDescriptor = resource.getPropertyCollection().getMetadata();
+ return metadataDescriptor.toXML();
+ }
+
+ public Element[] getMetadata(String dialect)
+ {
+ if (dialect == null)
+ {
+ return new Element[]{
+ getResourceMetadataDescriptor(),
+ getWSDL()};
+ } else {
+ if (WsrmdConstants.NAMESPACE_URI.equals(dialect))
+ {
+ return new Element[]{getResourceMetadataDescriptor()};
+ } else if (WsxConstants.WSDL_DIALECT.equals(dialect))
+ {
+ return new Element[]{getWSDL()};
+ }
+ }
+ return super.getMetadata(dialect);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java
new file mode 100644
index 0000000000..a00d2665ae
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java
@@ -0,0 +1,57 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.capabilities;
+
+import java.util.*;
+
+/**
+ * Data Transfer Object that encapsulates the result of a method invocation.
+ * This is the object that will be marshalled in XML and will contain the result of a method
+ * invocation (status code & text).
+ *
+ * @author Andrea Gazzarini
+ */
+public final class Result
+{
+ private final Map<String,Object> _outputParameters;
+
+ /**
+ * Builds a new result DTO with the given parameters.
+ *
+ * @param statusCode the return code.
+ * @param statusText the status message.
+ * @param outputParameters the output parameters.
+ */
+ public Result(Map<String, Object> outputParameters)
+ {
+ this._outputParameters = outputParameters;
+ }
+
+ /**
+ * Returns the output parameterss.
+ *
+ * @return the output parameterss.
+ */
+ public Map<String, Object> getOutputParameters()
+ {
+ return _outputParameters;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java
new file mode 100644
index 0000000000..c1678eb43f
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java
@@ -0,0 +1,135 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.capabilities;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.ObjectName;
+
+import org.apache.muse.core.Environment;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.resource.metadata.WsrmdConstants;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.qman.debug.WsdlDebugger;
+import org.w3c.dom.Element;
+
+/**
+ * Resource Metadata Descriptor Builder.
+ * It is used for build the metadata descriptor for properties of the
+ * incoming jmx object.
+ *
+ * @author Andrea Gazzarini
+ */
+class RmdBuilder implements IArtifactBuilder
+{
+ private List<Element> _metadataDescriptor = new ArrayList<Element>();
+
+ ObjectName _objectName;
+
+ /**
+ * Nothing to be done here on this builder.
+ * Simply logs a message indicating the target object name.
+ *
+ * @param objectName the jmx name of the object that is going to be processed.
+ */
+ public void begin(ObjectName objectName)
+ {
+ this._objectName = objectName;
+ }
+
+ /**
+ * Nothing to be done here on this builder.
+ *
+ * @throws BuilderException never.
+ */
+ public void endAttributes()
+ {
+ // N.A. for this builder.
+ }
+
+ /**
+ * Nothing to be done here on this builder.
+ *
+ * @throws BuilderException never.
+ */
+ public void endOperations()
+ {
+ // N.A. for this builder.
+ }
+
+ /**
+ * Process a single attribute metadata.
+ * An attribute (that is, a property) represented by the corresponding incoming
+ * attribute metadata will generate an wsrmd:Property xml element with the constraints
+ * (initial values, static values, allowed values) contained on the metadata.
+ *
+ * @param attributeMetadata the attribute (jmx) metadata.
+ */
+ public void onAttribute(MBeanAttributeInfo attributeMetadata)
+ {
+ Element property = XmlUtils.createElement(WsrmdConstants.PROPERTY_QNAME);
+ property.setAttribute(Names.NAME_ATTRIBUTE, Names.PREFIX+":"+attributeMetadata.getName());
+ property.setAttribute(Names.MODIFIABILITY,
+ attributeMetadata.isWritable()
+ ? Names.READ_WRITE
+ : Names.READ_ONLY);
+ property.setAttribute(Names.MUTABILITY,Names.MUTABLE);
+
+ WsdlDebugger.debug(_objectName, property);
+
+ _metadataDescriptor.add(property);
+ }
+
+ /**
+ * Nothing to be done here on this builder.
+ *
+ * @throws BuilderException never.
+ */
+ public void onOperation(MBeanOperationInfo operation)
+ {
+ // N.A. for this builder
+ }
+
+ /**
+ * Nothing to be done here on this builder.
+ *
+ * @throws BuilderException never.
+ */
+ public void setEnvironment(Environment environment)
+ {
+ // N.A. for this builder
+ }
+
+ /**
+ * Nothing to be done here on this builder.
+ *
+ * @throws BuilderException never.
+ */
+ public Element[] getResourceMetadataDescriptor()
+ {
+ Element [] properties = _metadataDescriptor.toArray(
+ new Element[_metadataDescriptor.size()]);
+ return properties;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java
new file mode 100644
index 0000000000..35a919c295
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java
@@ -0,0 +1,196 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.capabilities;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.ObjectName;
+
+import org.apache.muse.core.Environment;
+import org.apache.muse.core.Resource;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Director used for coordinate the building process of WS-DM artifacts.
+ *
+ * @author Andrea Gazzarini
+ */
+final class WSDMArtifactsDirector
+{
+ private final ObjectName _eventSourceObjectName;
+ private final MBeanInfo _metadata;
+
+ private final MBeanCapabilityBuilder _capabilityBuilder;
+ private final WsdlBuilder _wsdlBuilder;
+ private final RmdBuilder _rmdBuilder;
+
+ /**
+ * Builds a new director with the given objectname and (jmx) metadata.
+ *
+ * @param eventSourceObjectName the object name of the event source mbean.
+ * @param metadata the jmx metadata of the corresponding mbean.
+ */
+ WSDMArtifactsDirector(ObjectName eventSourceObjectName, MBeanInfo metadata)
+ {
+ this._eventSourceObjectName = eventSourceObjectName;
+ this._metadata = metadata;
+
+ _wsdlBuilder = new WsdlBuilder();
+ _capabilityBuilder = new MBeanCapabilityBuilder();
+ _rmdBuilder = new RmdBuilder();
+ }
+
+ /**
+ * Starts the build process of this director.
+ * This method acts as a facade of the whole build process.
+ *
+ * @throws BuilderException when one step of the build process fails.
+ */
+ void direct() throws BuilderException
+ {
+ processObjectName();
+ processAttributes();
+ endAttributes();
+ processOperations();
+ endOperations();
+ }
+
+ /**
+ * Notifiies builder that all the operations metadata have been transmitted.
+ *
+ * @throws BuilderException when one builder raises an exception during this operation.
+ */
+ private void endOperations() throws BuilderException
+ {
+ _capabilityBuilder.endOperations();
+ _wsdlBuilder.endOperations();
+ _rmdBuilder.endOperations();
+ }
+
+ /**
+ * Notifiies builder that all the attributes metadata have been transmitted.
+ *
+ * @throws BuilderException when one builder raises an exception during this operation.
+ */
+ private void endAttributes() throws BuilderException
+ {
+ _capabilityBuilder.endAttributes();
+ _wsdlBuilder.endAttributes();
+ _rmdBuilder.endAttributes();
+ }
+
+ /**
+ * Injects event source object name on all builders.
+ *
+ * @throws BuilderException when one builder raises an exception during this operation.
+ */
+ void processObjectName() throws BuilderException
+ {
+ _capabilityBuilder.begin(_eventSourceObjectName);
+ _wsdlBuilder.begin(_eventSourceObjectName);
+ _rmdBuilder.begin(_eventSourceObjectName);
+ }
+
+ /**
+ * Injects attributes metadata on all builders.
+ *
+ * @throws BuilderException when one builder raises an exception during this operation.
+ */
+ void processAttributes() throws BuilderException
+ {
+ for (MBeanAttributeInfo attribute : _metadata.getAttributes())
+ {
+ _capabilityBuilder.onAttribute(attribute);
+ _wsdlBuilder.onAttribute(attribute);
+ _rmdBuilder.onAttribute(attribute);
+ }
+ }
+
+ /**
+ * Injects operations metadata on all builders.
+ *
+ * @throws BuilderException when one builder raises an exception during this operation.
+ */
+ void processOperations() throws BuilderException
+ {
+ for (MBeanOperationInfo operation : _metadata.getOperations())
+ {
+ _capabilityBuilder.onOperation(operation);
+ _wsdlBuilder.onOperation(operation);
+ }
+ }
+
+ /**
+ * Returns the capabilty class.
+ *
+ * @return the capability class.
+ */
+ Class<MBeanCapability> getCapabilityClass()
+ {
+ return _capabilityBuilder.getCapabilityClass();
+ }
+
+ /**
+ * Returns the wsdl.
+ *
+ * @return the wsdl.
+ */
+ Document getWsdl()
+ {
+ return _wsdlBuilder.getWsdl();
+ }
+
+ /**
+ * Returns the resource metadata descriptor containing metadata (rules, constraints, etc)
+ * for the current resource.
+ * The returned object is an array of Element and each of them maps a resource property.
+ *
+ * @return the resource metadata descriptor (as an array of Element).
+ */
+ Element [] getResourceMetadataDescriptor()
+ {
+ return _rmdBuilder.getResourceMetadataDescriptor();
+ }
+
+ /**
+ * Injects the environment on this director.
+ *
+ * @param environment the QMan environment.
+ */
+ void setEnvironment(Environment environment)
+ {
+ _wsdlBuilder.setEnvironment(environment);
+ _capabilityBuilder.setEnvironment(environment);
+ _rmdBuilder.setEnvironment(environment);
+ }
+
+ /**
+ * Injectcs the ws resource on this director.
+ *
+ * @param resource the ws resource.
+ */
+ public void setResource(Resource resource)
+ {
+ _wsdlBuilder.setWsdlPath(resource.getWsdlPath());
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifacts.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifacts.java
new file mode 100644
index 0000000000..ac4636b9c9
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifacts.java
@@ -0,0 +1,93 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.capabilities;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Web Service Artifacts.
+ * Basically it acts as a container for all artifacts built when a new WS-Resource is created.
+ * With WS artifacts we mean :
+ *
+ * <ul>
+ * <li>Capability class (which encapsulate the WS-DM capability concern)</li>
+ * <li>WS Resource Metadata Descriptor (RMD)</li>
+ * <li>Web Service Description (WSDL)</li>
+ * </ul>
+ *
+ * @author Andrea Gazzarini
+ */
+class WsArtifacts {
+
+ private final Class<MBeanCapability>_capabilityClass;
+ private final Element[] _resourceMetadataDescriptor;
+ private final Document _wsdl;
+
+ /**
+ * Builds a new artifacts container with the given artifacts.
+ *
+ * @param capabilityClass the capability class.
+ * @param resourceMetadataDescriptor the resource metadata descriptor.
+ * @param wsdl the wsdl.
+ */
+ public WsArtifacts(
+ Class<MBeanCapability> capabilityClass,
+ Element[] resourceMetadataDescriptor,
+ Document wsdl)
+ {
+ this._capabilityClass = capabilityClass;
+ this._resourceMetadataDescriptor = resourceMetadataDescriptor;
+ this._wsdl = wsdl;
+ }
+
+ /**
+ * Returns the capability class.
+ *
+ * @return the capability class.
+ */
+ Class<MBeanCapability> getCapabilityClass()
+ {
+ return _capabilityClass;
+ }
+
+ /**
+ * Returns the resource metadata descriptor.
+ * It is not a whole document but each property metadata is described in a
+ * separated element so the returned object is an array of elements.
+ *
+ * @return the resource metadata descriptor.
+ */
+ Element[] getResourceMetadataDescriptor()
+ {
+ return _resourceMetadataDescriptor;
+ }
+
+ /**
+ * Returns the web service description.
+ *
+ * @return the web service description (WSDL).
+ */
+ Document getWsdl()
+ {
+ return _wsdl;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java
new file mode 100644
index 0000000000..94505d28f7
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.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.management.wsdm.capabilities;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.muse.core.Environment;
+import org.apache.muse.core.Resource;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Manager for all WS-* related artifacts.
+ * Basically it is a factory ehnanced with a _cache mechanism so each created resource
+ * (WSDL, capability class, descriptor) is created and its reference is returned when requested
+ * again.
+ *
+ * @author Andrea Gazzarini
+ */
+class WsArtifactsFactory
+{
+ private final static Logger LOGGER = Logger.get(WsArtifactsFactory.class);
+
+ private final MBeanServer _mxServer;
+ private final Environment _environment;
+ private Map<ObjectName, WsArtifacts> _cache;
+
+ /**
+ * Builds a new factory with the given environment and mbean server.
+ *
+ * @param environment the builder environment.
+ * @param mxServer the management server.
+ */
+ public WsArtifactsFactory(Environment environment, MBeanServer mxServer)
+ {
+ this._environment = environment;
+ this._mxServer = mxServer;
+ this._cache = new HashMap<ObjectName, WsArtifacts>();
+ }
+
+ /**
+ * Returns the WS artifacts corresponding with the given resource.
+ *
+ * @param resource the WS resource.
+ * @param objectName the resource identifier (name).
+ * @return the WS artifacts corresponding with the given resource.
+ * @throws ArtifactsNotAvailableException when some problem occurs during artifacts generation.
+ */
+ @SuppressWarnings("unchecked")
+ WsArtifacts getArtifactsFor(Resource resource, ObjectName objectName) throws ArtifactsNotAvailableException
+ {
+ WsArtifacts result = null;
+ try
+ {
+ Hashtable<String, String> keyProperties = objectName.getKeyPropertyList();
+ keyProperties.remove(Names.NAME_ATTRIBUTE);
+ keyProperties.remove(Names.OBJECT_ID);
+
+ ObjectName searchKey = ObjectName.getInstance(objectName.getDomain(),keyProperties);
+
+ LOGGER.debug(
+ Messages.QMAN_200041_INCOMING_OBJECT_NAME_AND_DERIVED_KEY,
+ objectName,
+ searchKey);
+
+ result = _cache.get(searchKey);
+ if (result == null)
+ {
+ MBeanInfo metadata = _mxServer.getMBeanInfo(objectName);
+
+ WSDMArtifactsDirector director = new WSDMArtifactsDirector(objectName,metadata);
+ director.setEnvironment(_environment);
+ director.setResource(resource);
+ director.direct();
+
+ result = new WsArtifacts(
+ director.getCapabilityClass(),
+ director.getResourceMetadataDescriptor(),
+ director.getWsdl());
+
+ _cache.put(searchKey, result);
+
+ LOGGER.debug(
+ Messages.QMAN_200040_WS_ARTIFACTS_CACHED,
+ searchKey);
+ }
+
+ return result;
+ } catch(Exception exception)
+ {
+ throw new ArtifactsNotAvailableException(
+ result,
+ exception,
+ objectName);
+ }
+ }
+
+ /**
+ * Utility method for create concrete instance of the given capability class.
+ *
+ * @param capabilityClass the capability class.
+ * @param objectName the object name that will act as the target for this capability invocations.
+ * @return an initialized instance of the given capability class.
+ * @throws InstantiationException when the class cannot be instantiated.
+ * @throws IllegalAccessException when this method does not have access to
+ * the definition of the capability class.
+ */
+ MBeanCapability createCapability(Class<MBeanCapability> capabilityClass, ObjectName objectName)
+ throws InstantiationException, IllegalAccessException
+ {
+ MBeanCapability capability = capabilityClass.newInstance();
+ capability.setResourceObjectName(objectName);
+ return capability;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java
new file mode 100644
index 0000000000..6bfccda1ce
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java
@@ -0,0 +1,460 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.capabilities;
+
+import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.ObjectName;
+import javax.xml.transform.TransformerException;
+
+import org.apache.muse.core.Environment;
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.muse.util.ReflectUtils;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.wsdl.WsdlUtils;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.wsdm.muse.engine.WSDMAdapterEnvironment;
+import org.apache.qpid.management.wsdm.muse.serializer.ObjectSerializer;
+import org.apache.qpid.qman.debug.WsdlDebugger;
+import org.apache.qpid.transport.util.Logger;
+import org.apache.xpath.XPathAPI;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+/**
+ * TO BE IMPROVED USING JAXB!!
+ *
+ * @author Andrea Gazzarini
+ */
+class WsdlBuilder implements IArtifactBuilder,Constants {
+
+ private final static Logger LOGGER = Logger.get(WsdlBuilder.class);
+
+ private WSDMAdapterEnvironment _environment;
+ private Document _document;
+ private Element schema;
+ private Element _wsrpProperties;
+ private ObjectSerializer _serializer;
+ private ObjectName _objectName;
+ private Map<String, String> arrayTypesAlreadyDeclared = new HashMap<String, String>();
+
+ private Element _arrayComplexType;
+ private Element _nestedArrayType;
+
+ /**
+ * For each attibute the corresponding xml type definition must be inserted on the QMan
+ * schema related section.
+ * After that, a reference to that definition must be declared on the wsrp element .
+ *
+ * @param attributeMetadata the attribute metadata.
+ * @throws BuilderException only if this builder wasn't able to get a reference (via XPath)
+ * to QMan schema section.
+ */
+ public void onAttribute(MBeanAttributeInfo attributeMetadata) throws BuilderException
+ {
+ try
+ {
+ String attributeName = attributeMetadata.getName();
+ schema.appendChild(defineSchemaFor(attributeMetadata.getType(), attributeName));
+
+ Element propertyRef= XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ propertyRef.setAttribute(MIN_OCCURS, "0");
+ propertyRef.setAttribute(
+ REF_ATTRIBUTE,
+ Names.PREFIX+":"+attributeName);
+
+ _wsrpProperties.appendChild(propertyRef);
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private Element defineSchemaFor(String type, String attributeName) throws Exception
+ {
+ Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ String xmlType = null;
+ if (type.equals(Map.class.getName()))
+ {
+ xmlType="qman:map";
+ } else if (UUID.class.getName().equals(type))
+ {
+ xmlType = "qman:uuid";
+ } else if (type.startsWith("["))
+ {
+ Class arrayClass = Class.forName(type);
+ Class clazz = ReflectUtils.getClassFromArrayClass(arrayClass);
+ String arrayType = arrayClass.getSimpleName().replace("[]", "").trim();
+ arrayType = Character.toUpperCase(arrayType.charAt(0))+arrayType.substring(1);
+ if (!arrayTypesAlreadyDeclared.containsKey(type))
+ {
+ _arrayComplexType.setAttribute(NAME_ATTRIBUTE, "arrayOf"+arrayType);
+ _nestedArrayType.setAttribute(TYPE_ATTRIBUTE, _serializer.getXmlType(clazz));
+ schema.appendChild(_arrayComplexType);
+ arrayTypesAlreadyDeclared.put(type, arrayType);
+ }
+ xmlType = "qman:arrayOf"+arrayTypesAlreadyDeclared.get(type);
+ }
+ else
+ {
+ xmlType = _serializer.getXmlType(Class.forName(type));
+ }
+ propertyDeclaration.setAttribute(NAME_ATTRIBUTE,attributeName);
+ propertyDeclaration.setAttribute(TYPE_ATTRIBUTE, xmlType);
+ return propertyDeclaration;
+ }
+
+ /**
+ * Initializes this builder.
+ *
+ * @param objectName the name of the current JMX entity.
+ * @throws BuilderException when it's not possible to proceed with the initialization.
+ */
+ public void begin(ObjectName objectName) throws BuilderException
+ {
+ this._objectName = objectName;
+ this._serializer = (ObjectSerializer) SerializerRegistry.getInstance().getSerializer(Object.class);
+
+ createWsrpPropertiesElement();
+
+ createReusableArrayComplextType();
+
+ replaceDummyServiceLocationOnWsdl();
+
+ createSchemaElement();
+ }
+
+ public void onOperation(MBeanOperationInfo operationMetadata) throws BuilderException
+ {
+ // SCHEMA SECTION
+ /*
+ <xs:element name='purgeRequest' type='qman:purgeRequest' />
+
+ <xs:element name='purgeResponse' type='qman:purgeResponse' />
+
+ <xs:complexType name='purgeRequest'>
+ <xs:sequence>
+ <xs:element name='arg0' type='xs:int' />
+ <xs:element minOccurs='0' name='arg1' type='qman:hashMap' />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name='hashMap'>
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs='unbounded' minOccurs='0' name='entry'>
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs='0' name='key' type='xs:string'/>
+ <xs:element minOccurs='0' name='value' type='xs:anyType'/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:complexType name='purgeResponse'>
+ <xs:sequence />
+ </xs:complexType>
+ */
+
+ try
+ {
+ // <xsd:element xmlns="" name="purgeRequest" type="qman:purgeRequest"/>
+
+ Element methodRequestElement= _document.createElement("xsd:element");
+ String methodNameRequest = operationMetadata.getName()+"Request";
+ methodRequestElement.setAttribute("name", methodNameRequest);
+ methodRequestElement.setAttribute("type", "qman:"+methodNameRequest);
+
+ // <xs:element name='purgeResponse' type='qman:purgeResponse' />
+// Element methodResponseElement= _document.createElement("xsd:element");
+ String methodNameResponse= operationMetadata.getName()+"Response";
+// methodResponseElement.setAttribute("name", methodNameResponse);
+// methodResponseElement.setAttribute("type", "qman:result");//+methodNameResponse);
+
+ schema.appendChild(methodRequestElement);
+// schema.appendChild(methodResponseElement);
+
+ /*
+ <xs:complexType name='purgeRequest'>
+ <xs:sequence>
+ <xs:element name='arg0' type='xs:int' />
+ <xs:element minOccurs='0' name='arg1' type='qman:hashMap' />
+ </xs:sequence>
+ </xs:complexType>
+
+ */
+
+ Element methodNameRequestComplexType = _document.createElement("xsd:complexType");
+ methodNameRequestComplexType.setAttribute("name", methodNameRequest);
+ Element methodNameRequestComplexTypeSequence = _document.createElement("xsd:sequence");
+
+ for(MBeanParameterInfo parameter : operationMetadata.getSignature())
+ {
+ methodNameRequestComplexTypeSequence.appendChild(defineSchemaFor(parameter.getType(), parameter.getName()));
+ }
+
+ methodNameRequestComplexType.appendChild(methodNameRequestComplexTypeSequence);
+ schema.appendChild(methodNameRequestComplexType);
+
+ /*
+ <message name="purgeResponseMessage">
+ <part element='qman:purgeResponse' name='purgeResponse'></part>
+ </message>
+
+ <message name='purgeRequestMessage'>
+ <part element="qman:purgeRequest" name='purgeRequest'></part>
+ </message>
+ */
+ Element definitions = (Element) XPathAPI.selectSingleNode(_document, "/wsdl:definitions");
+
+ String requestMessageName = methodNameRequest+"Message";
+ String responseMessageName = methodNameResponse+"Message";
+
+ Element requestMessage = _document.createElement("message");
+ requestMessage.setAttribute("name", requestMessageName);
+ Element requestPart = _document.createElement("wsdl:part");
+ requestPart.setAttribute("element", "qman:"+methodNameRequest);
+ requestPart.setAttribute("name", methodNameRequest);
+ requestMessage.appendChild(requestPart);
+
+ Element responseMessage = _document.createElement("wsdl:message");
+ responseMessage.setAttribute("name", responseMessageName);
+ Element responsePart = _document.createElement("wsdl:part");
+ responsePart.setAttribute("element", "qman:result");//+methodNameResponse);
+ responsePart.setAttribute("name", methodNameResponse);
+ responseMessage.appendChild(responsePart);
+
+ definitions.appendChild(requestMessage);
+ definitions.appendChild(responseMessage);
+
+
+ /*
+ <operation name='purge'>
+ <input message="qman:purgeRequestMessage">
+ </input>
+ <output message='qman:purgeResponseMessage'>
+ </output>
+ </operation>
+ */
+ Element portType = (Element) XPathAPI.selectSingleNode(_document, "/wsdl:definitions/wsdl:portType");
+ Element operation = _document.createElement("wsdl:operation");
+ operation.setAttribute("name", operationMetadata.getName());
+
+ Element input = _document.createElement("wsdl:input");
+ input.setAttribute("message", "qman:"+requestMessageName);
+ input.setAttribute("name", methodNameRequest);
+ input.setAttribute("wsa:action", Names.NAMESPACE_URI+"/"+operationMetadata.getName());
+
+ //name="SetResourcePropertiesRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesRequest"/>
+
+ operation.appendChild(input);
+
+ Element output = _document.createElement("wsdl:output");
+ output.setAttribute("message", "qman:"+responseMessageName);
+ output.setAttribute("name", methodNameResponse);
+ output.setAttribute("wsa:action", Names.NAMESPACE_URI+"/"+methodNameResponse);
+
+ operation.appendChild(output);
+
+ portType.appendChild(operation);
+
+ /*
+ <operation name='purge'>
+ <soap:operation soapAction='purge' />
+ <input>
+ <soap:body use='literal' />
+ </input>
+ <output>
+ <soap:body use='literal' />
+ </output>
+ </operation>
+ */
+ Element binding = (Element) XPathAPI.selectSingleNode(_document, "/wsdl:definitions/wsdl:binding");
+ Element bindingOperation = _document.createElement("wsdl:operation");
+ bindingOperation.setAttribute("name", operationMetadata.getName());
+
+ Element soapOperation = _document.createElement("wsdl-soap:operation");
+ soapOperation.setAttribute("soapAction", Names.NAMESPACE_URI+"/"+operationMetadata.getName());
+
+ Element bindingInput = _document.createElement("wsdl:input");
+ Element bodyIn = _document.createElement("wsdl-soap:body");
+ bodyIn.setAttribute("use", "literal");
+
+ Element bindingOutput = _document.createElement("wsdl:output");
+ Element bodyOut = _document.createElement("wsdl-soap:body");
+ bodyOut.setAttribute("use", "literal");
+
+ bindingOutput.appendChild(bodyOut);
+ bindingInput.appendChild(bodyIn);
+
+ bindingOperation.appendChild(soapOperation);
+ bindingOperation.appendChild(bindingInput);
+ bindingOperation.appendChild(bindingOutput);
+
+ binding.appendChild(bindingOperation);
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+
+ /**
+ * Director callback : all attributes have been notified.
+ * Nothing to do here.
+ */
+ public void endAttributes()
+ {
+ // N.A.
+ }
+
+ /**
+ * Director callback : all operations have been notified.
+ * Nothing to do here.
+ */
+ public void endOperations()
+ {
+ // N.A.
+ }
+
+ /**
+ * Returns the WSDL built by this builder.
+ *
+ * @return the WSDL built by this builder.
+ */
+ public Document getWsdl()
+ {
+ WsdlDebugger.debug(_objectName,_document);
+ return _document;
+ }
+
+ /**
+ * Injects the application context environment
+ * on this builder.
+ *
+ * @param environment the application context environment.
+ */
+ public void setEnvironment(Environment environment)
+ {
+ this._environment = (WSDMAdapterEnvironment)environment;
+ }
+
+ /**
+ * Injects the path of the wsdl document.
+ *
+ * @param wsdlPath the path of the wsdl document.
+ */
+ public void setWsdlPath(String wsdlPath)
+ {
+ _document = WsdlUtils.createWSDL(_environment, wsdlPath, true);
+ }
+
+ /**
+ * Create a reference to the WSRP properties element.
+ *
+ * @throws BuilderException in case of XPath evaluation problem.
+ */
+ private void createWsrpPropertiesElement() throws BuilderException
+ {
+ try
+ {
+ _wsrpProperties = (Element) XPathAPI.selectSingleNode(
+ _document,
+ WSRP_PROPERTIES_XPATH);
+ } catch (TransformerException exception)
+ {
+ LOGGER.error(Messages.QMAN_100040_UNABLE_TO_LOCATE_WSRP_PROPERTIES);
+ throw new BuilderException(exception);
+ }
+ }
+
+ /**
+ * Creates a template element that will be used for array
+ * type schema declaration(s).
+ */
+ private void createReusableArrayComplextType()
+ {
+ _arrayComplexType = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
+ Element sequence = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
+ _nestedArrayType = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ _nestedArrayType.setAttribute(NAME_ATTRIBUTE, "entry");
+ sequence.appendChild(_nestedArrayType);
+ _arrayComplexType.appendChild(sequence);
+ }
+
+ private void createSchemaElement() throws BuilderException
+ {
+ try
+ {
+ schema = (Element) XPathAPI.selectSingleNode(
+ _document.getDocumentElement(),
+ QMAN_SCHEMA_XPATH);
+ } catch(Exception exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100034_WSDL_SCHEMA_SECTION_NOT_FOUND);
+ throw new BuilderException(exception);
+ }
+ }
+
+ /**
+ * The template WSDL contains a dummy URL as service location that
+ * needs to be replaced with the real service address.
+ *
+ * @throws BuilderException when replacement fails (XPath problem).
+ */
+ private void replaceDummyServiceLocationOnWsdl() throws BuilderException
+ {
+ try
+ {
+ Attr location = (Attr) XPathAPI.selectSingleNode(
+ _document,
+ SERVICE_LOCATION_XPATH);
+
+ StringBuilder builder = new StringBuilder("http://")
+ .append(InetAddress.getLocalHost().getHostName())
+ .append(':')
+ .append(System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME,"8080"))
+ .append('/')
+ .append(_environment.getContextPath())
+ .append('/')
+ .append("services/QManWsResource");
+ location.setValue(builder.toString());
+ } catch(Exception exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100026_SOAP_ADDRESS_REPLACEMENT_FAILURE);
+ throw new BuilderException(exception);
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java
new file mode 100644
index 0000000000..116d74727a
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java
@@ -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.
+ *
+ */
+package org.apache.qpid.management.wsdm.common;
+
+import javax.management.ObjectName;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.qpid.management.Names;
+
+/**
+ * Thrown when some operation has been requested on an entity and the entity hasn't been found
+ * on the managed domain.
+ *
+ * @author Andrea Gazzarini
+ */
+public class EntityInstanceNotFoundFault extends QManFault
+{
+ private static final long serialVersionUID = -3772811863214553615L;
+
+ private final static QName EXCEPTION_QNAME = new QName(
+ Names.NAMESPACE_URI,
+ "EntityInstanceNotFoundFault",
+ Names.PREFIX);
+
+ /**
+ * Builds a new exception with the given endpoint reference and the object name of the entity
+ * that wasn't found.
+ *
+ * @param endpointReference the origin endpoint reference of this exception.
+ * @param targetEntityName the object name of the not found entity.
+ */
+ public EntityInstanceNotFoundFault(EndpointReference endpointReference, ObjectName targetEntityName)
+ {
+ super(
+ endpointReference,
+ EXCEPTION_QNAME,
+ targetEntityName.getCanonicalName());
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/MethodInvocationFault.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/MethodInvocationFault.java
new file mode 100644
index 0000000000..f24c2bfd46
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/MethodInvocationFault.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.management.wsdm.common;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * This is the exception encapsulating the fault that will be thrown in case of
+ * method invocation failure.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MethodInvocationFault extends QManFault
+{
+ private static final long serialVersionUID = 5977379710882983474L;
+
+ private String _message;
+ private long _returnCode;
+
+ /**
+ * Builds a new exception with the given endpoint reference and method invocation exception.
+ * This constructor will be used when the invocation thrown the MethodInvocationException.
+ *
+ * @param endpointReference the endpoint reference.
+ * @param methodName the name of the method.
+ * @param message the explanatio message.
+ * @param returnCode the a mnemonic code associated with the failure.
+ */
+ public MethodInvocationFault(
+ EndpointReference endpointReference,
+ String methodName,
+ String message,
+ long returnCode)
+ {
+ super(
+ endpointReference,
+ new QName(
+ Names.NAMESPACE_URI,
+ "OperationInvocationFault",
+ Names.PREFIX),
+ String.format("OPERATION \"%s\" FAILURE. See detail section for further details.",methodName));
+ this._message = message;
+ this._returnCode = returnCode;
+ }
+
+ @Override
+ public Element getDetail()
+ {
+ Element detail = super.getDetail();
+ Document owner = detail.getOwnerDocument();
+ detail.appendChild(XmlUtils.createElement(owner, Names.QMAN_STATUS_TEXT_NAME,_message));
+ detail.appendChild(XmlUtils.createElement(owner, Names.QMAN_STATUS_CODE_NAME,_returnCode));
+ return detail;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/NoSuchAttributeFault.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/NoSuchAttributeFault.java
new file mode 100644
index 0000000000..e9f37f8afb
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/NoSuchAttributeFault.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.management.wsdm.common;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * This is the exception encapsulating the fault that will be thrown when a requested
+ * attribute is not found on the target ws resource.
+ *
+ * @author Andrea Gazzarini
+ */
+public class NoSuchAttributeFault extends QManFault
+{
+ private static final long serialVersionUID = 5977379710882983474L;
+
+ private String _attributeName;
+
+ /**
+ * Builds a new exception with the given endpoint reference, JMX object name
+ * and attribute that hasn't been found.
+ *
+ * @param endpointReference the endpoint reference.
+ * @param attributeName the name of the attribute that hasn't been found.
+ */
+ public NoSuchAttributeFault(EndpointReference endpointReference, String attributeName)
+ {
+ super(
+ endpointReference,
+ new QName(
+ Names.NAMESPACE_URI,
+ "NoSuchAttributeFault",
+ Names.PREFIX),
+ "Attribute not found on this WS-Resource.");
+ _attributeName = attributeName;
+ }
+
+ @Override
+ public Element getDetail()
+ {
+ Element detail = super.getDetail();
+ Document owner = detail.getOwnerDocument();
+ detail.appendChild(XmlUtils.createElement(owner, Names.QMAN_STATUS_ATTRIBUTE_NAME,_attributeName));
+ return detail;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ObjectNameIdFactory.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ObjectNameIdFactory.java
new file mode 100644
index 0000000000..eb7eee9547
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ObjectNameIdFactory.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.management.wsdm.common;
+
+import javax.management.ObjectName;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.routing.ResourceIdFactory;
+import org.apache.qpid.management.Names;
+
+/**
+ * ResourceIdFactory implementation that is using an objectName as
+ * resource identifier.
+ * This is done in order to make a relationship between an MBean (which is part of the
+ * JMX core domain model) and a WS-Resource (the same entity as is represented on WS-DM adapter side).
+ *
+ * @author Andrea Gazzarini
+ */
+public class ObjectNameIdFactory implements ResourceIdFactory
+{
+ /**
+ * Returns the name of the identifier element.
+ *
+ * @return the name of the identifier element.
+ */
+ public QName getIdentifierName()
+ {
+ return Names.RESOURCE_ID_QNAME;
+ }
+
+ /**
+ * Returns the object name used as a resource identifier.
+ * Developer note : this factory is highly coupled with ThreadSessionManager stuff because
+ * the object name that will be used as identifier is supposed to be in the thread session.
+ *
+ * @return the object name used as a resource identifier.
+ */
+ public String getNextIdentifier()
+ {
+ ObjectName objectName = ThreadSessionManager.getInstance().getSession().getObjectName();
+ return objectName.getKeyProperty(Names.OBJECT_ID);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManFault.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManFault.java
new file mode 100644
index 0000000000..0a52c2ba65
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManFault.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.management.wsdm.common;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.basefaults.BaseFault;
+import org.apache.qpid.management.Names;
+
+/**
+ * Base class for QMan thrown faults.
+ * This should be thrown to denote a situation where a not-well cause could be determined.
+ */
+public class QManFault extends BaseFault
+{
+ private static final long serialVersionUID = 5977379710882983474L;
+ private final static QName SERVICE = new QName(
+ Names.NAMESPACE_URI,
+ "QMan",
+ Names.PREFIX);
+
+ private final static QName EXCEPTION_QNAME = new QName(
+ Names.NAMESPACE_URI,
+ "QManFault",
+ Names.PREFIX);
+
+ /**
+ * Builds a new exception with the given endpoint reference and the exception cause.
+ *
+ * @param endpointReference the endpoint reference.
+ * @param cause the exception cause.
+ */
+ public QManFault(EndpointReference endpointReference, Exception cause)
+ {
+ super(EXCEPTION_QNAME,cause.getMessage());
+ setCode(SERVICE);
+ setOriginReference(endpointReference);
+ }
+
+ /**
+ * Builds a new exception with the given endpoint reference, qname and detail message.
+ *
+ * @param endpointReference the endpoint reference.
+ * @param qname the qname of this exception.
+ * @param message the detail message of this exception.
+ */
+ public QManFault(EndpointReference endpointReference, QName qname, String message)
+ {
+ super(qname,message);
+ setOriginReference(endpointReference);
+ setCode(SERVICE);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManResourceIdFactory.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManResourceIdFactory.java
new file mode 100644
index 0000000000..1a34971c6a
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManResourceIdFactory.java
@@ -0,0 +1,57 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.common;
+
+import java.util.UUID;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.routing.ResourceIdFactory;
+import org.apache.qpid.management.Names;
+
+/**
+ * A simple implementation of resource id factory that uses a UUID as resource
+ * identifier.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QManResourceIdFactory implements ResourceIdFactory
+{
+ /**
+ * Returns the identifier name for id element.
+ *
+ * @return the identifier name for id element.
+ */
+ public QName getIdentifierName()
+ {
+ return Names.RESOURCE_ID_QNAME;
+ }
+
+ /**
+ * Returns the next valid identifier.
+ *
+ * @return the next valid identifier.
+ */
+ public String getNextIdentifier()
+ {
+ return UUID.randomUUID().toString();
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java
new file mode 100644
index 0000000000..588879b951
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java
@@ -0,0 +1,105 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.common;
+
+import javax.management.ObjectName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Thread-scoped session.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ThreadSession
+{
+ private ObjectName _objectName;
+ private Document _wsdl;
+ private Element [] _wsrmdProperties;
+
+ /**
+ * Empty constructor.
+ */
+ ThreadSession()
+ {
+ }
+
+ /**
+ * Gets the object name associated with this thread session.
+ *
+ * @return the object name associated with this thread session.
+ */
+ public ObjectName getObjectName()
+ {
+ return _objectName;
+ }
+
+ /**
+ * Sets the object name on this thread session.
+ *
+ * @param the object name of this thread session..
+ */
+ public void setObjectName(ObjectName objectName)
+ {
+ this._objectName = objectName;
+ }
+
+ /**
+ * Sets the WSDL document on this thread session.
+ *
+ * @param the WSDL document of this thread session..
+ */
+ public void setWsdlDocument(Document wsdlDoc)
+ {
+ this._wsdl = wsdlDoc;
+ }
+
+ /**
+ * Gets the WSDL document associated with this thread session.
+ *
+ * @return the WSDL document associated with this thread session.
+ */
+ public Document getWsdlDocument()
+ {
+ return _wsdl;
+ }
+
+ /**
+ * Gets the RDM elements associated with this thread session.
+ *
+ * @return the RDM elements associated with this thread session.
+ */
+ public Element[] getResourceMetadataDescriptor()
+ {
+ return _wsrmdProperties;
+ }
+
+ /**
+ * Sets the WSDL elements on this thread session.
+ *
+ * @param the WSDL elements of this thread session..
+ */
+ public void setResourceMetadataDescriptor(Element[] rmd)
+ {
+ this._wsrmdProperties = rmd;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSessionManager.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSessionManager.java
new file mode 100644
index 0000000000..6a081bfec4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSessionManager.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.management.wsdm.common;
+
+/**
+ * Thread session manager used to handle thread-scoped sessions.
+ *
+ * @author Andrea Gazzarini
+ */
+public final class ThreadSessionManager
+{
+ private static ThreadSessionManager instance = new ThreadSessionManager();
+
+ private ThreadLocal<ThreadSession> sessions;
+
+ /**
+ * Builds and initializes a new manager.
+ */
+ private ThreadSessionManager()
+ {
+ this.sessions = new ThreadLocal<ThreadSession>();
+ }
+
+ /**
+ * Returns the singleton instance of this manager.
+ *
+ * @return the singleton instance of this manager.
+ */
+ public static ThreadSessionManager getInstance()
+ {
+ return instance;
+ }
+
+ /**
+ * Returns (or create and returns) the session associated with the
+ * current thread.
+ *
+ * @return the thread session.
+ */
+ public ThreadSession getSession()
+ {
+ ThreadSession session = (ThreadSession) sessions.get();
+ if (session == null)
+ {
+ session = new ThreadSession();
+ sessions.set(session);
+ }
+ return session;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/UnableToConnectWithBrokerFault.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/UnableToConnectWithBrokerFault.java
new file mode 100644
index 0000000000..55365b4051
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/UnableToConnectWithBrokerFault.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.management.wsdm.common;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * This is the exception encapsulating the fault that will be thrown in case of
+ * broker connection failure.
+ *
+ * @author Andrea Gazzarini
+ */
+public class UnableToConnectWithBrokerFault extends QManFault
+{
+ private static final long serialVersionUID = 5977379710882983474L;
+
+ private String _host;
+ private int _port;
+ private String _username;
+ private String _virtualHostName;
+
+ /**
+ * Builds a new exception with the given endpoint reference and connection data.
+ *
+ * @param host the requested qpid host.
+ * @param port the requested qpid port.
+ * @param username the username used for estabilishing connection.
+ * @param virtualHostName the name of the target virtual host..
+ */
+ public UnableToConnectWithBrokerFault(
+ EndpointReference endpointReference,
+ String host,
+ int port,
+ String username,
+ String virtualHostName,
+ String message)
+ {
+ super(
+ endpointReference,
+ new QName(
+ Names.NAMESPACE_URI,
+ "UnableToConnectFault",
+ Names.PREFIX),
+ String.format("Unable to connect with the requested broker. Underlying exception message was %s",message));
+ this._host = host;
+ this._port = port;
+ this._username = username;
+ this._virtualHostName = virtualHostName;
+ }
+
+ @Override
+ public Element getDetail()
+ {
+ Element detail = super.getDetail();
+ Document owner = detail.getOwnerDocument();
+ detail.appendChild(XmlUtils.createElement(owner, Names.HOST_QNAME,_host));
+ detail.appendChild(XmlUtils.createElement(owner, Names.PORT_QNAME,_port));
+ detail.appendChild(XmlUtils.createElement(owner, Names.USERNAME_QNAME,_username));
+ detail.appendChild(XmlUtils.createElement(owner, Names.VIRTUAL_HOST_QNAME,_virtualHostName));
+ return detail;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java
new file mode 100644
index 0000000000..e4d0f25adc
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java
@@ -0,0 +1,118 @@
+package org.apache.qpid.management.wsdm.muse.engine;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+
+import java.io.File;
+import java.net.URI;
+
+import javax.servlet.ServletContext;
+
+import org.apache.muse.core.AbstractEnvironment;
+import org.apache.muse.util.FileUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * QMan Adapter enviroment implementation.
+ *
+ * @author Andrea Gazzarini
+ */
+public class WSDMAdapterEnvironment extends AbstractEnvironment
+{
+ private final static Logger LOGGER = Logger.get(WSDMAdapterEnvironment.class);
+ private final File _realDirectory;
+ private final ServletContext _servletContext;
+
+ /**
+ * Builds a new qman environment with the given application context.
+ *
+ * @param servletContext the application context.
+ */
+ public WSDMAdapterEnvironment(ServletContext servletContext)
+ {
+ this._servletContext = servletContext;
+ String realDirectoryPath = servletContext.getRealPath(Names.WEB_APP_CLASSES_FOLDER);
+
+ _realDirectory = (realDirectoryPath != null)
+ ? new File(realDirectoryPath)
+ : FileUtils.CURRENT_DIR;
+
+ String defaultURI = getDefaultURIPrefix()+"adapter";
+ setDefaultURI(defaultURI);
+
+ LOGGER.info(Messages.QMAN_000029_DEFAULT_URI, defaultURI);
+ }
+
+ /**
+ * Returns the endpoint created starting by this application default URI.
+ *
+ * @return the endpoint created starting by this application default URI.
+ */
+ public EndpointReference getDeploymentEPR()
+ {
+ return new EndpointReference(URI.create(getDefaultURI()));
+ }
+
+ /**
+ * Returns the application classes folder.
+ *
+ * @return the application classes folder.
+ */
+ public File getRealDirectory()
+ {
+ return _realDirectory;
+ }
+
+ /**
+ * Returns the default endpoint reference URI.
+ *
+ * @return the default endpoint reference URI.
+ */
+ public String getDefaultURIPrefix()
+ {
+ return new StringBuilder()
+ .append("http://")
+ .append(System.getProperty(
+ Names.ADAPTER_HOST_PROPERTY_NAME,
+ Protocol.DEFAULT_QMAN_HOSTNAME))
+ .append(":")
+ .append(System.getProperty(
+ Names.ADAPTER_PORT_PROPERTY_NAME,
+ String.valueOf(Protocol.DEFAULT_QMAN_PORT_NUMBER)))
+ .append(_servletContext.getContextPath())
+ .append("/services/")
+ .toString();
+ }
+
+ /**
+ * Returns the context path name of QMan application.
+ *
+ * @return the context path name of QMan application.
+ */
+ public String getContextPath()
+ {
+ return _servletContext.getContextPath();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterIsolationLayer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterIsolationLayer.java
new file mode 100644
index 0000000000..e9a74bf60c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterIsolationLayer.java
@@ -0,0 +1,57 @@
+package org.apache.qpid.management.wsdm.muse.engine;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+
+import javax.servlet.ServletContext;
+
+import org.apache.muse.core.Environment;
+import org.apache.muse.core.platform.mini.MiniIsolationLayer;
+
+/**
+ * QMan specific implementation of the Apache Muse isolation layer.
+ * If you are a Muse expert you were wondering why don't we use the muse default implementation...
+ * well,
+ *
+ * @author Andrea Gazzarini
+ */
+public class WSDMAdapterIsolationLayer extends MiniIsolationLayer
+{
+ /**
+ * Builds a new isolation layer with the given application context.
+ *
+ * @param initialContext the application context.
+ */
+ public WSDMAdapterIsolationLayer(ServletContext initialContext)
+ {
+ super(null, initialContext);
+ }
+
+ /**
+ * WSDMAdapterEnvironment factory method.
+ *
+ * @return the environment.
+ */
+ protected Environment createEnvironment()
+ {
+ return new WSDMAdapterEnvironment(getInitialContext());
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java
new file mode 100644
index 0000000000..c16c156b73
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java
@@ -0,0 +1,762 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.muse.resources;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.Capability;
+import org.apache.muse.core.Environment;
+import org.apache.muse.core.ResourceManager;
+import org.apache.muse.core.routing.MessageHandler;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.addressing.WsaConstants;
+import org.apache.muse.ws.addressing.soap.SoapConstants;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.addressing.soap.SoapUtils;
+import org.apache.muse.ws.resource.WsResource;
+import org.apache.muse.ws.resource.metadata.MetadataDescriptor;
+import org.apache.muse.ws.resource.metadata.WsrmdConstants;
+import org.apache.muse.ws.resource.metadata.impl.SimpleMetadataDescriptor;
+import org.apache.muse.ws.resource.metadata.impl.WsrmdUtils;
+import org.apache.muse.ws.resource.properties.ResourcePropertyCollection;
+import org.apache.muse.ws.resource.properties.impl.SimpleResourcePropertyCollection;
+import org.apache.muse.ws.resource.properties.impl.WsrpUtils;
+import org.apache.muse.ws.resource.properties.schema.ResourcePropertiesSchema;
+import org.apache.muse.ws.resource.properties.schema.impl.SimpleResourcePropertiesSchema;
+import org.apache.muse.ws.wsdl.WsdlUtils;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.wsdm.common.ThreadSessionManager;
+import org.apache.qpid.transport.util.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * QMan WS resource.
+ * We could say that this is a QMan manageable entity under the
+ * WS-DM perspective.
+ *
+ * @author Andrea Gazzarini
+ */
+@SuppressWarnings("unchecked")
+public class QManWsResource implements WsResource
+{
+ private final static Logger LOGGER = Logger.get(QManWsResource.class);
+
+ /**
+ * Internal state of this resource.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface State
+ {
+ /**
+ * Provides initialization of this resource.
+ *
+ * @throws SoapFault when the initialization fails.
+ */
+ void initialize() throws SoapFault;
+
+ /**
+ * Returns true if this resource has been initialized.
+ *
+ * @return true if this resource has been initialized.
+ */
+ boolean hasBeenInitialized();
+
+ /**
+ * Returns true if this resource has been shutdown.
+ *
+ * @return true if this resource has been shutdown.
+ */
+ boolean hasBeenShutdown();
+
+ /**
+ * Shuts down this resource.
+ *
+ * @throws SoapFault when the shutdown procedure fails.
+ */
+ void shutdown() throws SoapFault;
+ }
+
+ private final State _hasBeenShutdown = new State()
+ {
+ /**
+ * Return false because this resource has been shutdown so therefore
+ * initialization occurred.
+ *
+ * @return true;
+ */
+ public boolean hasBeenInitialized()
+ {
+ return true;
+ }
+
+ /**
+ * Returns true because this state indicates that resource has been shutdown.
+ *
+ * @return true.
+ */
+ public boolean hasBeenShutdown()
+ {
+ return true;
+ }
+
+ /**
+ * Since this resource has been shutdown the initialization
+ * cannot be performed again.
+ * As conseguence of that this method throws an exception.
+ *
+ * @throws SoapFault each time this method is called.
+ */
+ public void initialize() throws SoapFault
+ {
+ LOGGER.error(Messages.QMAN_100031_WS_RESOURCE_ALREADY_INITIALIZED);
+ throw new SoapFault(Messages.QMAN_100031_WS_RESOURCE_ALREADY_INITIALIZED);
+ }
+
+ public void shutdown() throws SoapFault
+ {
+ LOGGER.error(Messages.QMAN_100033_WS_RESOURCE_ALREADY_SHUTDOWN);
+ throw new SoapFault(Messages.QMAN_100033_WS_RESOURCE_ALREADY_SHUTDOWN);
+ }
+ };
+
+ private final State _hasBeenInitialized = new State()
+ {
+ /**
+ * Returns true because this is the state where a resource is when it
+ * has been initialized.
+ *
+ * @return true.
+ */
+ public boolean hasBeenInitialized()
+ {
+ return true;
+ }
+
+ /**
+ * Returns false because this resource has been initialized but no shutdown request
+ * has been received.
+ *
+ * @return false.
+ */
+ public boolean hasBeenShutdown()
+ {
+ return false;
+ }
+
+ /**
+ * A resource in this state cannot be initialized again so if this method is called an
+ * exception is thrown.
+ *
+ * @throws SoapFault each time this method is called.
+ */
+ public void initialize() throws SoapFault
+ {
+ LOGGER.error(Messages.QMAN_100031_WS_RESOURCE_ALREADY_INITIALIZED);
+ throw new SoapFault(Messages.QMAN_100031_WS_RESOURCE_ALREADY_INITIALIZED);
+ }
+
+ /**
+ * Shuts down this resource.
+ *
+ * @throws SoapFault when the shutdown procedure fails.
+ */
+ public void shutdown() throws SoapFault
+ {
+ shutdownCapabilities();
+
+ ResourceManager manager = getResourceManager();
+
+ if (manager.getResource(_enpointReference) != null)
+ {
+ manager.removeResource(_enpointReference);
+ }
+
+ _currentState = _hasBeenShutdown;
+ }
+ };
+
+ /**
+ * The initial state of this resource.
+ * As the name suggests, it is not yet initialized.
+ */
+ private final State _notYetInitialized = new State()
+ {
+ /**
+ * Provides initialization of this resource.
+ *
+ * @throws SoapFault when the initialization fails.
+ */
+ public void initialize() throws SoapFault
+ {
+ _properties = new SimpleResourcePropertyCollection();
+ _wsdl = ThreadSessionManager.getInstance().getSession().getWsdlDocument();
+
+ ResourcePropertiesSchema schema = createPropertiesSchema(_wsdl);
+ _properties.setSchema(schema);
+
+ MetadataDescriptor metadata = createMetadataDescriptor(_wsdl);
+ _properties.setMetadata(metadata);
+
+ initializeCapabilities();
+
+ _properties.applyMetadata();
+
+ // Resource intialization completed : Let's make a state change.
+ _currentState = _hasBeenInitialized;
+ }
+
+ /**
+ * Shuts down this resource.
+ *
+ * @throws SoapFault when the shutdown procedure fails. */
+ public void shutdown() throws SoapFault
+ {
+ LOGGER.error(Messages.QMAN_100032_WS_RESOURCE_NOT_YET_INITIALIZED);
+ throw new SoapFault(Messages.QMAN_100032_WS_RESOURCE_NOT_YET_INITIALIZED);
+ }
+
+ /**
+ * Returns false because this state indicates that
+ * the resource has not yet been initialized.
+ *
+ * @return false;
+ */
+ public boolean hasBeenInitialized()
+ {
+ return false;
+ }
+
+ /**
+ * Returns false because the resource, when is in this state
+ * hasn't been initialized and as conseguence of that hasn't
+ * been shutdonm.
+ *
+ * @return false;
+ */
+ public boolean hasBeenShutdown()
+ {
+ return false;
+ }
+ };
+
+ private Map<String,Capability> _capabilitiesByAction = new HashMap<String, Capability>();
+ private Map<String, Capability> _capabilitiesByURI = new LinkedHashMap<String, Capability>();
+
+ private String _contextPath;
+ private Environment _environment;
+ private EndpointReference _enpointReference;
+
+ private State _currentState = _notYetInitialized;
+
+ private ResourceManager _resourceManager;
+ private ResourcePropertyCollection _properties;
+
+ private Map<String,String> _initParameters = Collections.EMPTY_MAP;
+
+ // Workaround : muse is using and hardcoded java.util.logging.Logger but we should use
+ // SLF4j so this is the original implementatation that won't never be used (on QMan classes)
+ private java.util.logging.Logger _logger;
+
+ private Document _wsdl;
+ private String _wsdlPath;
+ private QName _wsdlPortType;
+
+ /**
+ * Adds the given capability to this resource.
+ *
+ * @param capability the capability to be added.
+ */
+ public void addCapability(Capability capability)
+ {
+ capability.setResource(this);
+ capability.setLog(getLog());
+ capability.setEnvironment(getEnvironment());
+
+ String uri = capability.getCapabilityURI();
+ _capabilitiesByURI.put(uri, capability);
+
+ LOGGER.debug(
+ Messages.QMAN_200033_CAPABILITY_CLASS_HAS_BEEN_ADDED,
+ capability.getClass(),
+ uri);
+ }
+
+ /**
+ * Returns the capability associated with the given URI.
+ *
+ * @return the capability associated with the given URI.
+ */
+ public Capability getCapability(String capabilityURI)
+ {
+ return _capabilitiesByURI.get(capabilityURI);
+ }
+
+ /**
+ * Returns a collection with all registered capability URIs.
+ *
+ * @return a collection with all registered capability URIs.
+ */
+ public final Collection getCapabilityURIs()
+ {
+ return Collections.unmodifiableSet(_capabilitiesByURI.keySet());
+ }
+
+ /**
+ * Returns the context path of this resource.
+ *
+ * @return the context path of this resource.
+ */
+ public final String getContextPath()
+ {
+ return _contextPath;
+ }
+
+ /**
+ * Returns the endpoint reference of this resource.
+ *
+ * @return the endpoint reference of this resource.
+ */
+ public EndpointReference getEndpointReference()
+ {
+ return _enpointReference;
+ }
+
+ /**
+ * Returns the enviroment associated with this resource.
+ *
+ * @return the enviroment associated with this resource.
+ */
+ public final Environment getEnvironment()
+ {
+ return _environment;
+ }
+
+ /**
+ * Returns the initialization parameter of this resource associated with
+ * the given name.
+ *
+ * @param name the init parameter name.
+ * @return the initialization parameter associated with the given name.
+ */
+ public final String getInitializationParameter(String name)
+ {
+ return (String)getInitializationParameters().get(name);
+ }
+
+ /**
+ * Returns the map containing all init parameters of this resource.
+ *
+ * @return the map containing all init parameters of this resource.
+ */
+ public final Map<String,String> getInitializationParameters()
+ {
+ return _initParameters;
+ }
+
+ /**
+ * N.A. This resource uses QMan logging instead of plain java.util.logger
+ * implementation.
+ */
+ public final java.util.logging.Logger getLog()
+ {
+ return _logger;
+ }
+
+ /**
+ * Returns the resource manager associated with this resource.
+ *
+ * @return the resource manager associated with this resource.
+ */
+ public ResourceManager getResourceManager()
+ {
+ return _resourceManager;
+ }
+
+ /**
+ * Returns the wsdl (relative) path of this resource.
+ *
+ * @return the wsdl (relative) path of this resource.
+ */
+ public String getWsdlPath()
+ {
+ return _wsdlPath;
+ }
+
+ /**
+ * Returns the port type of this resource.
+ *
+ * @return the port type of this resource.
+ */
+ public final QName getWsdlPortType()
+ {
+ return _wsdlPortType;
+ }
+
+ /**
+ * Returns true if this resource has been initialized, false otherwise.
+ *
+ * @return true if this resource has been initialized, false otherwise.
+ */
+ public final boolean hasBeenInitialized()
+ {
+ return _currentState.hasBeenInitialized();
+ }
+
+ /**
+ * Returns true if this resource has been shutdown, false otherwise.
+ *
+ * @return true if this resource has been shutdown, false otherwise.
+ */
+ public final boolean hasBeenShutdown()
+ {
+ return _currentState.hasBeenShutdown();
+ }
+
+ /**
+ * Checks if a capability with the given URI is available for this resource.
+ *
+ * @return true if a capability with the given URI is available for this resource, false otherwise.
+ */
+ public final boolean hasCapability(String capabilityURI)
+ {
+ return getCapability(capabilityURI) != null;
+ }
+
+ /**
+ * Returns the collection containing all properties of this resource.
+ *
+ * @return the collection containing all properties of this resource.
+ */
+ public final ResourcePropertyCollection getPropertyCollection()
+ {
+ return _properties;
+ }
+
+ /**
+ * Return the WSDL document of this resource.
+ *
+ * @return the WSDL document of this resource.
+ */
+ public Document getWsdl()
+ {
+ return _wsdl;
+ }
+
+ /**
+ * Initializes this resources.
+ * Note that the what needs to be done depends on the current state of this
+ * resource.
+ *
+ * @throws SoapFault when the initialization fails.
+ */
+ public void initialize() throws SoapFault
+ {
+ _currentState.initialize();
+ }
+
+ /**
+ * Invokes the action specified in the given soap request on this resource.
+ *
+ * @param requestBody the SOAP body.
+ * @return the result of the invocation as org.w3c.dom.Element
+ */
+ public Element invoke(Element requestBody)
+ {
+ String action = _environment.getAddressingContext().getAction();
+ Capability capability = getCapabilityForAction(action);
+
+ // Sanity check : is there a capability for the given action?
+ if (capability == null)
+ {
+ SoapFault wsaFault = new SoapFault(
+ String.format(
+ Messages.ACTION_NOT_SUPPORTED,
+ action,getContextPath()));
+
+ wsaFault.setCode(SoapConstants.SENDER_QNAME);
+ wsaFault.setSubCode(WsaConstants.ACTION_NOT_SUPPORTED_FAULT_QNAME);
+
+ Element detail = XmlUtils.createElement(WsaConstants.PROBLEM_ACTION_QNAME);
+ XmlUtils.setElement(detail, WsaConstants.ACTION_QNAME, action);
+ wsaFault.setDetail(detail);
+
+ LOGGER.error(
+ Messages.QMAN_100020_ACTION_NOT_SUPPORTED,
+ action,
+ getContextPath());
+
+ return wsaFault.toXML();
+ }
+
+ MessageHandler handler = capability.getMessageHandler(action);
+ Method method = handler.getMethod();
+
+ try
+ {
+ Object[]parameters = handler.fromXML(requestBody);
+ Object result = method.invoke(capability, parameters);
+ return handler.toXML(result);
+ }
+ catch (Throwable throwable)
+ {
+ LOGGER.error(
+ throwable,
+ Messages.QMAN_100037_INVOKE_OPERATION_FAILURE);
+
+ SoapFault response = SoapUtils.convertToFault(
+ (throwable.getCause()!= null)
+ ? throwable.getCause()
+ : throwable);
+ return response.toXML();
+ }
+ }
+
+ /**
+ * Sets the context path of this resource.
+ *
+ * @param contextPath the context path of this resource.
+ */
+ public final void setContextPath(String contextPath)
+ {
+ _contextPath = contextPath;
+ }
+
+ /**
+ * Sets the endpoint reference of this resource.
+ *
+ * @param endpointReference the endpoint reference of this resource.
+ */
+ public final void setEndpointReference(EndpointReference endpointReference)
+ {
+ if (_enpointReference != null && hasBeenInitialized())
+ throw new RuntimeException(("ExistingResourceEPR"));
+
+ _enpointReference = endpointReference;
+ }
+
+ /**
+ * Sets the context environment of this resource.
+ *
+ * @param environment the context environment of this resource.
+ */
+ public final void setEnvironment(Environment environment)
+ {
+ _environment = environment;
+ }
+
+ /**
+ * Sets the initialization parameters of this resource.
+ *
+ * @param parameters the init parameters of this resource.
+ */
+ public final void setInitializationParameters(Map parameters)
+ {
+ _initParameters = (parameters != null)
+ ? parameters
+ : Collections.EMPTY_MAP;
+ }
+
+ /**
+ * N.A. for this resource. QMan logging mechanism is used for that.
+ */
+ public final void setLog(java.util.logging.Logger log)
+ {
+ _logger = log;
+ }
+
+ /**
+ * Sets the resource manager owner of this resource.
+ *
+ * @param manager the resource manager of this resource.
+ */
+ public void setResourceManager(ResourceManager manager)
+ {
+ _resourceManager = manager;
+ }
+
+ /**
+ * Sets the WSDL (relative) path of this resource.
+ *
+ * @param wsdlPath the WSDL (relative) path of this resource.
+ */
+ public final void setWsdlPath(String wsdlPath)
+ {
+ this._wsdlPath = wsdlPath;
+ }
+
+ /**
+ * Sets the port type of this resource.
+ *
+ * @param wsdlPortType the port type of this resource.
+ */
+ public final void setWsdlPortType(QName wsdlPortType)
+ {
+ _wsdlPortType = wsdlPortType;
+ }
+
+ /**
+ * Shutdown procedure for this resource.
+ *
+ * @throws SoapFault when the shutdown procedure fails.
+ */
+ public synchronized void shutdown() throws SoapFault
+ {
+ _currentState.shutdown();
+ }
+
+ /**
+ * Returns a string representation of this resource.
+ * Basically the resource endpoint reference (as a string) is returned.
+ *
+ * @return the resource endpoint reference (as a string) is returned.
+ */
+ public String toString()
+ {
+ return getEndpointReference().toString();
+ }
+
+ /**
+ * Initializes capabilities of this resource.
+ *
+ * @throws SoapFault when at least one capability fails to initialize.
+ */
+ private void initializeCapabilities() throws SoapFault
+ {
+ for (Entry<String, Capability> entry : _capabilitiesByURI.entrySet())
+ {
+ Capability capability = entry.getValue();
+ capability.initialize();
+
+ for (Object action : capability.getActions())
+ {
+ _capabilitiesByAction.put((String)action, capability);
+ }
+
+ capability.initializeCompleted();
+ }
+ }
+
+ /**
+ * Shutdown procedure for all registered capabilities of this resource.
+ *
+ * @throws SoapFault when at least one capability shutdown fails.
+ */
+ private void shutdownCapabilities() throws SoapFault
+ {
+ for (Entry<String,Capability> entry : _capabilitiesByURI.entrySet())
+ {
+ Capability capabilty = entry.getValue();
+ capabilty.prepareShutdown();
+ capabilty.shutdown();
+ }
+ }
+
+ /**
+ * Creates a metadata descriptor for this resource.
+ *
+ * @param wsdl the WSDL document.
+ * @return a metadata descriptor for this resource.
+ * @throws SoapFault when it's not possible build the descriptor.
+ */
+ private MetadataDescriptor createMetadataDescriptor(Document wsdl) throws SoapFault
+ {
+ try
+ {
+ Element portTypeXML = WsdlUtils.getPortType(wsdl, getWsdlPortType());
+
+ String rmdName = XmlUtils.getAttribute(
+ portTypeXML,
+ WsrmdConstants.DESCRIPTOR_ATTR_QNAME);
+
+ String rmdPath = XmlUtils.getAttribute(
+ portTypeXML,
+ WsrmdConstants.DESCRIPTOR_LOCATION_ATTR_QNAME);
+
+ LOGGER.debug(Messages.QMAN_200034_RMD_NAME, rmdName);
+ LOGGER.debug(Messages.QMAN_200035_RMD_PATH, rmdPath);
+
+ Environment env = getEnvironment();
+ String path = env.createRelativePath(getWsdlPath(), rmdPath);
+ Document rmdDoc = env.getDocument(path);
+
+ Element[] additionalProperties =
+ ThreadSessionManager
+ .getInstance()
+ .getSession()
+ .getResourceMetadataDescriptor();
+
+ Element metadataDescriptor = WsrmdUtils.getMetadataDescriptor(rmdDoc, rmdName);
+
+ for (Element element : additionalProperties)
+ {
+
+// rmdDoc.importNode(element, true);
+ Element adopted = (Element) rmdDoc.importNode(element,false);
+ metadataDescriptor.appendChild(adopted);
+ }
+
+ return new SimpleMetadataDescriptor(metadataDescriptor);
+ }
+ catch(Exception exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100021_RMD_BUID_FAILURE,
+ getContextPath());
+ throw new SoapFault(exception);
+ }
+ }
+
+ /**
+ * Returns the capability associated with the given action.
+ *
+ * @param action the wsa:action of the requested capability.
+ * @return the capability associated with the given action.
+ */
+ private Capability getCapabilityForAction(String action)
+ {
+ return (Capability)_capabilitiesByAction.get(action);
+ }
+
+ /**
+ * Creates a WSRP document representing schema properties for this resource.
+ *
+ * @param wsdl the DOM document holding the resource's WSDL.
+ * @return the WSRP document schema.
+ */
+ private ResourcePropertiesSchema createPropertiesSchema(Document wsdl)
+ {
+ QName wsrpName = WsrpUtils.getPropertiesName(wsdl, getWsdlPortType());
+ Element wsrpDoc = WsdlUtils.getElementDeclaration(wsdl, wsrpName);
+ return new SimpleResourcePropertiesSchema(wsrpName, wsrpDoc);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ByteArraySerializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ByteArraySerializer.java
new file mode 100644
index 0000000000..a064542658
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ByteArraySerializer.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.muse.serializer;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.xerces.impl.dv.util.Base64;
+import org.w3c.dom.Element;
+
+/**
+ * Implementation of Muse Serializer for byte array type.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ByteArraySerializer implements Serializer {
+
+ /**
+ * Return a byte array representation of the given xml element.
+ *
+ * @param xml the element to unmarshal.
+ * @throws SoapFault when the unmarshalling fails.
+ */
+ public Object fromXML(Element xml) throws SoapFault
+ {
+ try
+ {
+ return Base64.decode(xml.getTextContent());
+ } catch (Exception exception)
+ {
+ throw new SoapFault(exception);
+ }
+ }
+
+ /**
+ * Returns the java type associated to this class.
+ *
+ * @return the java type associated to this class.
+ */
+ public Class<?> getSerializableType()
+ {
+ return byte[].class;
+ }
+
+ /**
+ * Return an xml representation of the given byte array with the given name.
+ *
+ * @param object the byte array to marshal.
+ * @param qname the qualified (xml) name of the object to use in xml representation.
+ * @return the xml representation of the byte array.
+ * @throws SoapFault when the marshalling fails.
+ */
+ public Element toXML(Object object, QName qname) throws SoapFault
+ {
+ Element element = XmlUtils.createElement(
+ qname,
+ Base64.encode((byte[]) object));
+ element.setAttribute("xmlns:xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
+ element.setAttribute("xsi:type","xsd:base64Binary");
+ return element;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/DateSerializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/DateSerializer.java
new file mode 100644
index 0000000000..60350ccc31
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/DateSerializer.java
@@ -0,0 +1,75 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.muse.serializer;
+
+import java.util.Date;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.w3c.dom.Element;
+
+/**
+ * Implementation of Muse Serializer for Date type.
+ * Note that Muse already ships a serializer but the formatter used on that class
+ * is losing precision betweem marshal / unmarshal operations.
+ *
+ * @author Andrea Gazzarini
+ */
+public class DateSerializer implements Serializer
+{
+ /**
+ * Return a Date representation of the given xml element.
+ *
+ * @param xml the element to unmarshal.
+ * @throws SoapFault when the unmarshalling fails.
+ */
+ public Object fromXML(Element elementData) throws SoapFault
+ {
+ return new Date(Long.parseLong(elementData.getTextContent()));
+ }
+
+ /**
+ * Returns the java type associated to this class.
+ *
+ * @return the java type associated to this class.
+ */
+ public Class<?> getSerializableType()
+ {
+ return Date.class;
+ }
+
+ /**
+ * Return an xml representation of the given UUID with the given name.
+ *
+ * @param object the UUID to marshal.
+ * @param qname the qualified (xml) name of the object to use in xml representation.
+ * @return the xml representation of the UUID.
+ * @throws SoapFault when the marshalling fails.
+ */
+ public Element toXML(Object obj, QName qname) throws SoapFault
+ {
+ Date date = (Date) obj;
+ return XmlUtils.createElement(qname, String.valueOf(date.getTime()));
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java
new file mode 100644
index 0000000000..b819d52ad1
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.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.management.wsdm.muse.serializer;
+
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.wsdm.capabilities.Result;
+import org.w3c.dom.Element;
+
+/**
+ * Implementation of Muse Serializer for Result type.
+ *
+ * @author Andrea Gazzarini
+ */
+public class InvocationResultSerializer implements Serializer
+{
+ private Serializer _mapSerializer = SerializerRegistry.getInstance().getSerializer(Map.class);
+
+ /**
+ * Return a UUID representation of the given xml element.
+ *
+ * @param xml the element to unmarshal.
+ * @throws SoapFault when the unmarshalling fails.
+ */
+ @SuppressWarnings("unchecked")
+ public Object fromXML(Element elementData) throws SoapFault
+ {
+ Element outputParameters = XmlUtils.getFirstElement(elementData);
+ return new Result((Map<String, Object>) _mapSerializer.fromXML(outputParameters));
+ }
+
+ /**
+ * Returns the java type associated to this class.
+ *
+ * @return the java type associated to this class.
+ */
+ public Class<?> getSerializableType()
+ {
+ return Result.class;
+ }
+
+ /**
+ * Return an xml representation of the given UUID with the given name.
+ *
+ * @param object the UUID to marshal.
+ * @param qname the qualified (xml) name of the object to use in xml representation.
+ * @return the xml representation of the UUID.
+ * @throws SoapFault when the marshalling fails.
+ */
+ public Element toXML(Object obj, QName qname) throws SoapFault
+ {
+ Result result = (Result) obj;
+ Element root = XmlUtils.createElement(qname);
+ if (result.getOutputParameters() != null)
+ {
+ Element outputSection = SerializerRegistry.getInstance().getSerializer(Map.class).toXML(result.getOutputParameters(), new QName("outputParameters"));
+ root.appendChild(outputSection);
+ }
+ return root;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java
new file mode 100644
index 0000000000..07e1dfdc56
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java
@@ -0,0 +1,134 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.muse.serializer;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+
+/**
+ * Implementation of Muse Serializer for Map type.
+ *
+ * <amspam>
+ * <entry>
+ * <key>
+ * <value>
+ * </entry>
+ * </amsasm>
+ *
+ * @author Andrea Gazzarini
+ */
+public class MapSerializer implements Serializer
+{
+
+ ByteArraySerializer _byteArraySerializer = new ByteArraySerializer();
+ Serializer _objectSerializer = SerializerRegistry.getInstance().getSerializer(Object.class);
+ Serializer _stringSerializer = SerializerRegistry.getInstance().getSerializer(String.class);
+
+ /**
+ * Return a map representation of the given xml element.
+ *
+ * @param xml the element to unmarshal.
+ * @throws SoapFault when the unmarshalling fails.
+ */
+ public Object fromXML(Element xml) throws SoapFault
+ {
+ Map<Object,Object> result = new HashMap<Object,Object>();
+
+ if (xml != null)
+ {
+ Element[] children = XmlUtils.getAllElements(xml);
+ Serializer objectDeserializer = SerializerRegistry.getInstance().getSerializer(Object.class);
+
+ for (Element entry : children)
+ {
+ Element[] keysAndValues = XmlUtils.getAllElements(entry);
+ Object key = null;
+ Object value = null;
+ for (Element element : keysAndValues)
+ {
+ if (Names.KEY.equals(element.getLocalName()))
+ {
+ key = _stringSerializer.fromXML(element);
+ } else if (Names.VALUE.equals(element.getLocalName()))
+ {
+ value = objectDeserializer.fromXML(element);
+ }
+ }
+ result.put(key, value);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns the java type associated to this class.
+ *
+ * @return the java type associated to this class.
+ */
+ public Class<?> getSerializableType()
+ {
+ return Map.class;
+ }
+
+ /**
+ * Return an xml representation of the given Map with the given name.
+ *
+ * @param object the Map to marshal.
+ * @param qname the qualified (xml) name of the object to use in xml representation.
+ * @return the xml representation of the given Map.
+ * @throws SoapFault when the marshalling fails.
+ */
+ public Element toXML(Object obj, QName qname) throws SoapFault
+ {
+
+ Map<?, ?> data = (Map<?, ?>) obj;
+
+ QName entryQName = new QName(qname.getNamespaceURI(),Names.ENTRY,qname.getPrefix());
+ QName keyQName = new QName(qname.getNamespaceURI(),Names.KEY,qname.getPrefix());
+ QName valueQName = new QName(qname.getNamespaceURI(),Names.VALUE,qname.getPrefix());
+
+ Element root = XmlUtils.createElement(qname);
+ root.setAttribute("xmlns:xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
+ for (Entry<?, ?> mapEntry: data.entrySet())
+ {
+ Element entry = XmlUtils.createElement(entryQName);
+ entry.appendChild(_stringSerializer.toXML(mapEntry.getKey(), keyQName));
+ if (mapEntry.getValue().getClass() == byte[].class) {
+ entry.appendChild(_byteArraySerializer.toXML(mapEntry.getValue(), valueQName));
+ } else {
+ entry.appendChild(_objectSerializer.toXML(mapEntry.getValue(), valueQName));
+ }
+ root.appendChild(entry);
+ }
+ return root;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ObjectSerializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ObjectSerializer.java
new file mode 100644
index 0000000000..ff0c69cdda
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ObjectSerializer.java
@@ -0,0 +1,202 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.muse.serializer;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+
+/**
+ * Generic Serializer for objects.
+ * It is a general-purpose serializer used for encoding Object values.
+ */
+public class ObjectSerializer implements Serializer
+{
+ /**
+ * Mapping between xsd and java types.
+ */
+ private Map<String, Class<?>> xml2Java = new HashMap<String, Class<?>>();
+ {
+ xml2Java.put("xsd:long", Long.class);
+ xml2Java.put("xsd:boolean",Boolean.class);
+ xml2Java.put("xsd:double",Double.class);
+ xml2Java.put("xsd:float",Float.class);
+ xml2Java.put("xsd:integer",Integer.class);
+ xml2Java.put("xsd:int",Integer.class);
+ xml2Java.put("xsd:short",Short.class);
+ xml2Java.put("xsd:string",String.class);
+ xml2Java.put("xsd:anyURI",URI.class);
+ xml2Java.put("xsd:dateTime",Date.class);
+ xml2Java.put("xsd:QName",QName.class);
+ xml2Java.put("xsd:element",Element.class);
+ xml2Java.put("xsd:base64Binary",byte[].class);
+ xml2Java.put("qman:arrayOfLong",Long[].class);
+ xml2Java.put("qman:arrayOfBoolean",Boolean[].class);
+ xml2Java.put("qman:arrayOfDouble",Double[].class);
+ xml2Java.put("qman:arrayOfFloat",Float[].class);
+ xml2Java.put("qman:arrayOfInteger",Integer[].class);
+ xml2Java.put("qman:arrayOfShort",Short[].class);
+ xml2Java.put("qman:arrayOfString",String[].class);
+ xml2Java.put("qman:arrayOfURI",URI[].class);
+ xml2Java.put("qman:arrayOfDate",Date[].class);
+ xml2Java.put("qman:uuid",UUID.class);
+ xml2Java.put("qman:map",Map.class);
+ xml2Java.put("qman:map",HashMap.class);
+ }
+
+ private Map<Class<?>, String> java2Xml = new HashMap<Class<?>, String>();
+ {
+ java2Xml.put(UUID.class,"qman:uuid");
+ java2Xml.put(Long.class,"xsd:long");
+ java2Xml.put(long.class,"xsd:long");
+ java2Xml.put(Boolean.class,"xsd:boolean");
+ java2Xml.put(boolean.class,"xsd:boolean");
+ java2Xml.put(Double.class,"xsd:double");
+ java2Xml.put(double.class,"xsd:double");
+ java2Xml.put(Float.class,"xsd:float");
+ java2Xml.put(float.class,"xsd:float");
+ java2Xml.put(Integer.class,"xsd:integer");
+ java2Xml.put(int.class,"xsd:integer");
+ java2Xml.put(Short.class,"xsd:short");
+ java2Xml.put(short.class,"xsd:short");
+ java2Xml.put(String.class,"xsd:string");
+ java2Xml.put(URI.class,"xsd:anyURI");
+ java2Xml.put(Date.class,"xsd:dateTime");
+ java2Xml.put(QName.class,"xsd:QName");
+ java2Xml.put(Element.class,"xsd:element");
+ java2Xml.put(byte[].class,"xsd:base64Binary");
+ java2Xml.put(Long[].class,"qman:arrayOfLong");
+ java2Xml.put(long[].class,"qman:arrayOfLong");
+ java2Xml.put(Boolean[].class,"qman:arrayOfBoolean");
+ java2Xml.put(boolean[].class,"qman:arrayOfBoolean");
+ java2Xml.put(Double[].class,"qman:arrayOfDouble");
+ java2Xml.put(double[].class,"qman:arrayOfDouble");
+ java2Xml.put(Float[].class,"qman:arrayOfFloat");
+ java2Xml.put(float[].class,"qman:arrayOfFloat");
+ java2Xml.put(Integer[].class,"qman:arrayOfInteger");
+ java2Xml.put(int[].class,"qman:arrayOfInteger");
+ java2Xml.put(Short[].class,"qman:arrayOfShort");
+ java2Xml.put(short[].class,"qman:arrayOfShort");
+ java2Xml.put(String[].class,"qman:arrayOfString");
+ java2Xml.put(URI[].class,"qman:arrayOfURI");
+ java2Xml.put(Date[].class,"qman:arrayOfDate");
+ java2Xml.put(Map.class,"qman:map");
+ java2Xml.put(HashMap.class,"qman:map");
+ }
+
+ /**
+ * Converts the incoming element into the appropriate Java type.
+ * The method will fail if :
+ *
+ * <br>1) The element has no xsi:type attribute;
+ * <br>2) The xsi:type attribute has no corresponding java type on this serializer mappings.
+ *
+ * @param elementData the xml element containing data to be unmarshalled.l
+ * @return the java object as result of xml element unmarshalling.
+ * @throws SoapFault when the marshalling fails.
+ */
+ public Object fromXML(Element elementData) throws SoapFault
+ {
+ Attr typeAttribute = elementData.getAttributeNodeNS(
+ XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
+ Names.TYPE);
+
+ if (typeAttribute == null)
+ {
+ throw new SoapFault(
+ "No type attribute was found for the current element. " +
+ "If you are using this serializer, in order to unmarshal the" +
+ " opportune type the xsi:type must be specified.");
+ }
+
+ Class<?> clazz = xml2Java.get(typeAttribute.getValue());
+
+ if (clazz == null)
+ {
+ throw new SoapFault(
+ String.format(
+ "No corresponding class was found on this serializer mappings for xsi:type %s.",
+ typeAttribute));
+ }
+
+ if (clazz == byte[].class) {
+ return new ByteArraySerializer().fromXML(elementData);
+ }
+
+ return SerializerRegistry.getInstance().getSerializer(clazz).fromXML(elementData);
+ }
+
+ /**
+ * As this serializer is supposed to deal with generic object types, this method returns Object.class.
+ *
+ * @return Object.class
+ */
+ public Class<?> getSerializableType()
+ {
+ return Object.class;
+ }
+
+ /**
+ * Converts the given object (with the given qname) in XML format.
+ * This method fails if there's no corresponding xml type for the given runtime type of the input object.
+ *
+ * @param obj the object to be marshalled.
+ * @param qname the qualified name that will be used in encoding.
+ */
+ public Element toXML(Object obj, QName qname) throws SoapFault
+ {
+ Class<?> clazz = obj.getClass();
+
+ Element result = null;
+
+ if (clazz == byte[].class) {
+ result = new ByteArraySerializer().toXML(obj,qname);
+ }
+ else {
+ result = SerializerRegistry.getInstance().getSerializer(clazz).toXML(obj,qname);
+ }
+ result.setAttribute(Names.XSI_TYPE, java2Xml.get(clazz));
+ return result;
+ }
+
+ /**
+ * Returns the xml type associated with the given class.
+ *
+ * @param clazz the class.
+ * @return the xml type associated with the given class.
+ */
+ public String getXmlType(Class<?> clazz)
+ {
+ return java2Xml.get(clazz);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/UUIDSerializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/UUIDSerializer.java
new file mode 100644
index 0000000000..408a8de6cf
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/UUIDSerializer.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.management.wsdm.muse.serializer;
+
+import java.util.UUID;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.w3c.dom.Element;
+
+/**
+ * Implementation of Muse Serializer for UUID type.
+ *
+ * @author Andrea Gazzarini
+ */
+public class UUIDSerializer implements Serializer
+{
+ /**
+ * Return a UUID representation of the given xml element.
+ *
+ * @param xml the element to unmarshal.
+ * @throws SoapFault when the unmarshalling fails.
+ */
+ public Object fromXML(Element elementData) throws SoapFault
+ {
+ return UUID.fromString(elementData.getTextContent());
+ }
+
+ /**
+ * Returns the java type associated to this class.
+ *
+ * @return the java type associated to this class.
+ */
+ public Class<?> getSerializableType()
+ {
+ return UUID.class;
+ }
+
+ /**
+ * Return an xml representation of the given UUID with the given name.
+ *
+ * @param object the UUID to marshal.
+ * @param qname the qualified (xml) name of the object to use in xml representation.
+ * @return the xml representation of the UUID.
+ * @throws SoapFault when the marshalling fails.
+ */
+ public Element toXML(Object obj, QName qname) throws SoapFault
+ {
+ return XmlUtils.createElement(qname, String.valueOf(obj));
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEvent.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEvent.java
new file mode 100644
index 0000000000..9284a62461
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEvent.java
@@ -0,0 +1,149 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.notifications;
+
+import org.apache.muse.util.xml.XmlSerializable;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Object representation of a QMan entity lifecycle event notification.
+ * Note that with entity we mean both object(s) and event(s).
+ *
+ * At the moment there are only two types of lifecycle events : CREATE and REMOVE.
+ * The first one if fired when a new instance (event or object) is created, while the second
+ * one is fired when an object instance (events are transient objects so they are not destroyed)
+ * is removed.
+ *
+ * Developer Note : The marshal & unmarshal ops could be handled using JAXB but
+ * we are not sure about the running environment (JAXB libs were included only
+ * starting from 1.6)
+ *
+ * This is the event XML representation :
+ *
+ * <LifecycleEvent Type="created" timemillis="">
+ <Resource>
+ <ResourceId>16038bd5-b62b-4e86-9833-7560ed57b474</id>
+ <Package>org.qpid.apache.broker</package>
+ <Name>session</name>
+ </Resource>
+ </lifecycle-event>
+
+ * @author Andrea Gazzarini
+ */
+public class LifeCycleEvent implements XmlSerializable
+{
+ private final String _resourceId;
+ private final String _packageName;
+ private final String _name;
+
+ private final LifeCycleEventType _type;
+
+ /**
+ * Builds a new event with the given data.
+ *
+ * @param resourceId resource identifier.
+ * @param packageName resource package name.
+ * @param name resource name.
+ * @param type event type.
+ */
+ private LifeCycleEvent(String resourceId, String packageName, String name, LifeCycleEventType type)
+ {
+ this._resourceId = resourceId;
+ this._packageName = packageName;
+ this._name = name;
+ this._type = type;
+ }
+
+ /**
+ * Factory method for a new "CREATE" event.
+ * Builds a new "CREATE" event with the given data.
+ *
+ * @param resourceId resource identifier.
+ * @param packageName resource package name.
+ * @param name resource name.
+ */
+ public static LifeCycleEvent newCreateEvent(String resourceId, String packageName, String name)
+ {
+ return new LifeCycleEvent(resourceId, packageName, name, LifeCycleEventType.CREATED);
+ }
+
+ /**
+ * Factory method for a new "REMOVE" event.
+ * Builds a new "REMOVE" event with the given data.
+ *
+ * @param resourceId resource identifier.
+ * @param packageName resource package name.
+ * @param name resource name.
+ */
+ public static LifeCycleEvent newRemoveEvent(String resourceId, String packageName, String name)
+ {
+ return new LifeCycleEvent(resourceId, packageName, name, LifeCycleEventType.REMOVED);
+ }
+
+ /**
+ * Returns an XML representation of this event.
+ *
+ * @return an XML representation of this event.
+ */
+ public Element toXML()
+ {
+ return toXML(XmlUtils.EMPTY_DOC);
+ }
+
+ /**
+ * Returns an XML representation of this event using the given
+ * input document as owner.
+ *
+ * @return an XML representation of this event.
+ */
+ public Element toXML(Document factory)
+ {
+ Element lifeCycleEvent = XmlUtils.createElement(factory, Names.LIFECYCLE_EVENT_QNAME);
+
+ lifeCycleEvent.setAttribute(
+ "Type",
+ _type.toString());
+
+ lifeCycleEvent.setAttribute(
+ Names.TIMEMILLIS_ATTRIBUTE_NAME,
+ String.valueOf(System.currentTimeMillis()));
+
+ Element resource = XmlUtils.createElement(factory, Names.RESOURCE_QNAME);
+ lifeCycleEvent.appendChild(resource);
+
+ Element id = XmlUtils.createElement(factory, Names.RES_ID_QNAME);
+ id.setTextContent(_resourceId);
+ resource.appendChild(id);
+
+ Element packageName = XmlUtils.createElement(factory, Names.PACKAGE_NAME_QNAME);
+ packageName.setTextContent(_packageName);
+ resource.appendChild(packageName);
+
+ Element name = XmlUtils.createElement(factory, Names.ENTITY_NAME_QNAME);
+ name.setTextContent(_name);
+ resource.appendChild(name);
+
+ return lifeCycleEvent;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEventType.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEventType.java
new file mode 100644
index 0000000000..9ce7bfc743
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEventType.java
@@ -0,0 +1,34 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.notifications;
+
+/**
+ * Event type enumeration.
+ * Event type are used as part of event WS-Notifications in order to inform
+ * the interested listeners about the lifecycle of a QMan managed entity (object or event instance).
+ *
+ * @author Andrea Gazzarini
+ */
+public enum LifeCycleEventType
+{
+ CREATED,
+ REMOVED;
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/WsdlDebugger.java b/qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/WsdlDebugger.java
new file mode 100644
index 0000000000..398a69817b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/WsdlDebugger.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.qman.debug;
+
+import javax.management.ObjectName;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.qpid.transport.util.Logger;
+import org.w3c.dom.Node;
+
+/**
+ * Utility class used for debbugging WSDL documents
+ *
+ * @author Andrea Gazzarini
+ */
+public class WsdlDebugger {
+ public final static Logger LOGGER = Logger.get(WsdlDebugger.class);
+
+ /**
+ * Prints out to log the given node.
+ *
+ * @param node the xml node to be printed out.
+ */
+ public static void debug(ObjectName resourceId, Node node)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(resourceId+" : "+XmlUtils.toString(node, false,true));
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/XmlDebugger.java b/qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/XmlDebugger.java
new file mode 100644
index 0000000000..600bb51858
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/XmlDebugger.java
@@ -0,0 +1,92 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.qman.debug;
+
+import javax.management.ObjectName;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.qpid.transport.util.Logger;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Utility class used for debbugging XML messages
+ *
+ * @author Andrea Gazzarini
+ */
+public class XmlDebugger {
+ public final static Logger LOGGER = Logger.get(XmlDebugger.class);
+
+ /**
+ * Prints out to log the given node.
+ *
+ * @param node the xml node to be printed out.
+ */
+ public static void debug(Node node)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(XmlUtils.toString(node, false,true));
+ }
+ }
+
+ /**
+ * Prints out to log the given node.
+ *
+ * @param node the xml node to be printed out.
+ */
+ public static void debug(ObjectName resourceId, Node node)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(resourceId+" : "+XmlUtils.toString(node, false,true));
+ }
+ }
+
+
+ /**
+ * Prints out to log the given element array.
+ *
+ * @param elements the element array to be printed out.
+ */
+ public static void debug(Element [] elements)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ StringBuilder builder = new StringBuilder();
+ for (Element element : elements) {
+ builder.append(XmlUtils.toString(element,false,true));
+ builder.append(System.getProperty("line.separator"));
+ }
+ LOGGER.debug(builder.toString());
+ }
+ }
+
+ /**
+ * Prints out to log the given node.
+ *
+ * @param node the xml node to be printed out.
+ */
+ public static void debug(String node)
+ {
+ LOGGER.debug(node);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/router-entries/adapter/resource-instance-1.xml b/qpid/java/management/client/src/main/java/router-entries/adapter/resource-instance-1.xml
new file mode 100644
index 0000000000..062791fa3f
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/router-entries/adapter/resource-instance-1.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing"/>
diff --git a/qpid/java/management/client/src/main/java/router-entries/consumer/resource-instance-1.xml b/qpid/java/management/client/src/main/java/router-entries/consumer/resource-instance-1.xml
new file mode 100644
index 0000000000..062791fa3f
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/router-entries/consumer/resource-instance-1.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing"/>
diff --git a/qpid/java/management/client/src/main/java/wsdl/QManAdapter.rmd b/qpid/java/management/client/src/main/java/wsdl/QManAdapter.rmd
new file mode 100644
index 0000000000..31e921a06b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/QManAdapter.rmd
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<Definitions xmlns="http://docs.oasis-open.org/wsrf/rmd-1">
+ <MetadataDescriptor
+ xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"
+ xmlns:wst="http://docs.oasis-open.org/wsn/t-1"
+ xmlns:muws1="http://docs.oasis-open.org/wsdm/muws1-2.xsd"
+ xmlns:muws2="http://docs.oasis-open.org/wsdm/muws2-2.xsd"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman"
+ name="WsDmAdapterMetadata"
+ interface="qman:QManAdapterPortType"
+ wsdlLocation="http://amqp.apache.org/qpid/management/qman QManAdapter.wsdl">
+ <Property name="wsrf-sg:MembershipContentRule" modifiability="read-only" mutability="mutable">
+ <StaticValues>
+ <wsrf-sg:MembershipContentRule MemberInterface="qman:QManWsResourcePortType"/>
+ </StaticValues>
+ </Property>
+ <Property name="wsrf-sg:Entry" modifiability="read-only" mutability="mutable" />
+ <Property name="wsrf-rp:QueryExpressionDialect" modifiability="read-only" mutability="constant" />
+ <Property name="wsnt:FixedTopicSet" modifiability="read-only" mutability="constant" />
+ <Property name="wst:TopicSet" modifiability="read-only" mutability="mutable" />
+ <Property name="wsnt:TopicExpression" modifiability="read-only" mutability="mutable" />
+ <Property name="wsnt:TopicExpressionDialect" modifiability="read-only" mutability="mutable" />
+ </MetadataDescriptor>
+</Definitions>
diff --git a/qpid/java/management/client/src/main/java/wsdl/QManAdapter.wsdl b/qpid/java/management/client/src/main/java/wsdl/QManAdapter.wsdl
new file mode 100644
index 0000000000..4b26862604
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/QManAdapter.wsdl
@@ -0,0 +1,694 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions
+ targetNamespace="http://amqp.apache.org/qpid/management/qman"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl-soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2"
+ xmlns:wsrf-sgw="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"
+ xmlns:wsntw="http://docs.oasis-open.org/wsn/bw-2"
+ xmlns:wst="http://docs.oasis-open.org/wsn/t-1"
+ xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1"
+ xmlns:muws1="http://docs.oasis-open.org/wsdm/muws1-2.xsd"
+ xmlns:muws2="http://docs.oasis-open.org/wsdm/muws2-2.xsd"
+ name="QManAdapter" >
+ <wsdl:types>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsrf/bf-2">
+ <xsd:include schemaLocation="WS-BaseFaults-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsrf/rp-2">
+ <xsd:include schemaLocation="WS-ResourceProperties-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsrf/r-2">
+ <xsd:include schemaLocation="WS-Resource-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://www.w3.org/2005/08/addressing">
+ <xsd:include schemaLocation="WS-Addressing-2005_08.xsd"/>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <xsd:include schemaLocation="WS-MetadataExchange-2004_09.xsd"/>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsrf/sg-2">
+ <xsd:include schemaLocation="WS-ServiceGroup-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsdm/muws1-2.xsd">
+ <xsd:include schemaLocation="WSDM-MUWS-Part1-1_1.xsd" />
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsdm/muws2-2.xsd">
+ <xsd:include schemaLocation="WSDM-MUWS-Part2-1_1.xsd" />
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsn/b-2">
+ <xsd:include schemaLocation="WS-BaseNotification-1_3.xsd" />
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsn/t-1">
+ <xsd:include schemaLocation="WS-Topics-1_3.xsd" />
+ </xsd:schema>
+ <xsd:schema targetNamespace="http://amqp.apache.org/qpid/management/qman">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2" schemaLocation="WS-BaseFaults-1_2.xsd"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/sg-2" schemaLocation="WS-ServiceGroup-1_2.xsd"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rp-2" schemaLocation="WS-ResourceProperties-1_2.xsd"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsn/b-2" schemaLocation="WS-BaseNotification-1_3.xsd"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsn/t-1" schemaLocation="WS-Topics-1_3.xsd"/>
+ <xsd:element name="WsDmAdapterResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-sg:Entry"/>
+ <xsd:element ref="wsrf-sg:MembershipContentRule"/>
+ <xsd:element ref="wsrf-rp:QueryExpressionDialect" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element ref="wsnt:FixedTopicSet" />
+ <xsd:element ref="wst:TopicSet" minOccurs="0" />
+ <xsd:element ref="wsnt:TopicExpression" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element ref="wsnt:TopicExpressionDialect" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="OperationInvocationFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="EntityInstanceNotFoundFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="MalformedEntityNameFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="NoSuchAttributeFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="Connect">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="host" type="xsd:string" minOccurs="1" nillable="false"/>
+ <xsd:element name="port" type="xsd:integer" minOccurs="1" nillable="false"/>
+ <xsd:element name="username" type="xsd:string" minOccurs="1" nillable="false"/>
+ <xsd:element name="password" type="xsd:string" minOccurs="1" nillable="false"/>
+ <xsd:element name="virtualHost" type="xsd:string" minOccurs="1" nillable="false"/>
+ <xsd:element name="initialPoolCapacity" type="xsd:integer" minOccurs="1" nillable="false"/>
+ <xsd:element name="maxPoolCapacity" type="xsd:integer" minOccurs="1" nillable="false"/>
+ <xsd:element name="maxWaitTimeout" type="xsd:long" minOccurs="1" nillable="false"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="ConnectResponse"/>
+ </xsd:schema>
+ </wsdl:types>
+
+ <wsdl:message name="SubscribeRequest">
+ <wsdl:part name="SubscribeRequest" element="wsnt:Subscribe" />
+ </wsdl:message>
+
+ <wsdl:message name="SubscribeResponse">
+ <wsdl:part name="SubscribeResponse"
+ element="wsnt:SubscribeResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="SubscribeCreationFailedFault">
+ <wsdl:part name="SubscribeCreationFailedFault"
+ element="wsnt:SubscribeCreationFailedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="TopicExpressionDialectUnknownFault">
+ <wsdl:part name="TopicExpressionDialectUnknownFault"
+ element="wsnt:TopicExpressionDialectUnknownFault" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidFilterFault">
+ <wsdl:part name="InvalidFilterFault"
+ element="wsnt:InvalidFilterFault" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidProducerPropertiesExpressionFault">
+ <wsdl:part name="InvalidProducerPropertiesExpressionFault"
+ element="wsnt:InvalidProducerPropertiesExpressionFault" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidMessageContentExpressionFault">
+ <wsdl:part name="InvalidMessageContentExpressionFault"
+ element="wsnt:InvalidMessageContentExpressionFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnrecognizedPolicyRequestFault">
+ <wsdl:part name="UnrecognizedPolicyRequestFault"
+ element="wsnt:UnrecognizedPolicyRequestFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnsupportedPolicyRequestFault">
+ <wsdl:part name="UnsupportedPolicyRequestFault"
+ element="wsnt:UnsupportedPolicyRequestFault" />
+ </wsdl:message>
+
+ <wsdl:message name="NotifyMessageNotSupportedFault">
+ <wsdl:part name="NotifyMessageNotSupportedFault"
+ element="wsnt:NotifyMessageNotSupportedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnacceptableInitialTerminationTimeFault">
+ <wsdl:part name="UnacceptableInitialTerminationTimeFault"
+ element="wsnt:UnacceptableInitialTerminationTimeFault" />
+ </wsdl:message>
+
+ <!-- ========== NotificationProducer::GetCurrentMessage ===========
+ GetCurrentMessage(topicExpression)
+ returns: a NotificationMessage (xsd:any)
+ -->
+ <wsdl:message name="GetCurrentMessageRequest">
+ <wsdl:part name="GetCurrentMessageRequest"
+ element="wsnt:GetCurrentMessage" />
+ </wsdl:message>
+
+ <wsdl:message name="GetCurrentMessageResponse">
+ <wsdl:part name="GetCurrentMessageResponse"
+ element="wsnt:GetCurrentMessageResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidTopicExpressionFault">
+ <wsdl:part name="InvalidTopicExpressionFault"
+ element="wsnt:InvalidTopicExpressionFault" />
+ </wsdl:message>
+
+ <wsdl:message name="TopicNotSupportedFault">
+ <wsdl:part name="TopicNotSupportedFault"
+ element="wsnt:TopicNotSupportedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="MultipleTopicsSpecifiedFault">
+ <wsdl:part name="MultipleTopicsSpecifiedFault"
+ element="wsnt:MultipleTopicsSpecifiedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="NoCurrentMessageOnTopicFault">
+ <wsdl:part name="NoCurrentMessageOnTopicFault"
+ element="wsnt:NoCurrentMessageOnTopicFault" />
+ </wsdl:message>
+
+
+
+ <wsdl:message name="OperationInvocationFaultMessage">
+ <wsdl:part name="OperationInvocationFault" element="qman:OperationInvocationFault" />
+ </wsdl:message>
+ <wsdl:message name="EntityInstanceNotFoundFaultMessage">
+ <wsdl:part name="EntityInstanceNotFound" element="qman:EntityInstanceNotFoundFault" />
+ </wsdl:message>
+ <wsdl:message name="MalformedEntityNameFaultMessage">
+ <wsdl:part name="MalformedEntityName" element="qman:MalformedEntityNameFault" />
+ </wsdl:message>
+ <wsdl:message name="NoSuchAttributeFaultMessage">
+ <wsdl:part name="NoSuchAttributeFault" element="qman:NoSuchAttributeFault" />
+ </wsdl:message>
+ <wsdl:message name="ConnectRequestMessage">
+ <wsdl:part name="ConnectRequest" element="qman:Connect" />
+ </wsdl:message>
+ <wsdl:message name="ConnectResponseMessage">
+ <wsdl:part name="ConnectResponse" element="qman:ConnectResponse" />
+ </wsdl:message>
+ <wsdl:message name="InvalidResourcePropertyQNameFault">
+ <wsdl:part name="InvalidResourcePropertyQNameFault" element="wsrf-rp:InvalidResourcePropertyQNameFault" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnknownFault">
+ <wsdl:part name="ResourceUnknownFault" element="wsrf-r:ResourceUnknownFault" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnavailableFault">
+ <wsdl:part name="ResourceUnavailableFault" element="wsrf-r:ResourceUnavailableFault" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentRequest">
+ <wsdl:part name="GetResourcePropertyDocumentRequest" element="wsrf-rp:GetResourcePropertyDocument"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentResponse">
+ <wsdl:part name="GetResourcePropertyDocumentResponse" element="wsrf-rp:GetResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesRequest">
+ <wsdl:part name="GetMultipleResourcePropertiesRequest" element="wsrf-rp:GetMultipleResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesResponse">
+ <wsdl:part name="GetMultipleResourcePropertiesResponse" element="wsrf-rp:GetMultipleResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyRequest">
+ <wsdl:part name="GetResourcePropertyRequest" element="wsrf-rp:GetResourceProperty" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyResponse">
+ <wsdl:part name="GetResourcePropertyResponse" element="wsrf-rp:GetResourcePropertyResponse" />
+ </wsdl:message>
+ <wsdl:message name="GetMetadataRequestMessage">
+ <wsdl:part name="GetMetadataMsg" element="wsx:GetMetadata" />
+ </wsdl:message>
+ <wsdl:message name="GetMetadataResponseMessage">
+ <wsdl:part name="GetMetadataResponseMsg" element="wsx:Metadata" />
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesRequest">
+ <wsdl:part name="QueryResourcePropertiesRequest" element="wsrf-rp:QueryResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesResponse">
+ <wsdl:part name="QueryResourcePropertiesResponse" element="wsrf-rp:QueryResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:message name="UnknownQueryExpressionDialectFault">
+ <wsdl:part name="UnknownQueryExpressionDialectFault" element="wsrf-rp:UnknownQueryExpressionDialectFault" />
+ </wsdl:message>
+ <wsdl:message name="InvalidQueryExpressionFault">
+ <wsdl:part name="InvalidQueryExpressionFault" element="wsrf-rp:InvalidQueryExpressionFault" />
+ </wsdl:message>
+ <wsdl:message name="QueryEvaluationErrorFault">
+ <wsdl:part name="QueryEvaluationErrorFault" element="wsrf-rp:QueryEvaluationErrorFault" />
+ </wsdl:message>
+ <wsdl:portType
+ name="QManAdapterPortType"
+ wsrf-rp:ResourceProperties="qman:WsDmAdapterResourceProperties"
+ wsrmd:Descriptor="WsDmAdapterMetadata" wsrmd:DescriptorLocation="QManAdapter.rmd">
+
+ <wsdl:operation name="Subscribe">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeRequest"
+ message="qman:SubscribeRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeResponse"
+ message="qman:SubscribeResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="qman:ResourceUnknownFault" />
+ <wsdl:fault name="InvalidFilterFault"
+ message="qman:InvalidFilterFault" />
+ <wsdl:fault name="TopicExpressionDialectUnknownFault"
+ message="qman:TopicExpressionDialectUnknownFault" />
+ <wsdl:fault name="InvalidTopicExpressionFault"
+ message="qman:InvalidTopicExpressionFault" />
+ <wsdl:fault name="TopicNotSupportedFault"
+ message="qman:TopicNotSupportedFault" />
+ <wsdl:fault name="InvalidProducerPropertiesExpressionFault"
+ message="qman:InvalidProducerPropertiesExpressionFault" />
+ <wsdl:fault name="InvalidMessageContentExpressionFault"
+ message="qman:InvalidMessageContentExpressionFault" />
+ <wsdl:fault name="UnacceptableInitialTerminationTimeFault"
+ message="qman:UnacceptableInitialTerminationTimeFault" />
+ <wsdl:fault name="UnrecognizedPolicyRequestFault"
+ message="qman:UnrecognizedPolicyRequestFault" />
+ <wsdl:fault name="UnsupportedPolicyRequestFault"
+ message="qman:UnsupportedPolicyRequestFault" />
+ <wsdl:fault name="NotifyMessageNotSupportedFault"
+ message="qman:NotifyMessageNotSupportedFault" />
+ <wsdl:fault name="SubscribeCreationFailedFault"
+ message="qman:SubscribeCreationFailedFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetCurrentMessage">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/GetCurrentMessageRequest"
+ message="qman:GetCurrentMessageRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/GetCurrentMessageResponse"
+ message="qman:GetCurrentMessageResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="qman:ResourceUnknownFault" />
+ <wsdl:fault name="TopicExpressionDialectUnknownFault"
+ message="qman:TopicExpressionDialectUnknownFault" />
+ <wsdl:fault name="InvalidTopicExpressionFault"
+ message="qman:InvalidTopicExpressionFault" />
+ <wsdl:fault name="TopicNotSupportedFault"
+ message="qman:TopicNotSupportedFault" />
+ <wsdl:fault name="NoCurrentMessageOnTopicFault"
+ message="qman:NoCurrentMessageOnTopicFault" />
+ <wsdl:fault name="MultipleTopicsSpecifiedFault"
+ message="qman:MultipleTopicsSpecifiedFault" />
+ </wsdl:operation>
+
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesRequest"
+ name="QueryResourcePropertiesRequest"
+ message="qman:QueryResourcePropertiesRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesResponse"
+ name="QueryResourcePropertiesResponse"
+ message="qman:QueryResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault" message="qman:UnknownQueryExpressionDialectFault"/>
+ <wsdl:fault name="InvalidQueryExpressionFault" message="qman:InvalidQueryExpressionFault"/>
+ <wsdl:fault name="QueryEvaluationErrorFault" message="qman:QueryEvaluationErrorFault" />
+ </wsdl:operation>
+ <wsdl:operation name="Connect">
+ <wsdl:documentation>
+ Connects QMan with a new broker.
+ </wsdl:documentation>
+ <wsdl:input
+ wsa:Action="http://amqp.apache.org/qpid/management/qman/Connect"
+ name="ConnectRequestInput"
+ message="qman:ConnectRequestMessage" />
+ <wsdl:output
+ wsa:Action="http://amqp.apache.org/qpid/management/qman/ConnectResponse"
+ name="ConnectResponseOutput"
+ message="qman:ConnectResponseMessage" />
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:documentation>
+ Returns an array containing values for the requested properties.
+ Note that using this method it's possibile to retrieve only the value of the QManService properties.
+ That is : this method is not supposed to be used for retrieve attributes of the QMan managed entities. For that, the GetManagedEntityAttributeValue must be used.</wsdl:documentation>
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"
+ name="GetMultipleResourcePropertiesRequest"
+ message="qman:GetMultipleResourcePropertiesRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse"
+ name="GetMultipleResourcePropertiesResponse"
+ message="qman:GetMultipleResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="qman:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:documentation>
+ Returns resource's entire WS-RP document, with the most up-to-date values of all properties. Note that using this method it's possibile to retrieve only the value of the QManService properties.
+ That is : this method is not supposed to be used for retrieve attributes of the QMan managed entities. For that, the GetManagedEntityAttributeValue must be used.</wsdl:documentation>
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"
+ name="GetResourcePropertyDocumentRequest"
+ message="qman:GetResourcePropertyDocumentRequest"/>
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse"
+ name="GetResourcePropertyDocumentResponse"
+ message="qman:GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:documentation>
+ Returns the value of the given property. Note that using this method it's possibile to retrieve only the value of the QManService properties.
+ That is : this method is not supposed to be used for retrieve attributes of the QMan managed entities. For that, the GetManagedEntityAttributeValue must be used.
+ </wsdl:documentation>
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"
+ name="GetResourcePropertyRequest"
+ message="qman:GetResourcePropertyRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse"
+ name="GetResourcePropertyResponse"
+ message="qman:GetResourcePropertyResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="qman:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetMetadata">
+ <wsdl:documentation>
+ Implementation of the WS-MetadataExchange GetMetadata port type. Note that the only supported metadata type (dialect) is WSDL.
+ </wsdl:documentation>
+ <wsdl:input
+ wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata"
+ name="GetMetadataMsg"
+ message="qman:GetMetadataRequestMessage"/>
+ <wsdl:output
+ wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse"
+ name="GetMetadataResponseMsg"
+ message="qman:GetMetadataResponseMessage"/>
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="QManAdapterBinding" type="qman:QManAdapterPortType">
+ <wsdl-soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="Subscribe">
+ <wsdl-soap:operation
+ soapAction="http://ws.apache.org/muse/test/wsrf/Subscribe" />
+ <wsdl:input>
+ <wsdl-soap:body use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="ResourceUnknownFault" />
+ </wsdl:fault>
+ <wsdl:fault name="InvalidFilterFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="InvalidFilterFault" />
+ </wsdl:fault>
+ <wsdl:fault name="TopicExpressionDialectUnknownFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="TopicExpressionDialectUnknownFault" />
+ </wsdl:fault>
+ <wsdl:fault name="InvalidTopicExpressionFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="InvalidTopicExpressionFault" />
+ </wsdl:fault>
+ <wsdl:fault name="TopicNotSupportedFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="TopicNotSupportedFault" />
+ </wsdl:fault>
+ <wsdl:fault
+ name="InvalidProducerPropertiesExpressionFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="InvalidProducerPropertiesExpressionFault" />
+ </wsdl:fault>
+ <wsdl:fault name="InvalidMessageContentExpressionFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="InvalidMessageContentExpressionFault" />
+ </wsdl:fault>
+ <wsdl:fault
+ name="UnacceptableInitialTerminationTimeFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="UnacceptableInitialTerminationTimeFault" />
+ </wsdl:fault>
+ <wsdl:fault name="UnrecognizedPolicyRequestFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="UnrecognizedPolicyRequestFault" />
+ </wsdl:fault>
+ <wsdl:fault name="UnsupportedPolicyRequestFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="UnsupportedPolicyRequestFault" />
+ </wsdl:fault>
+ <wsdl:fault name="NotifyMessageNotSupportedFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="NotifyMessageNotSupportedFault" />
+ </wsdl:fault>
+ <wsdl:fault name="SubscribeCreationFailedFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="SubscribeCreationFailedFault" />
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetCurrentMessage">
+ <wsdl-soap:operation
+ soapAction="http://ws.apache.org/muse/test/wsrf/GetCurrentMessage" />
+ <wsdl:input>
+ <wsdl-soap:body use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="ResourceUnknownFault" />
+ </wsdl:fault>
+ <wsdl:fault name="TopicExpressionDialectUnknownFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="TopicExpressionDialectUnknownFault" />
+ </wsdl:fault>
+ <wsdl:fault name="InvalidTopicExpressionFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="InvalidTopicExpressionFault" />
+ </wsdl:fault>
+ <wsdl:fault name="TopicNotSupportedFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="TopicNotSupportedFault" />
+ </wsdl:fault>
+ <wsdl:fault name="NoCurrentMessageOnTopicFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="NoCurrentMessageOnTopicFault" />
+ </wsdl:fault>
+ <wsdl:fault name="MultipleTopicsSpecifiedFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="MultipleTopicsSpecifiedFault" />
+ </wsdl:fault>
+ </wsdl:operation>
+
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl-soap:operation soapAction="QueryResourceProperties"/>
+ <wsdl:input name="QueryResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input>
+ <wsdl:output name="QueryResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="UnknownQueryExpressionDialectFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidQueryExpressionFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="InvalidQueryExpressionFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="QueryEvaluationErrorFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="QueryEvaluationErrorFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="Connect">
+ <wsdl-soap:operation soapAction="Connect" />
+ <wsdl:input>
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl-soap:operation soapAction="GetMultipleResourceProperties"/>
+ <wsdl:input name="GetMultipleResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input>
+ <wsdl:output name="GetMultipleResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl-soap:operation soapAction="GetResourcePropertyDocument"/>
+ <wsdl:input name="GetResourcePropertyDocumentRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input>
+ <wsdl:output name="GetResourcePropertyDocumentResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl-soap:operation soapAction="GetResourceProperty"/>
+ <wsdl:input name="GetResourcePropertyRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input>
+ <wsdl:output name="GetResourcePropertyResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="GetMetadata" />
+ <wsdl:input>
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="QManAdapterService">
+ <wsdl:port name="QManAdapterPort" binding="qman:QManAdapterBinding">
+ <wsdl-soap:address location="http://romagazzarini:8080/qman/services/adapter"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/QManWsResource.rmd b/qpid/java/management/client/src/main/java/wsdl/QManWsResource.rmd
new file mode 100644
index 0000000000..c4944440e0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/QManWsResource.rmd
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<Definitions xmlns="http://docs.oasis-open.org/wsrf/rmd-1" >
+ <MetadataDescriptor
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"
+ xmlns:wst="http://docs.oasis-open.org/wsn/t-1"
+ xmlns:muws1="http://docs.oasis-open.org/wsdm/muws1-2.xsd"
+ xmlns:muws2="http://docs.oasis-open.org/wsdm/muws2-2.xsd"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman"
+ name="QManWsResourceMetadata"
+ interface="qman:QManWsResourcePortType"
+ wsdlLocation="http://ws.apache.org/muse/test/wsrf QManWsResource.wsdl" >
+ <Property name="wsrf-rp:QueryExpressionDialect" modifiability="read-only" mutability="constant" />
+ </MetadataDescriptor>
+
+</Definitions> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl b/qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl
new file mode 100644
index 0000000000..16169c9b78
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl
@@ -0,0 +1,507 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions
+ targetNamespace="http://amqp.apache.org/qpid/management/qman"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsdl-soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ name="QManWsResource">
+ <wsdl:types>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://www.w3.org/2005/08/addressing">
+ <xsd:include schemaLocation="WS-Addressing-2005_08.xsd"/>
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <xsd:include schemaLocation="WS-MetadataExchange-2004_09.xsd"/>
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rl-2">
+ <xsd:include schemaLocation="WS-ResourceLifetime-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rp-2">
+ <xsd:include schemaLocation="WS-ResourceProperties-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/r-2">
+ <xsd:include schemaLocation="WS-Resource-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rmd-1">
+ <xsd:include schemaLocation="WS-ResourceMetadataDescriptor-CD-01.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://amqp.apache.org/qpid/management/qman">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rl-2" schemaLocation="WS-ResourceLifetime-1_2.xsd"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rp-2" schemaLocation="WS-ResourceProperties-1_2.xsd"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2" schemaLocation="WS-BaseFaults-1_2.xsd"/>
+ <xsd:element name="QManWsResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:QueryExpressionDialect" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="QManFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="MethodInvocationFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="EntityInstanceNotFoundFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="MalformedEntityNameFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="NoSuchAttributeFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="uuid">
+ <xsd:sequence>
+ <xsd:element name="uuid" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="map">
+ <xsd:sequence>
+ <xsd:element name="entry" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="key" type="xsd:string"/>
+ <xsd:element name="value" type="xsd:anyType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="result">
+ <xsd:sequence>
+ <xsd:element name="outputParameters" type="qman:map"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ </xsd:schema>
+ </wsdl:types>
+ <wsdl:message name="GetMetadataMsg">
+ <wsdl:part name="GetMetadataMsg" element="wsx:GetMetadata" />
+ </wsdl:message>
+ <wsdl:message name="GetMetadataResponseMsg">
+ <wsdl:part name="GetMetadataResponseMsg" element="wsx:Metadata" />
+ </wsdl:message>
+ <wsdl:message name="DestroyRequest">
+ <wsdl:part name="DestroyRequest" element="wsrf-rl:Destroy" />
+ </wsdl:message>
+ <wsdl:message name="DestroyResponse">
+ <wsdl:part name="DestroyResponse" element="wsrf-rl:DestroyResponse" />
+ </wsdl:message>
+ <wsdl:message name="ResourceNotDestroyedFault">
+ <wsdl:part name="ResourceNotDestroyedFault" element="wsrf-rl:ResourceNotDestroyedFault" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnknownFault">
+ <wsdl:part name="ResourceUnknownFault" element="wsrf-r:ResourceUnknownFault" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnavailableFault">
+ <wsdl:part name="ResourceUnavailableFault" element="wsrf-r:ResourceUnavailableFault" />
+ </wsdl:message>
+ <wsdl:message name="UnableToPutResourcePropertyDocumentFault">
+ <wsdl:part name="UnableToPutResourcePropertyDocumentFault" element="wsrf-rp:UnableToPutResourcePropertyDocumentFault" />
+ </wsdl:message>
+ <wsdl:message name="PutResourcePropertyDocumentRequest">
+ <wsdl:part name="PutResourcePropertyDocumentRequest" element="wsrf-rp:PutResourcePropertyDocument"/>
+ </wsdl:message>
+ <wsdl:message name="PutResourcePropertyDocumentResponse">
+ <wsdl:part name="PutResourcePropertyDocumentResponse" element="wsrf-rp:PutResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentRequest">
+ <wsdl:part name="GetResourcePropertyDocumentRequest" element="wsrf-rp:GetResourcePropertyDocument"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentResponse">
+ <wsdl:part name="GetResourcePropertyDocumentResponse" element="wsrf-rp:GetResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyRequest">
+ <wsdl:part name="GetResourcePropertyRequest" element="wsrf-rp:GetResourceProperty" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyResponse">
+ <wsdl:part name="GetResourcePropertyResponse" element="wsrf-rp:GetResourcePropertyResponse" />
+ </wsdl:message>
+ <wsdl:message name="InvalidResourcePropertyQNameFault">
+ <wsdl:part name="InvalidResourcePropertyQNameFault" element="wsrf-rp:InvalidResourcePropertyQNameFault" />
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesRequest">
+ <wsdl:part name="GetMultipleResourcePropertiesRequest" element="wsrf-rp:GetMultipleResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesResponse">
+ <wsdl:part name="GetMultipleResourcePropertiesResponse" element="wsrf-rp:GetMultipleResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesRequest">
+ <wsdl:part name="QueryResourcePropertiesRequest" element="wsrf-rp:QueryResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesResponse">
+ <wsdl:part name="QueryResourcePropertiesResponse" element="wsrf-rp:QueryResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:message name="UnknownQueryExpressionDialectFault">
+ <wsdl:part name="UnknownQueryExpressionDialectFault" element="wsrf-rp:UnknownQueryExpressionDialectFault" />
+ </wsdl:message>
+ <wsdl:message name="InvalidQueryExpressionFault">
+ <wsdl:part name="InvalidQueryExpressionFault" element="wsrf-rp:InvalidQueryExpressionFault" />
+ </wsdl:message>
+ <wsdl:message name="QueryEvaluationErrorFault">
+ <wsdl:part name="QueryEvaluationErrorFault" element="wsrf-rp:QueryEvaluationErrorFault" />
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertiesRequest">
+ <wsdl:part name="SetResourcePropertiesRequest" element="wsrf-rp:SetResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertiesResponse">
+ <wsdl:part name="SetResourcePropertiesResponse" element="wsrf-rp:SetResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:message name="InvalidModificationFault">
+ <wsdl:part name="InvalidModificationFault" element="wsrf-rp:InvalidModificationFault" />
+ </wsdl:message>
+ <wsdl:message name="UnableToModifyResourcePropertyFault">
+ <wsdl:part name="UnableToModifyResourcePropertyFault" element="wsrf-rp:UnableToModifyResourcePropertyFault" />
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertyRequestFailedFault">
+ <wsdl:part name="SetResourcePropertyRequestFailedFault" element="wsrf-rp:SetResourcePropertyRequestFailedFault" />
+ </wsdl:message>
+ <wsdl:portType
+ name="QManWsResourcePortType"
+ wsrf-rp:ResourceProperties="qman:QManWsResourceProperties"
+ wsrmd:Descriptor="QManWsResourceMetadata"
+ wsrmd:DescriptorLocation="QManWsResource.rmd">
+ <wsdl:operation name="GetMetadata">
+ <wsdl:input
+ wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata"
+ name="GetMetadataMsg"
+ message="qman:GetMetadataMsg"/>
+ <wsdl:output
+ wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse"
+ name="GetMetadataResponseMsg"
+ message="qman:GetMetadataResponseMsg"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"
+ name="GetResourcePropertyDocumentRequest"
+ message="qman:GetResourcePropertyDocumentRequest"/>
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse"
+ name="GetResourcePropertyDocumentResponse"
+ message="qman:GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="PutResourcePropertyDocument">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/PutResourcePropertyDocument/PutResourcePropertyDocumentRequest"
+ name="PutResourcePropertyDocumentRequest"
+ message="qman:PutResourcePropertyDocumentRequest"/>
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/PutResourcePropertyDocument/PutResourcePropertyDocumentResponse"
+ name="PutResourcePropertyDocumentResponse"
+ message="qman:PutResourcePropertyDocumentResponse"/>
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="UnableToPutResourcePropertyDocumentFault" message="qman:UnableToPutResourcePropertyDocumentFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"
+ name="GetResourcePropertyRequest"
+ message="qman:GetResourcePropertyRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse"
+ name="GetResourcePropertyResponse"
+ message="qman:GetResourcePropertyResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="qman:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"
+ name="GetMultipleResourcePropertiesRequest"
+ message="qman:GetMultipleResourcePropertiesRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse"
+ name="GetMultipleResourcePropertiesResponse"
+ message="qman:GetMultipleResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="qman:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesRequest"
+ name="QueryResourcePropertiesRequest"
+ message="qman:QueryResourcePropertiesRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesResponse"
+ name="QueryResourcePropertiesResponse"
+ message="qman:QueryResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault" message="qman:UnknownQueryExpressionDialectFault"/>
+ <wsdl:fault name="InvalidQueryExpressionFault" message="qman:InvalidQueryExpressionFault"/>
+ <wsdl:fault name="QueryEvaluationErrorFault" message="qman:QueryEvaluationErrorFault" />
+ </wsdl:operation>
+ <wsdl:operation name="SetResourceProperties">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesRequest"
+ name="SetResourcePropertiesRequest"
+ message="qman:SetResourcePropertiesRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesResponse"
+ name="SetResourcePropertiesResponse"
+ message="qman:SetResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidModificationFault" message="qman:InvalidModificationFault" />
+ <wsdl:fault name="UnableToModifyResourcePropertyFault" message="qman:UnableToModifyResourcePropertyFault" />
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="qman:InvalidResourcePropertyQNameFault" />
+ <wsdl:fault name="SetResourcePropertyRequestFailedFault" message="qman:SetResourcePropertyRequestFailedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="QManWsResourceBinding" type="qman:QManWsResourcePortType">
+ <wsdl-soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="GetMetadata" />
+ <wsdl:input>
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="PutResourcePropertyDocument">
+ <wsdl-soap:operation soapAction="PutResourcePropertyDocument"/>
+ <wsdl:input name="PutResourcePropertyDocumentRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input>
+ <wsdl:output name="PutResourcePropertyDocumentResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnableToPutResourcePropertyDocumentFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="UnableToPutResourcePropertyDocumentFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl-soap:operation soapAction="GetResourcePropertyDocument"/>
+ <wsdl:input name="GetResourcePropertyDocumentRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetResourcePropertyDocumentResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl-soap:operation soapAction="GetResourceProperty"/>
+ <wsdl:input name="GetResourcePropertyRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetResourcePropertyResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl-soap:operation soapAction="GetMultipleResourceProperties"/>
+ <wsdl:input name="GetMultipleResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetMultipleResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl-soap:operation soapAction="QueryResourceProperties"/>
+ <wsdl:input name="QueryResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="QueryResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="UnknownQueryExpressionDialectFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidQueryExpressionFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="InvalidQueryExpressionFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="QueryEvaluationErrorFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="QueryEvaluationErrorFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="SetResourceProperties">
+ <wsdl-soap:operation soapAction="http://oasis.org/SetResourceProperties"/>
+ <wsdl:input name="SetResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="SetResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidModificationFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="InvalidModificationFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnableToModifyResourcePropertyFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="UnableToModifyResourcePropertyFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="SetResourcePropertyRequestFailedFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="SetResourcePropertyRequestFailedFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="QManWsResourceService">
+ <wsdl:port name="QManWsResourcePort" binding="qman:QManWsResourceBinding">
+ <wsdl-soap:address location="http://localhost:8080/qman/services/QManWsResource"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/SOAP-Envelope-1_2.xsd b/qpid/java/management/client/src/main/java/wsdl/SOAP-Envelope-1_2.xsd
new file mode 100644
index 0000000000..ab38b1b7f2
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/SOAP-Envelope-1_2.xsd
@@ -0,0 +1,181 @@
+<?xml version="1.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.
+
+-->
+
+
+<!-- Schema defined in the SOAP Version 1.2 Part 1 specification
+ Proposed Recommendation:
+ http://www.w3.org/TR/2003/PR-soap12-part1-20030507/
+ $Id: SOAP-Envelope-1_2.xsd,v 1.1 2006/05/07 19:09:15 danjemiolo Exp $
+
+ Copyright (C)2003 W3C(R) (MIT, ERCIM, Keio), All Rights Reserved.
+ W3C viability, trademark, document use and software licensing rules
+ apply.
+ http://www.w3.org/Consortium/Legal/
+
+ This document is governed by the W3C Software License [1] as
+ described in the FAQ [2].
+
+ [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
+ [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
+-->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:tns="http://www.w3.org/2003/05/soap-envelope"
+ targetNamespace="http://www.w3.org/2003/05/soap-envelope"
+ elementFormDefault="qualified">
+
+ <xs:import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="XML-Namespace-1998.xsd"/>
+
+ <!-- Envelope, header and body -->
+ <xs:element name="Envelope" type="tns:Envelope"/>
+ <xs:complexType name="Envelope">
+ <xs:sequence>
+ <xs:element ref="tns:Header" minOccurs="0"/>
+ <xs:element ref="tns:Body" minOccurs="1"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <xs:element name="Header" type="tns:Header"/>
+ <xs:complexType name="Header">
+ <xs:annotation>
+ <xs:documentation>
+ Elements replacing the wildcard MUST be namespace qualified, but can be in the targetNamespace
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <xs:element name="Body" type="tns:Body"/>
+ <xs:complexType name="Body">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <!-- Global Attributes. The following attributes are intended to be
+ usable via qualified attribute names on any complex type referencing
+ them. -->
+ <xs:attribute name="mustUnderstand" type="xs:boolean" default="0"/>
+ <xs:attribute name="relay" type="xs:boolean" default="0"/>
+ <xs:attribute name="role" type="xs:anyURI"/>
+
+ <!-- 'encodingStyle' indicates any canonicalization conventions
+ followed in the contents of the containing element. For example, the
+ value 'http://www.w3.org/2003/05/soap-encoding' indicates the pattern
+ described in the last call working draft of SOAP Version 1.2 Part 2:
+ Adjuncts -->
+
+ <xs:attribute name="encodingStyle" type="xs:anyURI"/>
+
+ <xs:element name="Fault" type="tns:Fault"/>
+ <xs:complexType name="Fault" final="extension">
+ <xs:annotation>
+ <xs:documentation>
+ Fault reporting structure
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Code" type="tns:faultcode"/>
+ <xs:element name="Reason" type="tns:faultreason"/>
+ <xs:element name="Node" type="xs:anyURI" minOccurs="0"/>
+ <xs:element name="Role" type="xs:anyURI" minOccurs="0"/>
+ <xs:element name="Detail" type="tns:detail" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="faultreason">
+ <xs:sequence>
+ <xs:element name="Text" type="tns:reasontext"
+ minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="reasontext">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute ref="xml:lang" use="required"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="faultcode">
+ <xs:sequence>
+ <xs:element name="Value"
+ type="tns:faultcodeEnum"/>
+ <xs:element name="Subcode"
+ type="tns:subcode"
+ minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="faultcodeEnum">
+ <xs:restriction base="xs:QName">
+ <xs:enumeration value="tns:DataEncodingUnknown"/>
+ <xs:enumeration value="tns:MustUnderstand"/>
+ <xs:enumeration value="tns:Receiver"/>
+ <xs:enumeration value="tns:Sender"/>
+ <xs:enumeration value="tns:VersionMismatch"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="subcode">
+ <xs:sequence>
+ <xs:element name="Value"
+ type="xs:QName"/>
+ <xs:element name="Subcode"
+ type="tns:subcode"
+ minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="detail">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <!-- Global element declaration and complex type definition for header entry returned due to a mustUnderstand fault -->
+ <xs:element name="NotUnderstood" type="tns:NotUnderstoodType"/>
+ <xs:complexType name="NotUnderstoodType">
+ <xs:attribute name="qname" type="xs:QName" use="required"/>
+ </xs:complexType>
+
+ <!-- Global element and associated types for managing version transition as described in Appendix A of the SOAP Version 1.2 Part 1 Last Call Working Draft -->
+ <xs:complexType name="SupportedEnvType">
+ <xs:attribute name="qname" type="xs:QName" use="required"/>
+ </xs:complexType>
+
+ <xs:element name="Upgrade" type="tns:UpgradeType"/>
+ <xs:complexType name="UpgradeType">
+ <xs:sequence>
+ <xs:element name="SupportedEnvelope" type="tns:SupportedEnvType" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+</xs:schema>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-Addressing-2005_08.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-Addressing-2005_08.xsd
new file mode 100644
index 0000000000..04b4a688b3
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-Addressing-2005_08.xsd
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<xs:schema
+ targetNamespace="http://www.w3.org/2005/08/addressing"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:tns="http://www.w3.org/2005/08/addressing"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified">
+
+ <!-- Constructs from the WS-Addressing Core -->
+
+ <xs:element name="EndpointReference"
+ type="tns:EndpointReferenceType" />
+ <xs:complexType name="EndpointReferenceType" mixed="false">
+ <xs:sequence>
+ <xs:element name="Address" type="tns:AttributedURIType" />
+ <xs:element name="ReferenceParameters"
+ type="tns:ReferenceParametersType" minOccurs="0" />
+ <xs:element ref="tns:Metadata" minOccurs="0" />
+ <xs:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+ <xs:complexType name="ReferenceParametersType" mixed="false">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+ <xs:element name="Metadata" type="tns:MetadataType" />
+ <xs:complexType name="MetadataType" mixed="false">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+ <xs:element name="MessageID" type="tns:AttributedURIType" />
+ <xs:element name="RelatesTo" type="tns:RelatesToType" />
+ <xs:complexType name="RelatesToType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute name="RelationshipType"
+ type="tns:RelationshipTypeOpenEnum" use="optional"
+ default="http://www.w3.org/2005/08/addressing/reply" />
+ <xs:anyAttribute namespace="##other"
+ processContents="lax" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="RelationshipTypeOpenEnum">
+ <xs:union memberTypes="tns:RelationshipType xs:anyURI" />
+ </xs:simpleType>
+
+ <xs:simpleType name="RelationshipType">
+ <xs:restriction base="xs:anyURI">
+ <xs:enumeration
+ value="http://www.w3.org/2005/08/addressing/reply" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="ReplyTo" type="tns:EndpointReferenceType" />
+ <xs:element name="From" type="tns:EndpointReferenceType" />
+ <xs:element name="FaultTo" type="tns:EndpointReferenceType" />
+ <xs:element name="To" type="tns:AttributedURIType" />
+ <xs:element name="Action" type="tns:AttributedURIType" />
+
+ <xs:complexType name="AttributedURIType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:anyAttribute namespace="##other"
+ processContents="lax" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <!-- Constructs from the WS-Addressing SOAP binding -->
+
+ <xs:attribute name="IsReferenceParameter" type="xs:boolean" />
+
+ <xs:simpleType name="FaultCodesOpenEnumType">
+ <xs:union memberTypes="tns:FaultCodesType xs:QName" />
+ </xs:simpleType>
+
+ <xs:simpleType name="FaultCodesType">
+ <xs:restriction base="xs:QName">
+ <xs:enumeration value="tns:InvalidAddressingHeader" />
+ <xs:enumeration value="tns:InvalidAddress" />
+ <xs:enumeration value="tns:InvalidEPR" />
+ <xs:enumeration value="tns:InvalidCardinality" />
+ <xs:enumeration value="tns:MissingAddressInEPR" />
+ <xs:enumeration value="tns:DuplicateMessageID" />
+ <xs:enumeration value="tns:ActionMismatch" />
+ <xs:enumeration value="tns:MessageAddressingHeaderRequired" />
+ <xs:enumeration value="tns:DestinationUnreachable" />
+ <xs:enumeration value="tns:ActionNotSupported" />
+ <xs:enumeration value="tns:EndpointUnavailable" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="RetryAfter" type="tns:AttributedUnsignedLongType" />
+ <xs:complexType name="AttributedUnsignedLongType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:unsignedLong">
+ <xs:anyAttribute namespace="##other"
+ processContents="lax" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:element name="ProblemHeaderQName"
+ type="tns:AttributedQNameType" />
+ <xs:complexType name="AttributedQNameType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:QName">
+ <xs:anyAttribute namespace="##other"
+ processContents="lax" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:element name="ProblemHeader" type="tns:AttributedAnyType" />
+ <xs:complexType name="AttributedAnyType" mixed="false">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"
+ minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+ <xs:element name="ProblemIRI" type="tns:AttributedURIType" />
+
+ <xs:element name="ProblemAction" type="tns:ProblemActionType" />
+ <xs:complexType name="ProblemActionType" mixed="false">
+ <xs:sequence>
+ <xs:element ref="tns:Action" minOccurs="0" />
+ <xs:element name="SoapAction" minOccurs="0"
+ type="xs:anyURI" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+</xs:schema>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-BaseFaults-1_2.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-BaseFaults-1_2.xsd
new file mode 100644
index 0000000000..665797e486
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-BaseFaults-1_2.xsd
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+-->
+
+<xsd:schema
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-bf=
+ "http://docs.oasis-open.org/wsrf/bf-2"
+ elementFormDefault="qualified" attributeFormDefault="unqualified"
+ targetNamespace=
+ "http://docs.oasis-open.org/wsrf/bf-2">
+ <xsd:import
+ namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="WS-Addressing-2005_08.xsd"/>
+
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="XML-Namespace-1998.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ Get access to the xml: attribute groups for xml:lang as declared on 'schema'
+ and 'documentation' below
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:import>
+<!-- ====================== BaseFault Types ======================= -->
+
+ <xsd:element name="BaseFault" type="wsrf-bf:BaseFaultType"/>
+
+ <xsd:complexType name="BaseFaultType">
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="Timestamp" type="xsd:dateTime"
+ minOccurs="1" maxOccurs="1"/>
+ <xsd:element name="Originator" type="wsa:EndpointReferenceType"
+ minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="ErrorCode"
+ minOccurs="0" maxOccurs="1">
+ <xsd:complexType>
+ <xsd:complexContent mixed="true">
+ <xsd:extension base="xsd:anyType">
+ <xsd:attribute name="dialect" type="xsd:anyURI"
+ use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="Description"
+ minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute ref="xml:lang" use="optional"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="FaultCause" minOccurs="0" maxOccurs="1">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="1" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+</xsd:schema>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl b/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl
new file mode 100644
index 0000000000..d53bf60f3a
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl
@@ -0,0 +1,449 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2004-2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+<wsdl:definitions name="WS-BaseNotification"
+ targetNamespace="http://docs.oasis-open.org/wsn/bw-2"
+ xmlns:wsntw="http://docs.oasis-open.org/wsn/bw-2"
+ xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-rw="http://docs.oasis-open.org/wsrf/rw-2"
+ xmlns:wsrf-rlw="http://docs.oasis-open.org/wsrf/rlw-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrf-rpw="http://docs.oasis-open.org/wsrf/rpw-2"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
+
+<!-- ========================== Imports =========================== -->
+ <wsdl:import
+ namespace="http://docs.oasis-open.org/wsrf/rw-2"
+ location="WS-Resource-1_2.wsdl"/>
+
+ <wsdl:import
+ namespace="http://docs.oasis-open.org/wsrf/rlw-2"
+ location="WS-ResourceLifetime-1_2.wsdl"/>
+
+ <wsdl:import
+ namespace="http://docs.oasis-open.org/wsrf/rpw-2"
+ location="WS-ResourceProperties-1_2.wsdl"/>
+
+<!-- ===================== Types Definitions ====================== -->
+ <wsdl:types>
+ <xsd:schema>
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsn/b-2"
+ schemaLocation="WS-BaseNotification-1_3.xsd"/>
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/rp-2"
+ schemaLocation="WS-ResourceProperties-1_2.xsd"/>
+ </xsd:schema>
+ </wsdl:types>
+
+<!-- ================ NotificationConsumer::Notify ================
+ Notify(
+ NotificationMessage
+ (SubscriptionReference, TopicExpression, ProducerReference,
+ Message)*
+ returns: n/a (one way)
+-->
+ <wsdl:message name="Notify">
+ <wsdl:part name="Notify" element="wsnt:Notify"/>
+ </wsdl:message>
+
+<!-- ============== NotificationProducer::Subscribe ===============
+ Subscribe(
+ (ConsumerEndpointReference, [Filter], [SubscriptionPolicy],
+ [InitialTerminationTime])
+ returns: WS-Resource qualified EPR to a Subscription
+-->
+ <wsdl:message name="SubscribeRequest" >
+ <wsdl:part name="SubscribeRequest"
+ element="wsnt:Subscribe"/>
+ </wsdl:message>
+
+ <wsdl:message name="SubscribeResponse">
+ <wsdl:part name="SubscribeResponse"
+ element="wsnt:SubscribeResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="SubscribeCreationFailedFault">
+ <wsdl:part name="SubscribeCreationFailedFault"
+ element="wsnt:SubscribeCreationFailedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="TopicExpressionDialectUnknownFault">
+ <wsdl:part name="TopicExpressionDialectUnknownFault"
+ element="wsnt:TopicExpressionDialectUnknownFault" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidFilterFault">
+ <wsdl:part name="InvalidFilterFault"
+ element="wsnt:InvalidFilterFault" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidProducerPropertiesExpressionFault">
+ <wsdl:part name="InvalidProducerPropertiesExpressionFault"
+ element="wsnt:InvalidProducerPropertiesExpressionFault" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidMessageContentExpressionFault">
+ <wsdl:part name="InvalidMessageContentExpressionFault"
+ element="wsnt:InvalidMessageContentExpressionFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnrecognizedPolicyRequestFault">
+ <wsdl:part name="UnrecognizedPolicyRequestFault"
+ element="wsnt:UnrecognizedPolicyRequestFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnsupportedPolicyRequestFault">
+ <wsdl:part name="UnsupportedPolicyRequestFault"
+ element="wsnt:UnsupportedPolicyRequestFault" />
+ </wsdl:message>
+
+ <wsdl:message name="NotifyMessageNotSupportedFault">
+ <wsdl:part name="NotifyMessageNotSupportedFault"
+ element="wsnt:NotifyMessageNotSupportedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnacceptableInitialTerminationTimeFault">
+ <wsdl:part name="UnacceptableInitialTerminationTimeFault"
+ element="wsnt:UnacceptableInitialTerminationTimeFault"/>
+ </wsdl:message>
+
+<!-- ========== NotificationProducer::GetCurrentMessage ===========
+ GetCurrentMessage(topicExpression)
+ returns: a NotificationMessage (xsd:any)
+-->
+ <wsdl:message name="GetCurrentMessageRequest">
+ <wsdl:part name="GetCurrentMessageRequest"
+ element="wsnt:GetCurrentMessage"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetCurrentMessageResponse">
+ <wsdl:part name="GetCurrentMessageResponse"
+ element="wsnt:GetCurrentMessageResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="InvalidTopicExpressionFault">
+ <wsdl:part name="InvalidTopicExpressionFault"
+ element="wsnt:InvalidTopicExpressionFault" />
+ </wsdl:message>
+
+ <wsdl:message name="TopicNotSupportedFault">
+ <wsdl:part name="TopicNotSupportedFault"
+ element="wsnt:TopicNotSupportedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="MultipleTopicsSpecifiedFault">
+ <wsdl:part name="MultipleTopicsSpecifiedFault"
+ element="wsnt:MultipleTopicsSpecifiedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="NoCurrentMessageOnTopicFault">
+ <wsdl:part name="NoCurrentMessageOnTopicFault"
+ element="wsnt:NoCurrentMessageOnTopicFault" />
+ </wsdl:message>
+
+<!-- ========== PullPoint::GetMessages ===========
+ GetMessages(MaximumNumber)
+ returns: NotificationMessage list
+-->
+ <wsdl:message name="GetMessagesRequest">
+ <wsdl:part name="GetMessagesRequest"
+ element="wsnt:GetMessages"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetMessagesResponse">
+ <wsdl:part name="GetMessagesResponse"
+ element="wsnt:GetMessagesResponse"/>
+ </wsdl:message>
+
+<!-- ========== PullPoint::DestroyPullPoint ===========
+ DestroyPullPoint()
+ returns: void
+-->
+ <wsdl:message name="DestroyPullPointRequest">
+ <wsdl:part name="DestroyPullPointRequest"
+ element="wsnt:DestroyPullPoint"/>
+ </wsdl:message>
+
+ <wsdl:message name="DestroyPullPointResponse">
+ <wsdl:part name="DestroyPullPointResponse"
+ element="wsnt:DestroyPullPointResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="UnableToDestroyPullPointFault">
+ <wsdl:part name="UnableToDestroyPullPointFault"
+ element="wsnt:UnableToDestroyPullPointFault"/>
+ </wsdl:message>
+
+<!-- ========== PullPoint::CreatePullPoint ===========
+ CreatePullPoint()
+ returns: PullPoint (wsa:EndpointReference)
+-->
+ <wsdl:message name="CreatePullPointRequest">
+ <wsdl:part name="CreatePullPointRequest"
+ element="wsnt:CreatePullPoint"/>
+ </wsdl:message>
+
+ <wsdl:message name="CreatePullPointResponse">
+ <wsdl:part name="CreatePullPointResponse"
+ element="wsnt:CreatePullPointResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="UnableToCreatePullPointFault">
+ <wsdl:part name="UnableToCreatePullPointFault"
+ element="wsnt:UnableToCreatePullPointFault"/>
+ </wsdl:message>
+
+<!-- ================ SubscriptionManager::Renew ==================
+ Renew( Duration | AbsoluteTime)
+ returns: (New Termination Time [CurrentTime])
+-->
+ <wsdl:message name="RenewRequest">
+ <wsdl:part name="RenewRequest"
+ element="wsnt:Renew"/>
+ </wsdl:message>
+
+ <wsdl:message name="RenewResponse">
+ <wsdl:part name="RenewResponse"
+ element="wsnt:RenewResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="UnacceptableTerminationTimeFault">
+ <wsdl:part name="UnacceptableTerminationTimeFault"
+ element="wsnt:UnacceptableTerminationTimeFault" />
+ </wsdl:message>
+
+<!-- ============== SubscriptionManager::Unsubscribe ===============
+ Unsubscribe()
+ returns: empty
+-->
+ <wsdl:message name="UnsubscribeRequest">
+ <wsdl:part name="UnsubscribeRequest"
+ element="wsnt:Unsubscribe"/>
+ </wsdl:message>
+
+ <wsdl:message name="UnsubscribeResponse">
+ <wsdl:part name="UnsubscribeResponse"
+ element="wsnt:UnsubscribeResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="UnableToDestroySubscriptionFault">
+ <wsdl:part name="UnableToDestroySubscriptionFault"
+ element="wsnt:UnableToDestroySubscriptionFault" />
+ </wsdl:message>
+
+<!-- ========== SubscriptionManager::PauseSubscription ============
+ PauseSubscription()
+ returns: empty
+-->
+ <wsdl:message name="PauseSubscriptionRequest">
+ <wsdl:part name="PauseSubscriptionRequest"
+ element="wsnt:PauseSubscription"/>
+ </wsdl:message>
+
+ <wsdl:message name="PauseSubscriptionResponse">
+ <wsdl:part name="PauseSubscriptionResponse"
+ element="wsnt:PauseSubscriptionResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="PauseFailedFault">
+ <wsdl:part name="PauseFailedFault"
+ element="wsnt:PauseFailedFault" />
+ </wsdl:message>
+
+<!-- ========= SubscriptionManager::ResumeSubscription ============
+ ResumeSubscription()
+ returns: empty
+-->
+ <wsdl:message name="ResumeSubscriptionRequest">
+ <wsdl:part name="ResumeSubscriptionRequest"
+ element="wsnt:ResumeSubscription"/>
+ </wsdl:message>
+
+ <wsdl:message name="ResumeSubscriptionResponse">
+ <wsdl:part name="ResumeSubscriptionResponse"
+ element="wsnt:ResumeSubscriptionResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="ResumeFailedFault">
+ <wsdl:part name="ResumeFailedFault"
+ element="wsnt:ResumeFailedFault" />
+ </wsdl:message>
+
+<!-- =================== PortType Definitions ===================== -->
+<!-- ========= NotificationConsumer PortType Definition =========== -->
+ <wsdl:portType name="NotificationConsumer">
+ <wsdl:operation name="Notify">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer/NotifyRequest" message="wsntw:Notify" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+<!-- ========= NotificationProducer PortType Definition =========== -->
+ <wsdl:portType name="NotificationProducer">
+ <wsdl:operation name="Subscribe">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeRequest"
+ message="wsntw:SubscribeRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeResponse"
+ message="wsntw:SubscribeResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault" />
+ <wsdl:fault name="InvalidFilterFault"
+ message="wsntw:InvalidFilterFault"/>
+ <wsdl:fault name="TopicExpressionDialectUnknownFault"
+ message="wsntw:TopicExpressionDialectUnknownFault"/>
+ <wsdl:fault name="InvalidTopicExpressionFault"
+ message="wsntw:InvalidTopicExpressionFault" />
+ <wsdl:fault name="TopicNotSupportedFault"
+ message="wsntw:TopicNotSupportedFault" />
+ <wsdl:fault name="InvalidProducerPropertiesExpressionFault"
+ message="wsntw:InvalidProducerPropertiesExpressionFault"/>
+ <wsdl:fault name="InvalidMessageContentExpressionFault"
+ message="wsntw:InvalidMessageContentExpressionFault"/>
+ <wsdl:fault name="UnacceptableInitialTerminationTimeFault"
+ message="wsntw:UnacceptableInitialTerminationTimeFault"/>
+ <wsdl:fault name="UnrecognizedPolicyRequestFault"
+ message="wsntw:UnrecognizedPolicyRequestFault"/>
+ <wsdl:fault name="UnsupportedPolicyRequestFault"
+ message="wsntw:UnsupportedPolicyRequestFault"/>
+ <wsdl:fault name="NotifyMessageNotSupportedFault"
+ message="wsntw:NotifyMessageNotSupportedFault"/>
+ <wsdl:fault name="SubscribeCreationFailedFault"
+ message="wsntw:SubscribeCreationFailedFault"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetCurrentMessage">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/GetCurrentMessageRequest"
+ message="wsntw:GetCurrentMessageRequest"/>
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/GetCurrentMessageResponse"
+ message="wsntw:GetCurrentMessageResponse"/>
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault" />
+ <wsdl:fault name="TopicExpressionDialectUnknownFault"
+ message="wsntw:TopicExpressionDialectUnknownFault"/>
+ <wsdl:fault name="InvalidTopicExpressionFault"
+ message="wsntw:InvalidTopicExpressionFault" />
+ <wsdl:fault name="TopicNotSupportedFault"
+ message="wsntw:TopicNotSupportedFault" />
+ <wsdl:fault name="NoCurrentMessageOnTopicFault"
+ message="wsntw:NoCurrentMessageOnTopicFault" />
+ <wsdl:fault name="MultipleTopicsSpecifiedFault"
+ message="wsntw:MultipleTopicsSpecifiedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+<!-- ========== PullPoint PortType Definition ===================== -->
+ <wsdl:portType name="PullPoint">
+ <wsdl:operation name="GetMessages">
+ <wsdl:input name="GetMessagesRequest"
+ message="wsntw:GetMessagesRequest" />
+ <wsdl:output name="GetMessagesResponse"
+ message="wsntw:GetMessagesResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault" />
+ </wsdl:operation>
+
+ <wsdl:operation name="Notify">
+ <wsdl:input message="wsntw:Notify"/>
+ </wsdl:operation>
+ </wsdl:portType>
+
+<!-- ========== CreatePullPoint PortType Definition =============== -->
+ <wsdl:portType name="CreatePullPoint">
+ <wsdl:operation name="CreatePullPoint">
+ <wsdl:input name="CreatePullPointRequest"
+ message="wsntw:CreatePullPointRequest" />
+ <wsdl:output name="CreatePullPointResponse"
+ message="wsntw:CreatePullPointResponse" />
+ <wsdl:fault name="UnableToCreatePullPointFault"
+ message="wsntw:UnableToCreatePullPointFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+<!-- ========== SubscriptionManager PortType Definition =========== -->
+ <wsdl:portType name="SubscriptionManager"
+ wsrf-rp:ResourceProperties="wsnt:SubscriptionManagerRP">
+
+ <wsdl:operation name="Destroy">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination/DestroyRequest"
+ name="DestroyRequest" message="wsrf-rlw:DestroyRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination/DestroyResponse"
+ name="DestroyResponse" message="wsrf-rlw:DestroyResponse" />
+ <wsdl:fault name="ResourceNotDestroyedFault" message="wsrf-rlw:ResourceNotDestroyedFault" />
+ <wsdl:fault name="ResourceUnknownFault" message="wsrf-rw:ResourceUnknownFault" />
+ <wsdl:fault name="ResourceUnavailableFault" message="wsrf-rw:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="SetTerminationTime">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination/SetTerminationTimeRequest"
+ name="SetTerminationTimeRequest" message="wsrf-rlw:SetTerminationTimeRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination/SetTerminationTimeResponse"
+ name="SetTerminationTimeResponse" message="wsrf-rlw:SetTerminationTimeResponse" />
+ <wsdl:fault name="UnableToSetTerminationTimeFault" message="wsrf-rlw:UnableToSetTerminationTimeFault" />
+ <wsdl:fault name="ResourceUnknownFault" message="wsrf-rw:ResourceUnknownFault" />
+ <wsdl:fault name="ResourceUnavailableFault" message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="TerminationTimeChangeRejectedFault" message="wsrf-rlw:TerminationTimeChangeRejectedFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"
+ name="GetResourcePropertyDocumentRequest" message="wsrf-rpw:GetResourcePropertyDocumentRequest"/>
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse"
+ name="GetResourcePropertyDocumentResponse" message="wsrf-rpw:GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault name="ResourceUnknownFault" message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="wsrf-rw:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"
+ name="GetResourcePropertyRequest" message="wsrf-rpw:GetResourcePropertyRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse"
+ name="GetResourcePropertyResponse" message="wsrf-rpw:GetResourcePropertyResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"
+ name="GetMultipleResourcePropertiesRequest" message="wsrf-rpw:GetMultipleResourcePropertiesRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse"
+ name="GetMultipleResourcePropertiesResponse" message="wsrf-rpw:GetMultipleResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+
+<!-- </wsdl:portType>
+
+ <wsdl:portType name="PausableSubscriptionManager">
+-->
+ <!-- === PausableSubscriptionManager specific operations === -->
+ <wsdl:operation name="PauseSubscription">
+ <wsdl:input message="wsntw:PauseSubscriptionRequest" wsa:Action="http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/PauseSubscriptionRequest"/>
+ <wsdl:output message="wsntw:PauseSubscriptionResponse" wsa:Action="http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/PauseSubscriptionResponse"/>
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault" />
+ <wsdl:fault name="PauseFailedFault"
+ message="wsntw:PauseFailedFault" />
+ </wsdl:operation>
+ <wsdl:operation name="ResumeSubscription">
+ <wsdl:input message="wsntw:ResumeSubscriptionRequest" wsa:Action="http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/ResumeSubscriptionRequest"/>
+ <wsdl:output message="wsntw:ResumeSubscriptionResponse" wsa:Action="http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/ResumeSubscriptionResponse"/>
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault" />
+ <wsdl:fault name="ResumeFailedFault"
+ message="wsntw:ResumeFailedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+</wsdl:definitions> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.xsd
new file mode 100644
index 0000000000..9e10282759
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.xsd
@@ -0,0 +1,577 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2004-2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+
+<xsd:schema
+ targetNamespace="http://docs.oasis-open.org/wsn/b-2"
+ xmlns="http://docs.oasis-open.org/wsn/b-2"
+ xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wstop="http://docs.oasis-open.org/wsn/t-1"
+xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+<!-- ======================== Imports ============================ -->
+
+ <xsd:import namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="WS-Addressing-2005_08.xsd"
+ />
+
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"
+ schemaLocation="WS-BaseFaults-1_2.xsd"
+ />
+
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rl-2"
+ schemaLocation="WS-ResourceLifetime-1_2.xsd"
+ />
+ <xsd:import namespace="http://docs.oasis-open.org/wsn/t-1"
+ schemaLocation="WS-Topics-1_3.xsd"
+ />
+
+<!-- ===================== Misc. Helper Types ===================== -->
+
+ <xsd:complexType name="QueryExpressionType" mixed="true">
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="1" processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="Dialect" type="xsd:anyURI" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="TopicExpressionType" mixed="true">
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="1" processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="Dialect" type="xsd:anyURI" use="required" />
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+
+ <xsd:complexType name="FilterType">
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="SubscriptionPolicyType">
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+<!-- =============== Resource Property Related =================== -->
+<!-- ======== Resource Properties for NotificationProducer ======== -->
+ <xsd:element name="TopicExpression" type="wsnt:TopicExpressionType"/>
+ <xsd:element name="FixedTopicSet" type="xsd:boolean" default="true"/>
+ <xsd:element name="TopicExpressionDialect" type="xsd:anyURI"/>
+
+ <xsd:element name="NotificationProducerRP">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsnt:TopicExpression"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element ref="wsnt:FixedTopicSet"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsnt:TopicExpressionDialect"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element ref="wstop:TopicSet"
+ minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ======== Resource Properties for SubscriptionManager ========= -->
+ <xsd:element name="ConsumerReference"
+ type="wsa:EndpointReferenceType" />
+ <xsd:element name="Filter" type="wsnt:FilterType" />
+ <xsd:element name="SubscriptionPolicy" type="wsnt:SubscriptionPolicyType" />
+
+
+ <xsd:element name="CreationTime" type="xsd:dateTime" />
+
+ <xsd:element name="SubscriptionManagerRP" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsnt:ConsumerReference"
+ minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="wsnt:Filter"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsnt:SubscriptionPolicy"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsnt:CreationTime"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsrf-rl:CurrentTime"/>
+ <xsd:element ref="wsrf-rl:TerminationTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ================= Notification Metadata ===================== -->
+ <xsd:element name="SubscriptionReference"
+ type="wsa:EndpointReferenceType" />
+ <xsd:element name="Topic"
+ type="wsnt:TopicExpressionType" />
+ <xsd:element name="ProducerReference"
+ type="wsa:EndpointReferenceType" />
+
+<!-- ================== Message Helper Types ===================== -->
+ <xsd:complexType name="NotificationMessageHolderType" >
+ <xsd:sequence>
+ <xsd:element ref="wsnt:SubscriptionReference"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsnt:Topic"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsnt:ProducerReference"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element name="Message">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="lax"
+ minOccurs="1" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="NotificationMessage"
+ type="wsnt:NotificationMessageHolderType"/>
+
+<!-- ========== Message Types for NotificationConsumer =========== -->
+ <xsd:element name="Notify" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsnt:NotificationMessage"
+ minOccurs="1" maxOccurs="unbounded" />
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ========== Message Types for NotificationProducer =========== -->
+
+ <xsd:simpleType name="AbsoluteOrRelativeTimeType">
+ <xsd:union memberTypes="xsd:dateTime xsd:duration" />
+ </xsd:simpleType>
+
+ <xsd:element name="CurrentTime" type="xsd:dateTime" />
+
+ <xsd:element name="TerminationTime"
+ nillable="true" type="xsd:dateTime" />
+
+ <xsd:element name="ProducerProperties"
+ type="wsnt:QueryExpressionType" />
+
+ <xsd:element name="MessageContent"
+ type="wsnt:QueryExpressionType" />
+
+ <xsd:element name="UseRaw"><xsd:complexType/></xsd:element>
+
+ <xsd:element name="Subscribe" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="ConsumerReference"
+ type="wsa:EndpointReferenceType"
+ minOccurs="1" maxOccurs="1" />
+ <xsd:element name="Filter"
+ type="wsnt:FilterType"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element name="InitialTerminationTime"
+ type="wsnt:AbsoluteOrRelativeTimeType"
+ nillable="true"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element name="SubscriptionPolicy"
+ minOccurs="0" maxOccurs="1">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="SubscribeResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="SubscriptionReference"
+ type="wsa:EndpointReferenceType"
+ minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="wsnt:CurrentTime"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsnt:TerminationTime"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="GetCurrentMessage">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="Topic"
+ type="wsnt:TopicExpressionType" />
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="GetCurrentMessageResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="SubscribeCreationFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="SubscribeCreationFailedFault"
+ type="wsnt:SubscribeCreationFailedFaultType"/>
+
+ <xsd:complexType name="InvalidFilterFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="UnknownFilter" type="xsd:QName"
+ minOccurs="1" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidFilterFault"
+ type="wsnt:InvalidFilterFaultType"/>
+
+ <xsd:complexType name="TopicExpressionDialectUnknownFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="TopicExpressionDialectUnknownFault"
+ type="wsnt:TopicExpressionDialectUnknownFaultType"/>
+
+ <xsd:complexType name="InvalidTopicExpressionFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidTopicExpressionFault"
+ type="wsnt:InvalidTopicExpressionFaultType"/>
+
+ <xsd:complexType name="TopicNotSupportedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="TopicNotSupportedFault"
+ type="wsnt:TopicNotSupportedFaultType"/>
+
+ <xsd:complexType name="MultipleTopicsSpecifiedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="MultipleTopicsSpecifiedFault"
+ type="wsnt:MultipleTopicsSpecifiedFaultType"/>
+
+ <xsd:complexType name="InvalidProducerPropertiesExpressionFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidProducerPropertiesExpressionFault"
+ type="wsnt:InvalidProducerPropertiesExpressionFaultType"/>
+
+ <xsd:complexType name="InvalidMessageContentExpressionFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidMessageContentExpressionFault"
+ type="wsnt:InvalidMessageContentExpressionFaultType"/>
+
+ <xsd:complexType name="UnrecognizedPolicyRequestFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="UnrecognizedPolicy" type="xsd:QName"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnrecognizedPolicyRequestFault"
+ type="wsnt:UnrecognizedPolicyRequestFaultType"/>
+
+ <xsd:complexType name="UnsupportedPolicyRequestFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="UnsupportedPolicy" type="xsd:QName"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnsupportedPolicyRequestFault"
+ type="wsnt:UnsupportedPolicyRequestFaultType"/>
+
+ <xsd:complexType name="NotifyMessageNotSupportedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="NotifyMessageNotSupportedFault"
+ type="wsnt:NotifyMessageNotSupportedFaultType"/>
+
+ <xsd:complexType name="UnacceptableInitialTerminationTimeFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="MinimumTime" type="xsd:dateTime"/>
+ <xsd:element name="MaximumTime" type="xsd:dateTime"
+ minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnacceptableInitialTerminationTimeFault"
+ type="wsnt:UnacceptableInitialTerminationTimeFaultType"/>
+
+ <xsd:complexType name="NoCurrentMessageOnTopicFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="NoCurrentMessageOnTopicFault"
+ type="wsnt:NoCurrentMessageOnTopicFaultType"/>
+
+<!-- ======== Message Types for PullPoint ======================== -->
+ <xsd:element name="GetMessages">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="MaximumNumber"
+ type="xsd:nonNegativeInteger"/>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="GetMessagesResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsnt:NotificationMessage"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="DestroyPullPoint">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="DestroyPullPointResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="UnableToDestroyPullPointFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnableToDestroyPullPointFault"
+ type="wsnt:UnableToDestroyPullPointFaultType"/>
+
+<!-- ======== Message Types for Create PullPoint ================= -->
+ <xsd:element name="CreatePullPoint">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="CreatePullPointResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="PullPoint"
+ type="wsa:EndpointReferenceType"/>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="UnableToCreatePullPointFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnableToCreatePullPointFault"
+ type="wsnt:UnableToCreatePullPointFaultType"/>
+
+<!-- ======== Message Types for Base SubscriptionManager ========= -->
+ <xsd:element name="Renew">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="TerminationTime"
+ type="wsnt:AbsoluteOrRelativeTimeType"
+ nillable="true"
+ minOccurs="1" maxOccurs="1" />
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="RenewResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsnt:TerminationTime"
+ minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="wsnt:CurrentTime"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="UnacceptableTerminationTimeFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="MinimumTime" type="xsd:dateTime"/>
+ <xsd:element name="MaximumTime" type="xsd:dateTime"
+ minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnacceptableTerminationTimeFault"
+ type="wsnt:UnacceptableTerminationTimeFaultType"/>
+
+ <xsd:element name="Unsubscribe">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="UnsubscribeResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="UnableToDestroySubscriptionFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnableToDestroySubscriptionFault"
+ type="wsnt:UnableToDestroySubscriptionFaultType"/>
+
+<!-- ====== Message Types for Pausable SubscriptionManager ======= -->
+
+ <xsd:element name="PauseSubscription">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="PauseSubscriptionResponse" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="ResumeSubscription">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="ResumeSubscriptionResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="PauseFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="PauseFailedFault"
+ type="wsnt:PauseFailedFaultType"/>
+
+ <xsd:complexType name="ResumeFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResumeFailedFault"
+ type="wsnt:ResumeFailedFaultType"/>
+
+</xsd:schema> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-MetadataExchange-2004_09.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-MetadataExchange-2004_09.xsd
new file mode 100644
index 0000000000..4cef35b510
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-MetadataExchange-2004_09.xsd
@@ -0,0 +1,134 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<!--
+(c) 2004 BEA Systems Inc., Computer Associates International, Inc.,
+International Business Machines Corporation, Microsoft Corporation,
+Inc., SAP AG, Sun Microsystems, and webMethods. All rights reserved.
+
+Permission to copy and display the WS-MetadataExchange Specification
+(the "Specification"), in any medium without fee or royalty is hereby
+granted, provided that you include the following on ALL copies of the
+Specification that you make:
+
+1. A link or URL to the Specification at this location.
+2. The copyright notice as shown in the Specification.
+
+BEA Systems, Computer Associates, IBM, Microsoft, SAP, Sun, and
+webMethods (collectively, the "Authors") each agree to grant you a
+license, under royalty-free and otherwise reasonable,
+non-discriminatory terms and conditions, to their respective essential
+patent claims that they deem necessary to implement the
+WS-MetadataExchange Specification.
+
+THE SPECIFICATION IS PROVIDED "AS IS," AND THE AUTHORS MAKE NO
+REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE
+SPECIFICATION ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE
+IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY
+PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL,
+INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY
+USE OR DISTRIBUTION OF THE SPECIFICATIONS.
+
+The name and trademarks of the Authors may NOT be used in any manner,
+including advertising or publicity pertaining to the Specifications or
+their contents without specific, written prior permission. Title to
+copyright in the Specifications will at all times remain with the
+Authors.
+
+No other rights are granted by implication, estoppel or otherwise.
+-->
+
+<xs:schema
+ targetNamespace="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:tns="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified" >
+
+ <xs:import
+ namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="WS-Addressing-2005_08.xsd" />
+
+ <!-- Get Metadata request -->
+ <xs:element name='GetMetadata' >
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref='tns:Dialect' minOccurs='0' />
+ <xs:element ref='tns:Identifier' minOccurs='0' />
+ </xs:sequence>
+ <xs:anyAttribute namespace='##other' processContents='lax' />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name='Dialect' type='xs:anyURI' />
+ <xs:element name='Identifier' type='xs:anyURI' />
+
+ <!-- Get Metadata response -->
+ <xs:element name='Metadata' >
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref='tns:MetadataSection'
+ minOccurs='0'
+ maxOccurs='unbounded' />
+ </xs:sequence>
+ <xs:anyAttribute namespace='##other' processContents='lax' />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name='MetadataSection' >
+ <xs:complexType>
+ <xs:choice>
+ <xs:any namespace='##other'
+ processContents='lax'
+ minOccurs='0'
+ maxOccurs='unbounded' />
+ <xs:element ref='tns:MetadataReference' />
+ <xs:element ref='tns:Location' />
+ </xs:choice>
+ <xs:attribute name='Dialect' type='xs:anyURI' use='required' />
+ <xs:attribute name='Identifier' type='xs:anyURI' />
+ <xs:anyAttribute namespace='##other' processContents='lax' />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name='MetadataReference'
+ type='wsa:EndpointReferenceType' />
+
+ <xs:element name='Location'
+ type='xs:anyURI' />
+
+ <!-- count(/s:Envelope/s:Body/*) = 0 for Get request -->
+
+ <!-- Get Response returns xs:any -->
+
+ <xs:complexType name='AnyXmlType' >
+ <xs:sequence>
+ <xs:any namespace='##any' processContents='lax' />
+ </xs:sequence>
+ <xs:anyAttribute namespace='##any' processContents='lax' />
+ </xs:complexType>
+
+</xs:schema>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.wsdl b/qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.wsdl
new file mode 100644
index 0000000000..ed1c309211
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.wsdl
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+
+<wsdl:definitions name="WS-Resource"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-rw="http://docs.oasis-open.org/wsrf/rw-2"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rw-2"
+>
+
+<!-- ===================== Types Definitions ====================== -->
+ <wsdl:types>
+ <xsd:schema
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rw-2"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified">
+
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/r-2"
+ schemaLocation="WS-Resource-1_2.xsd"
+ />
+
+ </xsd:schema>
+ </wsdl:types>
+
+<!-- ================= WS-Resource faults ========================= -->
+ <wsdl:message name="ResourceUnknownFault">
+ <part name="ResourceUnknownFault"
+ element="wsrf-r:ResourceUnknownFault" />
+ </wsdl:message>
+
+ <wsdl:message name="ResourceUnavailableFault">
+ <part name="ResourceUnavailableFault"
+ element="wsrf-r:ResourceUnavailableFault" />
+ </wsdl:message>
+
+</wsdl:definitions>
+
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.xsd
new file mode 100644
index 0000000000..5d50284a33
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.xsd
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+<xsd:schema
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ elementFormDefault="qualified" attributeFormDefault="unqualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/r-2"
+>
+
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/bf-2"
+ schemaLocation="WS-BaseFaults-1_2.xsd" />
+
+<!-- ====================== WS-Resource fault types ============= -->
+
+ <xsd:complexType name="ResourceUnknownFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResourceUnknownFault"
+ type="wsrf-r:ResourceUnknownFaultType"/>
+
+ <xsd:complexType name="ResourceUnavailableFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResourceUnavailableFault"
+ type="wsrf-r:ResourceUnavailableFaultType"/>
+</xsd:schema>
+
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.wsdl b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.wsdl
new file mode 100644
index 0000000000..adea5800fc
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.wsdl
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+ OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+ Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+ The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+ This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+<wsdl:definitions name="WS-ResourceLifetime"
+targetNamespace="http://docs.oasis-open.org/wsrf/rlw-2"
+xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+xmlns:wsrf-rlw="http://docs.oasis-open.org/wsrf/rlw-2"
+xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+xmlns:wsrf-rw="http://docs.oasis-open.org/wsrf/rw-2"
+xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
+
+ <wsdl:import namespace="http://docs.oasis-open.org/wsrf/rw-2"
+ location="WS-Resource-1_2.wsdl"/>
+ <wsdl:types>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ xmlns="http://www.w3.org/2001/XMLSchema">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rl-2"
+ schemaLocation="WS-ResourceLifetime-1_2.xsd" />
+ </xsd:schema>
+ </wsdl:types>
+
+ <wsdl:message name="SetTerminationTimeRequest">
+ <wsdl:part element="wsrf-rl:SetTerminationTime" name="SetTerminationTimeRequest" />
+ </wsdl:message>
+ <wsdl:message name="SetTerminationTimeResponse">
+ <wsdl:part element="wsrf-rl:SetTerminationTimeResponse" name="SetTerminationTimeResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="DestroyRequest">
+ <wsdl:part element="wsrf-rl:Destroy" name="DestroyRequest" />
+ </wsdl:message>
+ <wsdl:message name="DestroyResponse">
+ <wsdl:part element="wsrf-rl:DestroyResponse" name="DestroyResponse" />
+ </wsdl:message>
+ <wsdl:message name="ResourceNotDestroyedFault">
+ <wsdl:part element="wsrf-rl:ResourceNotDestroyedFault" name="ResourceNotDestroyedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnableToSetTerminationTimeFault">
+ <wsdl:part element="wsrf-rl:UnableToSetTerminationTimeFault" name="UnableToSetTerminationTimeFault" />
+ </wsdl:message>
+ <wsdl:message name="TerminationTimeChangeRejectedFault">
+ <wsdl:part element="wsrf-rl:TerminationTimeChangeRejectedFault" name="TerminationTimeChangeRejectedFault" />
+ </wsdl:message>
+ <wsdl:portType name="ImmediateResourceTermination">
+ <wsdl:operation name="Destroy">
+ <wsdl:input name="DestroyRequest" message="wsrf-rlw:DestroyRequest" />
+
+ <wsdl:output name="DestroyResponse" message="wsrf-rlw:DestroyResponse" />
+ <wsdl:fault message="wsrf-rlw:ResourceNotDestroyedFault" name="ResourceNotDestroyedFault" />
+ <wsdl:fault name="ResourceUnknownFault" message="wsrf-rw:ResourceUnknownFault" />
+ <wsdl:fault name="ResourceUnavailableFault" message="wsrf-rw:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:portType name="ScheduledResourceTermination"
+ wsrf-rp:ResourceProperties="wsrf-rl:ScheduledResourceTerminationRP">
+ <wsdl:operation name="SetTerminationTime">
+ <wsdl:input name="SetTerminationTimeRequest" message="wsrf-rlw:SetTerminationTimeRequest" />
+ <wsdl:output name="SetTerminationTimeResponse" message="wsrf-rlw:SetTerminationTimeResponse" />
+
+ <wsdl:fault message="wsrf-rlw:UnableToSetTerminationTimeFault" name="UnableToSetTerminationTimeFault" />
+ <wsdl:fault name="ResourceUnknownFault" message="wsrf-rw:ResourceUnknownFault" />
+ <wsdl:fault name="ResourceUnavailableFault" message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault message="wsrf-rlw:TerminationTimeChangeRejectedFault" name="TerminationTimeChangeRejectedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+</wsdl:definitions> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.xsd
new file mode 100644
index 0000000000..3338faf191
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.xsd
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+ OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+ Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+ The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+ This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+
+
+<xsd:schema
+xmlns="http://www.w3.org/2001/XMLSchema"
+xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+elementFormDefault="qualified" attributeFormDefault="unqualified"
+targetNamespace="http://docs.oasis-open.org/wsrf/rl-2">
+
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"
+ schemaLocation="WS-BaseFaults-1_2.xsd" />
+ <!--
+ =============== Resource Property Related ===================
+ -->
+ <!--
+ ==== Resource Properties for ScheduledResourceTermination ====
+ -->
+
+ <xsd:element name="CurrentTime" >
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:dateTime" >
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="TerminationTime" nillable="true">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:dateTime" >
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+
+
+ <!-- ==== Resource Properties for ScheduledResourceTermination ==== -->
+ <xsd:element name="ScheduledResourceTerminationRP">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element maxOccurs="1" minOccurs="1" ref="wsrf-rl:CurrentTime" />
+ <xsd:element maxOccurs="1" minOccurs="1" ref="wsrf-rl:TerminationTime" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- ====== Message Types for ImmediateResourceTermination ======= -->
+ <xsd:element name="Destroy">
+ <xsd:complexType />
+ </xsd:element>
+
+ <xsd:element name="DestroyResponse">
+ <xsd:complexType />
+ </xsd:element>
+
+ <xsd:complexType name="ResourceNotDestroyedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType" />
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResourceNotDestroyedFault" type="wsrf-rl:ResourceNotDestroyedFaultType" />
+ <!-- ====== Message Types for ScheduledResourceTermination ======= -->
+ <xsd:element name="SetTerminationTime">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element name="RequestedTerminationTime" nillable="true" type="xsd:dateTime" />
+ <xsd:element name="RequestedLifetimeDuration" type="xsd:duration" />
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="SetTerminationTimeResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="NewTerminationTime" nillable="true" type="xsd:dateTime" />
+ <xsd:element name="CurrentTime" type="xsd:dateTime" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="UnableToSetTerminationTimeFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType" />
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="UnableToSetTerminationTimeFault" type="wsrf-rl:UnableToSetTerminationTimeFaultType" />
+ <xsd:complexType name="TerminationTimeChangeRejectedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType" />
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="TerminationTimeChangeRejectedFault" type="wsrf-rl:TerminationTimeChangeRejectedFaultType" />
+
+
+ <!--
+ ============= Notification Message Related ==================
+ -->
+ <xsd:element name="TerminationNotification">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="TerminationTime" type="xsd:dateTime" minOccurs="1" maxOccurs="1" nillable="true" />
+ <xsd:element name="TerminationReason" type="xsd:anyType" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+
+ </xsd:complexType>
+ </xsd:element>
+
+
+</xsd:schema> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ResourceMetadataDescriptor-CD-01.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceMetadataDescriptor-CD-01.xsd
new file mode 100644
index 0000000000..2c5952264b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceMetadataDescriptor-CD-01.xsd
@@ -0,0 +1,325 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2005-2006). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+-->
+
+<xsd:schema
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rmd-1"
+ xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1"
+ elementFormDefault="qualified">
+
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/rp-2"
+ schemaLocation="WS-ResourceProperties-1_2.xsd" />
+
+ <xsd:import
+ namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="WS-Addressing-2005_08.xsd" />
+
+
+
+<!-- ======================== Utility Types ======================= -->
+ <xsd:simpleType name="PairsOfURIType">
+ <xsd:list itemType="xsd:anyURI" />
+ </xsd:simpleType>
+
+<!-- ================ PortType Attribute Extensions ================ -->
+ <xsd:attribute name="Descriptor" type="xsd:QName" />
+
+ <xsd:attribute name="DescriptorLocation" type="xsd:anyURI" />
+
+<!-- ================= Documentation Component ==================== -->
+ <xsd:complexType name="DocumentationType" mixed="true" >
+ <xsd:sequence>
+ <xsd:any namespace="##any"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+
+ <xsd:complexType name="DocumentedType">
+ <xsd:sequence>
+ <xsd:element name="documentation" type="wsrmd:DocumentationType"
+ minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+<!-- ================== Definitions Component ===================== -->
+<!--
+ <Definitions
+ targetNamespace="xsd:anyURI"
+ {anyAttribute}* >
+
+ <documentation />?
+ <MetadataDescriptor /> *
+ {any}*
+
+</Definitions>
+ -->
+
+ <xsd:complexType name= "DefinitionsType" >
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:element ref="wsrmd:MetadataDescriptor"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="targetNamespace"
+ type="xsd:anyURI" use="required"/>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="Definitions" type="wsrmd:DefinitionsType" >
+ <xsd:key name="MetadataDescriptor">
+ <xsd:annotation>
+ <xsd:documentation>
+ To form a QName, the name of any MetadataDescriptor must be
+ unique within a Definitions element.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:selector xpath="wsrmd:MetadataDescriptor" />
+ <xsd:field xpath="@name" />
+ </xsd:key>
+ </xsd:element>
+
+<!-- =============== MetadataDescriptor Component =================== -->
+<!--
+<MetadataDescriptor
+ name="xsd:NCName"
+ interface="xsd:QName"
+ wsdlLocation="list of xsd:anyURI"?
+ {anyAttribute}* >
+
+ <documentation />?
+ <Property /> *
+ {any}*
+
+</MetadataDescriptor>
+-->
+
+ <xsd:complexType name= "MetadataDescriptorType" >
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:element ref="wsrmd:Property"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="name"
+ type="xsd:NCName" use="required"/>
+ <xsd:attribute name="interface"
+ type="xsd:QName" use="required"/>
+ <xsd:attribute name="wsdlLocation"
+ type="wsrmd:PairsOfURIType" />
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="MetadataDescriptor"
+ type="wsrmd:MetadataDescriptorType" />
+
+<!-- ==================== Property Component ====================== -->
+<!--
+<Property
+ name="xsd:QName"
+ mutability="[constant|appendable|mutable]" ?
+ modifiability="[read-only|read-write]" ?
+ subscribability="xs:boolean" ?
+ {anyAttribute}* >
+
+ <documentation />?
+ [ <ValidValues> {any}* </ValidValues> |
+ <ValidValueRange lowerBound=’xsd:simpleType’
+ upperBound=’xsd:simpleType’>
+ </ValidValueRange> ] ?
+ <StaticValues> {any}* </StaticValues> ?
+
+ {any} *
+
+</Property>
+-->
+ <xsd:complexType name= "PropertyType" >
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element ref="wsrmd:ValidValues"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsrmd:ValidValueRange"
+ minOccurs="0" maxOccurs="1" />
+ </xsd:choice>
+ <xsd:element ref="wsrmd:StaticValues"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="name"
+ type="xsd:QName" use="required"/>
+ <xsd:attribute name="mutability"
+ type="wsrmd:MutabilityType" />
+ <xsd:attribute name="modifiability"
+ type="wsrmd:ModifiabilityType" />
+ <xsd:attribute name="subscribability" type="xsd:boolean" default="false" />
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="Property" type="wsrmd:PropertyType" />
+
+ <xsd:simpleType name="MutabilityType">
+ <xsd:restriction base="xsd:string" >
+ <xsd:enumeration value="constant" />
+ <xsd:enumeration value="appendable" />
+ <xsd:enumeration value="mutable" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="ModifiabilityType">
+ <xsd:restriction base="xsd:string" >
+ <xsd:enumeration value="read-only" />
+ <xsd:enumeration value="read-write" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+<!-- ================= Valid Values Component ===================== -->
+<!--
+<ValidValues
+ {anyAttribute}* >
+ <documentation />?
+ {any}*
+</ValidValues>
+-->
+ <xsd:complexType name= "ValidValuesType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="documentation" type="wsrmd:DocumentationType"
+ minOccurs="0" maxOccurs="1" />
+
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+
+ <xsd:element name="ValidValues" type="wsrmd:ValidValuesType" />
+
+<!-- ================= Valid Range Component ===================== -->
+<!--
+<ValidValueRange
+ lowerBound="xs:anySimpleType" ? upperBound="xs:anySimpleType" ?
+ {anyAttribute}* >
+ <documentation />?
+ {any}*
+</ValidValueRange>
+-->
+ <xsd:complexType name= "ValidValueRangeType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="documentation" type="wsrmd:DocumentationType"
+ minOccurs="0" maxOccurs="1" />
+
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="lowerBound" type="xsd:anySimpleType" />
+ <xsd:attribute name="upperBound" type="xsd:anySimpleType" />
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+
+ <xsd:element name="ValidValueRange" type="wsrmd:ValidValueRangeType" />
+
+<!-- ================ Static Values Component ===================== -->
+<!--
+<StaticValues
+ {anyAttribute}* >
+ <documentation />?
+ {any}*
+</StaticValues>
+-->
+ <xsd:complexType name= "StaticValuesType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="documentation" type="wsrmd:DocumentationType"
+ minOccurs="0" maxOccurs="1" />
+
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+
+ <xsd:element name="StaticValues" type="wsrmd:StaticValuesType" />
+
+<!-- ================ Initial Values Component ==================== -->
+<!--
+<InitialValues
+ {anyAttribute}* >
+ <documentation />?
+ {any}*
+</InitialValues>
+-->
+ <xsd:complexType name= "InitialValuesType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="documentation" type="wsrmd:DocumentationType"
+ minOccurs="0" maxOccurs="1" />
+
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+
+ <xsd:element name="InitialValues" type="wsrmd:InitialValuesType" />
+
+
+<!-- =========== MetadataDescriptorReference RP GED =============== -->
+ <xsd:complexType name="MetadataDescriptorReferenceType">
+ <xsd:complexContent>
+ <xsd:extension base="wsa:EndpointReferenceType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="MetadataDescriptorReference"
+ type="wsrmd:MetadataDescriptorReferenceType" />
+
+<!--
+
+Metadata Resource RP Doc
+
+This defines one property - MetadataDescriptor - which must have a cardinality of one.
+
+-->
+
+ <xsd:element name="MetadataResourceRP" type="wsrmd:DefinitionsType"/>
+
+</xsd:schema>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.wsdl b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.wsdl
new file mode 100644
index 0000000000..5d9d7562f4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.wsdl
@@ -0,0 +1,395 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+
+<wsdl:definitions name="WS-ResourceProperties"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrf-rpw="http://docs.oasis-open.org/wsrf/rpw-2"
+ xmlns:wsrf-rw="http://docs.oasis-open.org/wsrf/rw-2"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rpw-2"
+>
+
+<!-- ========================== Imports ========================== -->
+
+ <wsdl:import
+ namespace="http://docs.oasis-open.org/wsrf/rw-2"
+ location="WS-Resource-1_2.wsdl" />
+
+<!-- ===================== Types Definitions ====================== -->
+ <wsdl:types>
+ <xsd:schema>
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/rp-2"
+ schemaLocation="WS-ResourceProperties-1_2.xsd" />
+ </xsd:schema>
+ </wsdl:types>
+
+<!-- ================== GetResourcePropertyDocument ===============
+ GetResourcePropertyDocument()
+ returns: any
+-->
+ <wsdl:message name="GetResourcePropertyDocumentRequest">
+ <wsdl:part name="GetResourcePropertyDocumentRequest"
+ element="wsrf-rp:GetResourcePropertyDocument"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetResourcePropertyDocumentResponse">
+ <wsdl:part name="GetResourcePropertyDocumentResponse"
+ element="wsrf-rp:GetResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+
+<!-- ===================== GetResourceProperty ====================
+ GetResourceProperty(QName)
+ returns: any
+-->
+ <wsdl:message name="GetResourcePropertyRequest">
+ <wsdl:part name="GetResourcePropertyRequest"
+ element="wsrf-rp:GetResourceProperty" />
+ </wsdl:message>
+
+ <wsdl:message name="GetResourcePropertyResponse">
+ <wsdl:part name="GetResourcePropertyResponse"
+ element="wsrf-rp:GetResourcePropertyResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidResourcePropertyQNameFault">
+ <part name="InvalidResourcePropertyQNameFault"
+ element="wsrf-rp:InvalidResourcePropertyQNameFault" />
+ </wsdl:message>
+
+<!-- ==============GetMultipleResourceProperties ==================
+ GetMultipleResourceProperties(list of QName)
+ returns: sequence of any
+-->
+ <wsdl:message name="GetMultipleResourcePropertiesRequest">
+ <wsdl:part name="GetMultipleResourcePropertiesRequest"
+ element="wsrf-rp:GetMultipleResourceProperties" />
+ </wsdl:message>
+
+ <wsdl:message name="GetMultipleResourcePropertiesResponse">
+ <wsdl:part name="GetMultipleResourcePropertiesResponse"
+ element="wsrf-rp:GetMultipleResourcePropertiesResponse" />
+ </wsdl:message>
+<!-- ================== PutResourcePropertyDocument ===============
+ PutResourcePropertyDocument(any)
+ returns: any?
+-->
+ <wsdl:message name="PutResourcePropertyDocumentRequest">
+ <wsdl:part name="PutResourcePropertyDocumentRequest"
+ element="wsrf-rp:PutResourcePropertyDocument"/>
+ </wsdl:message>
+
+ <wsdl:message name="PutResourcePropertyDocumentResponse">
+ <wsdl:part name="PutResourcePropertyDocumentResponse"
+ element="wsrf-rp:PutResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="UnableToPutResourcePropertyDocumentFault">
+ <part name="UnableToPutResourcePropertyDocumentFault"
+ element="wsrf-rp:UnableToPutResourcePropertyDocumentFault" />
+ </wsdl:message>
+
+<!-- ================= SetResourceProperties ======================
+ SetResourceProperties(
+ { insert (any)* |
+ update (any)* |
+ delete@QName } +
+ )
+ returns: empty
+-->
+ <wsdl:message name="SetResourcePropertiesRequest">
+ <wsdl:part name="SetResourcePropertiesRequest"
+ element="wsrf-rp:SetResourceProperties" />
+ </wsdl:message>
+
+ <wsdl:message name="SetResourcePropertiesResponse">
+ <wsdl:part name="SetResourcePropertiesResponse"
+ element="wsrf-rp:SetResourcePropertiesResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidModificationFault">
+ <part name="InvalidModificationFault"
+ element="wsrf-rp:InvalidModificationFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnableToModifyResourcePropertyFault">
+ <part name="UnableToModifyResourcePropertyFault"
+ element="wsrf-rp:UnableToModifyResourcePropertyFault" />
+ </wsdl:message>
+
+ <wsdl:message name="SetResourcePropertyRequestFailedFault">
+ <part name="SetResourcePropertyRequestFailedFault"
+ element="wsrf-rp:SetResourcePropertyRequestFailedFault" />
+ </wsdl:message>
+
+<!-- =============== InsertResourceProperties =====================
+ InsertResourceProperties((any)* )
+ returns: empty
+-->
+ <wsdl:message name="InsertResourcePropertiesRequest">
+ <wsdl:part name="InsertResourcePropertiesRequest"
+ element="wsrf-rp:InsertResourceProperties" />
+ </wsdl:message>
+
+ <wsdl:message name="InsertResourcePropertiesResponse">
+ <wsdl:part name="InsertResourcePropertiesResponse"
+ element="wsrf-rp:InsertResourcePropertiesResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="InsertResourcePropertiesRequestFailedFault">
+ <part name="InsertResourcePropertiesRequestFailedFault"
+ element="wsrf-rp:InsertResourcePropertiesRequestFailedFault" />
+ </wsdl:message>
+
+<!-- =============== UpdateResourceProperties =====================
+ UpdateResourceProperties((any)* )
+ returns: empty
+-->
+ <wsdl:message name="UpdateResourcePropertiesRequest">
+ <wsdl:part name="UpdateResourcePropertiesRequest"
+ element="wsrf-rp:UpdateResourceProperties" />
+ </wsdl:message>
+
+ <wsdl:message name="UpdateResourcePropertiesResponse">
+ <wsdl:part name="UpdateResourcePropertiesResponse"
+ element="wsrf-rp:UpdateResourcePropertiesResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="UpdateResourcePropertiesRequestFailedFault">
+ <part name="UpdateResourcePropertiesRequestFailedFault"
+ element="wsrf-rp:UpdateResourcePropertiesRequestFailedFault" />
+ </wsdl:message>
+
+<!-- =============== DeleteResourceProperties =====================
+ DeleteResourceProperties( ResourceProperty )
+ returns: empty
+-->
+ <wsdl:message name="DeleteResourcePropertiesRequest">
+ <wsdl:part name="DeleteResourcePropertiesRequest"
+ element="wsrf-rp:DeleteResourceProperties" />
+ </wsdl:message>
+
+ <wsdl:message name="DeleteResourcePropertiesResponse">
+ <wsdl:part name="DeleteResourcePropertiesResponse"
+ element="wsrf-rp:DeleteResourcePropertiesResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="DeleteResourcePropertiesRequestFailedFault">
+ <part name="DeleteResourcePropertiesRequestFailedFault"
+ element="wsrf-rp:DeleteResourcePropertiesRequestFailedFault" />
+ </wsdl:message>
+
+<!-- ================ QueryResourceProperties =====================
+ QueryResourceProperties(QueryExpression)
+ returns: any
+-->
+ <wsdl:message name="QueryResourcePropertiesRequest">
+ <wsdl:part name="QueryResourcePropertiesRequest"
+ element="wsrf-rp:QueryResourceProperties" />
+ </wsdl:message>
+
+ <wsdl:message name="QueryResourcePropertiesResponse">
+ <wsdl:part name="QueryResourcePropertiesResponse"
+ element="wsrf-rp:QueryResourcePropertiesResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="UnknownQueryExpressionDialectFault">
+ <part name="UnknownQueryExpressionDialectFault"
+ element="wsrf-rp:UnknownQueryExpressionDialectFault" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidQueryExpressionFault">
+ <part name="InvalidQueryExpressionFault"
+ element="wsrf-rp:InvalidQueryExpressionFault" />
+ </wsdl:message>
+
+ <wsdl:message name="QueryEvaluationErrorFault">
+ <part name="QueryEvaluationErrorFault"
+ element="wsrf-rp:QueryEvaluationErrorFault" />
+ </wsdl:message>
+
+<!-- =================== PortType Definitions ===================== -->
+ <wsdl:portType name="GetResourcePropertyDocument">
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:input name="GetResourcePropertyDocumentRequest"
+ message="wsrf-rpw:GetResourcePropertyDocumentRequest"/>
+ <wsdl:output name="GetResourcePropertyDocumentResponse"
+ message="wsrf-rpw:GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:portType name="GetResourceProperty">
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:input name="GetResourcePropertyRequest"
+ message="wsrf-rpw:GetResourcePropertyRequest" />
+ <wsdl:output name="GetResourcePropertyResponse"
+ message="wsrf-rpw:GetResourcePropertyResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault"
+ message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:portType name="GetMultipleResourceProperties">
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:input name="GetMultipleResourcePropertiesRequest"
+ message="wsrf-rpw:GetMultipleResourcePropertiesRequest" />
+ <wsdl:output name="GetMultipleResourcePropertiesResponse"
+ message="wsrf-rpw:GetMultipleResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault"
+ message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:portType name="PutResourcePropertyDocument">
+ <wsdl:operation name="PutResourcePropertyDocument">
+ <wsdl:input name="PutResourcePropertyDocumentRequest"
+ message="wsrf-rpw:PutResourcePropertyDocumentRequest" />
+ <wsdl:output name="PutResourcePropertyDocumentResponse"
+ message="wsrf-rpw:PutResourcePropertyDocumentResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="UnableToPutResourcePropertyDocumentFault"
+ message="wsrf-rpw:UnableToPutResourcePropertyDocumentFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:portType name="SetResourceProperties">
+ <wsdl:operation name="SetResourceProperties">
+ <wsdl:input name="SetResourcePropertiesRequest"
+ message="wsrf-rpw:SetResourcePropertiesRequest" />
+ <wsdl:output name="SetResourcePropertiesResponse"
+ message="wsrf-rpw:SetResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidModificationFault"
+ message="wsrf-rpw:InvalidModificationFault" />
+ <wsdl:fault name="UnableToModifyResourcePropertyFault"
+ message="wsrf-rpw:UnableToModifyResourcePropertyFault" />
+ <wsdl:fault name="InvalidResourcePropertyQNameFault"
+ message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ <wsdl:fault name="SetResourcePropertyRequestFailedFault"
+ message="wsrf-rpw:SetResourcePropertyRequestFailedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:portType name="InsertResourceProperties">
+ <wsdl:operation name="InsertResourceProperties">
+ <wsdl:input name="InsertResourcePropertiesRequest"
+ message="wsrf-rpw:InsertResourcePropertiesRequest" />
+ <wsdl:output name="InsertResourcePropertiesResponse"
+ message="wsrf-rpw:InsertResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidModificationFault"
+ message="wsrf-rpw:InvalidModificationFault" />
+ <wsdl:fault name="UnableToModifyResourcePropertyFault"
+ message="wsrf-rpw:UnableToModifyResourcePropertyFault" />
+ <wsdl:fault name="InvalidResourcePropertyQNameFault"
+ message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ <wsdl:fault name="InsertResourcePropertiesRequestFailedFault"
+ message="wsrf-rpw:InsertResourcePropertiesRequestFailedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:portType name="UpdateResourceProperties">
+ <wsdl:operation name="UpdateResourceProperties">
+ <wsdl:input name="UpdateResourcePropertiesRequest"
+ message="wsrf-rpw:UpdateResourcePropertiesRequest" />
+ <wsdl:output name="UpdateResourcePropertiesResponse"
+ message="wsrf-rpw:UpdateResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidModificationFault"
+ message="wsrf-rpw:InvalidModificationFault" />
+ <wsdl:fault name="UnableToModifyResourcePropertyFault"
+ message="wsrf-rpw:UnableToModifyResourcePropertyFault" />
+ <wsdl:fault name="InvalidResourcePropertyQNameFault"
+ message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ <wsdl:fault name="UpdateResourcePropertiesRequestFailedFault"
+ message="wsrf-rpw:UpdateResourcePropertiesRequestFailedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:portType name="DeleteResourceProperties">
+ <wsdl:operation name="DeleteResourceProperties">
+ <wsdl:input name="DeleteResourcePropertiesRequest"
+ message="wsrf-rpw:DeleteResourcePropertiesRequest" />
+ <wsdl:output name="DeleteResourcePropertiesResponse"
+ message="wsrf-rpw:DeleteResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidModificationFault"
+ message="wsrf-rpw:InvalidModificationFault" />
+ <wsdl:fault name="UnableToModifyResourcePropertyFault"
+ message="wsrf-rpw:UnableToModifyResourcePropertyFault" />
+ <wsdl:fault name="InvalidResourcePropertyQNameFault"
+ message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ <wsdl:fault name="DeleteResourcePropertiesRequestFailedFault"
+ message="wsrf-rpw:DeleteResourcePropertiesRequestFailedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+<wsdl:portType name="QueryResourceProperties"
+ wsrf-rp:ResourceProperties="wsrf-rp:QueryExpressionRPDocument">
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl:input name="QueryResourcePropertiesRequest"
+ message="wsrf-rpw:QueryResourcePropertiesRequest" />
+ <wsdl:output name="QueryResourcePropertiesResponse"
+ message="wsrf-rpw:QueryResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault"
+ message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ <wsdl:fault name="UnknownQueryExpressionDialectFault"
+ message="wsrf-rpw:UnknownQueryExpressionDialectFault" />
+ <wsdl:fault name="InvalidQueryExpressionFault"
+ message="wsrf-rpw:InvalidQueryExpressionFault" />
+ <wsdl:fault name="QueryEvaluationErrorFault"
+ message="wsrf-rpw:QueryEvaluationErrorFault" />
+ </wsdl:operation>
+
+ </wsdl:portType>
+
+</wsdl:definitions> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.xsd
new file mode 100644
index 0000000000..c408b36db1
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.xsd
@@ -0,0 +1,394 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+<xsd:schema
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ elementFormDefault="qualified" attributeFormDefault="unqualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rp-2"
+>
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/bf-2"
+ schemaLocation="WS-BaseFaults-1_2.xsd"
+ />
+<!-- =============== Resource Property Related =================== -->
+<!-- ====== Resource Properties for QueryResourceProperties ======= -->
+ <xsd:element name="QueryExpressionDialect" type="xsd:anyURI"/>
+
+ <xsd:element name="QueryExpressionRPDocument">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:QueryExpressionDialect"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ======= Global Attribute Declaration for WSDL 1.1 portType==== -->
+ <xsd:attribute name="ResourceProperties" type="xsd:QName" />
+
+<!-- = Notification Message for ResourceProperties value change === -->
+ <xsd:complexType name="ResourcePropertyValueChangeNotificationType">
+ <xsd:sequence>
+ <xsd:element name="OldValues" nillable="true"
+ minOccurs="0" maxOccurs="1" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="NewValues" nillable="true"
+ minOccurs="1" maxOccurs="1" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="ResourcePropertyValueChangeNotification"
+ type="wsrf-rp:ResourcePropertyValueChangeNotificationType" />
+
+ <xsd:complexType name="QueryExpressionType" mixed="true">
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="1" processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="Dialect" type="xsd:anyURI" />
+ </xsd:complexType>
+
+ <xsd:element name="QueryExpression" type="wsrf-rp:QueryExpressionType" />
+
+<!-- ======= Message Types for GetResourcePropertyDocument ======= -->
+
+ <xsd:element name="GetResourcePropertyDocument">
+ <xsd:complexType/>
+ </xsd:element>
+
+ <xsd:element name="GetResourcePropertyDocumentResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="1" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ========== Message Types for GetResourceProperty ============ -->
+
+ <xsd:element name="GetResourceProperty"
+ type="xsd:QName" />
+
+ <xsd:element name="GetResourcePropertyResponse" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="InvalidResourcePropertyQNameFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidResourcePropertyQNameFault"
+ type="wsrf-rp:InvalidResourcePropertyQNameFaultType"/>
+
+<!-- ====== Message Types for GetMultipleResourceProperties ======= -->
+ <xsd:element name="GetMultipleResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="ResourceProperty" type="xsd:QName"
+ minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="GetMultipleResourcePropertiesResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ========== Message Types for PutResourceProperty ============ -->
+
+ <xsd:element name="PutResourcePropertyDocument">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="1" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="PutResourcePropertyDocumentResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="ResourcePropertyChangeFailureType">
+ <xsd:sequence>
+ <xsd:element name="CurrentValue" minOccurs="0" maxOccurs="1">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="RequestedValue" minOccurs="0" maxOccurs="1">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:attribute name="Restored" type="xsd:boolean"/>
+ </xsd:complexType>
+
+ <xsd:complexType
+ name="UnableToPutResourcePropertyDocumentFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="ResourcePropertyChangeFailure" type=
+ "wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnableToPutResourcePropertyDocumentFault"
+ type=
+ "wsrf-rp:UnableToPutResourcePropertyDocumentFaultType"/>
+
+<!-- ========= Message Types for SetResourceProperties =========== -->
+
+ <xsd:complexType name="InsertType">
+ <xsd:sequence>
+ <xsd:any processContents="lax"
+ minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Insert" type="wsrf-rp:InsertType"/>
+
+ <xsd:complexType name="UpdateType">
+ <xsd:sequence>
+ <xsd:any processContents="lax"
+ minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Update" type="wsrf-rp:UpdateType"/>
+
+ <xsd:complexType name="DeleteType">
+ <xsd:attribute name="ResourceProperty"
+ type="xsd:QName" use="required" />
+ </xsd:complexType>
+ <xsd:element name="Delete" type="wsrf-rp:DeleteType"/>
+
+ <xsd:element name="SetResourceProperties">
+ <xsd:complexType>
+ <xsd:choice minOccurs="1" maxOccurs="unbounded">
+ <xsd:element ref="wsrf-rp:Insert"/>
+ <xsd:element ref="wsrf-rp:Update"/>
+ <xsd:element ref="wsrf-rp:Delete"/>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="SetResourcePropertiesResponse" >
+ <xsd:complexType />
+ </xsd:element>
+
+ <xsd:complexType
+ name="InvalidModificationFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="ResourcePropertyChangeFailure" type=
+ "wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name=
+ "InvalidModificationFault"
+ type=
+ "wsrf-rp:InvalidModificationFaultType"/>
+
+ <xsd:complexType name="UnableToModifyResourcePropertyFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="ResourcePropertyChangeFailure" type=
+ "wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnableToModifyResourcePropertyFault"
+ type="wsrf-rp:UnableToModifyResourcePropertyFaultType"/>
+
+ <xsd:complexType name="SetResourcePropertyRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="ResourcePropertyChangeFailure" type=
+ "wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="SetResourcePropertyRequestFailedFault"
+ type=
+ "wsrf-rp:SetResourcePropertyRequestFailedFaultType"/>
+
+ <xsd:complexType name="InsertResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="ResourcePropertyChangeFailure" type=
+ "wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InsertResourcePropertiesRequestFailedFault"
+ type=
+ "wsrf-rp:InsertResourcePropertiesRequestFailedFaultType"/>
+
+ <xsd:complexType name="UpdateResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="ResourcePropertyChangeFailure" type=
+ "wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UpdateResourcePropertiesRequestFailedFault"
+ type="wsrf-rp:UpdateResourcePropertiesRequestFailedFaultType"/>
+
+ <xsd:complexType name="DeleteResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="ResourcePropertyChangeFailure" type=
+ "wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="DeleteResourcePropertiesRequestFailedFault"
+ type="wsrf-rp:DeleteResourcePropertiesRequestFailedFaultType"/>
+
+<!-- ======== Message Types for InsertResourceProperties ========== -->
+ <xsd:element name="InsertResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Insert"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="InsertResourcePropertiesResponse" >
+ <xsd:complexType />
+ </xsd:element>
+
+<!-- ======== Message Types for UpdateResourceProperties ========== -->
+ <xsd:element name="UpdateResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Update"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="UpdateResourcePropertiesResponse" >
+ <xsd:complexType />
+ </xsd:element>
+
+<!-- ======== Message Types for DeleteResourceProperties ========== -->
+ <xsd:element name="DeleteResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Delete"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="DeleteResourcePropertiesResponse" >
+ <xsd:complexType />
+ </xsd:element>
+
+<!-- ========= Message Types for QueryResourceProperties ========== -->
+
+ <xsd:element name="QueryResourceProperties" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:QueryExpression"
+ minOccurs="1" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="QueryResourcePropertiesResponse" >
+ <xsd:complexType>
+ <xsd:complexContent mixed="true">
+ <xsd:restriction base="xsd:anyType">
+ <xsd:sequence>
+ <xsd:any processContents="lax"
+ minOccurs="1" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="UnknownQueryExpressionDialectFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnknownQueryExpressionDialectFault"
+ type="wsrf-rp:UnknownQueryExpressionDialectFaultType"/>
+
+ <xsd:complexType name="InvalidQueryExpressionFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidQueryExpressionFault"
+ type="wsrf-rp:InvalidQueryExpressionFaultType"/>
+
+ <xsd:complexType name="QueryEvaluationErrorFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="QueryEvaluationErrorFault"
+ type="wsrf-rp:QueryEvaluationErrorFaultType"/>
+
+</xsd:schema> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.wsdl b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.wsdl
new file mode 100644
index 0000000000..a75cd59728
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.wsdl
@@ -0,0 +1,269 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions
+ targetNamespace="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns:tns="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2"
+ xmlns:wsrf-sgw="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl-soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ name="ServiceGroup">
+ <wsdl:types>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <xsd:include schemaLocation="WS-MetadataExchange-2004_09.xsd"/>
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rp-2">
+ <xsd:include schemaLocation="WS-ResourceProperties-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/r-2">
+ <xsd:include schemaLocation="WS-Resource-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/sg-2">
+ <xsd:include schemaLocation="WS-ServiceGroup-1_2.xsd" />
+ </xsd:schema>
+ </wsdl:types>
+ <wsdl:message name="GetMetadataMsg">
+ <wsdl:part name="GetMetadataMsg" element="wsx:GetMetadata" />
+ </wsdl:message>
+ <wsdl:message name="GetMetadataResponseMsg">
+ <wsdl:part name="GetMetadataResponseMsg" element="wsx:Metadata" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnknownFault">
+ <wsdl:part name="ResourceUnknownFault" element="wsrf-r:ResourceUnknownFault" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnavailableFault">
+ <wsdl:part name="ResourceUnavailableFault" element="wsrf-r:ResourceUnavailableFault" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentRequest">
+ <wsdl:part name="GetResourcePropertyDocumentRequest" element="wsrf-rp:GetResourcePropertyDocument"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentResponse">
+ <wsdl:part name="GetResourcePropertyDocumentResponse" element="wsrf-rp:GetResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyRequest">
+ <wsdl:part name="GetResourcePropertyRequest" element="wsrf-rp:GetResourceProperty" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyResponse">
+ <wsdl:part name="GetResourcePropertyResponse" element="wsrf-rp:GetResourcePropertyResponse" />
+ </wsdl:message>
+ <wsdl:message name="InvalidResourcePropertyQNameFault">
+ <wsdl:part name="InvalidResourcePropertyQNameFault" element="wsrf-rp:InvalidResourcePropertyQNameFault" />
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesRequest">
+ <wsdl:part name="GetMultipleResourcePropertiesRequest" element="wsrf-rp:GetMultipleResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesResponse">
+ <wsdl:part name="GetMultipleResourcePropertiesResponse" element="wsrf-rp:GetMultipleResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesRequest">
+ <wsdl:part name="QueryResourcePropertiesRequest" element="wsrf-rp:QueryResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesResponse">
+ <wsdl:part name="QueryResourcePropertiesResponse" element="wsrf-rp:QueryResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:message name="UnknownQueryExpressionDialectFault">
+ <wsdl:part name="UnknownQueryExpressionDialectFault" element="wsrf-rp:UnknownQueryExpressionDialectFault" />
+ </wsdl:message>
+ <wsdl:message name="InvalidQueryExpressionFault">
+ <wsdl:part name="InvalidQueryExpressionFault" element="wsrf-rp:InvalidQueryExpressionFault" />
+ </wsdl:message>
+ <wsdl:message name="QueryEvaluationErrorFault">
+ <wsdl:part name="QueryEvaluationErrorFault" element="wsrf-rp:QueryEvaluationErrorFault" />
+ </wsdl:message>
+ <wsdl:portType
+ name="ServiceGroupPortType"
+ wsrf-rp:ResourceProperties="wsrf-sg:ServiceGroupRP">
+ <wsdl:operation name="GetMetadata">
+ <wsdl:input wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata"
+ name="GetMetadataMsg" message="tns:GetMetadataMsg"/>
+ <wsdl:output wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse"
+ name="GetMetadataResponseMsg" message="tns:GetMetadataResponseMsg"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"
+ name="GetResourcePropertyDocumentRequest" message="tns:GetResourcePropertyDocumentRequest"/>
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse"
+ name="GetResourcePropertyDocumentResponse" message="tns:GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault name="ResourceUnknownFault" message="tns:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="tns:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"
+ name="GetResourcePropertyRequest" message="tns:GetResourcePropertyRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse"
+ name="GetResourcePropertyResponse" message="tns:GetResourcePropertyResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="tns:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="tns:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="tns:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"
+ name="GetMultipleResourcePropertiesRequest" message="tns:GetMultipleResourcePropertiesRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse"
+ name="GetMultipleResourcePropertiesResponse" message="tns:GetMultipleResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="tns:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="tns:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="tns:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesRequest"
+ name="QueryResourcePropertiesRequest" message="tns:QueryResourcePropertiesRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesResponse"
+ name="QueryResourcePropertiesResponse" message="tns:QueryResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="tns:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="tns:ResourceUnavailableFault"/>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault" message="tns:UnknownQueryExpressionDialectFault"/>
+ <wsdl:fault name="InvalidQueryExpressionFault" message="tns:InvalidQueryExpressionFault"/>
+ <wsdl:fault name="QueryEvaluationErrorFault" message="tns:QueryEvaluationErrorFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="ServiceGroupBinding" type="tns:ServiceGroupPortType">
+ <wsdl-soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="GetMetadata" />
+ <wsdl:input>
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl-soap:operation soapAction="GetResourcePropertyDocument"/>
+ <wsdl:input name="GetResourcePropertyDocumentRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetResourcePropertyDocumentResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl-soap:operation soapAction="GetResourceProperty"/>
+ <wsdl:input name="GetResourcePropertyRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetResourcePropertyResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl-soap:operation soapAction="GetMultipleResourceProperties"/>
+ <wsdl:input name="GetMultipleResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetMultipleResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl-soap:operation soapAction="QueryResourceProperties"/>
+ <wsdl:input name="QueryResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="QueryResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="UnknownQueryExpressionDialectFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidQueryExpressionFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="InvalidQueryExpressionFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="QueryEvaluationErrorFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="QueryEvaluationErrorFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="ServiceGroupService">
+ <wsdl:port name="ServiceGroupPort" binding="tns:ServiceGroupBinding">
+ <wsdl-soap:address location="http://localhost:8080/wsrf/services/ServiceGroup"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.xsd
new file mode 100644
index 0000000000..87238f90e5
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.xsd
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+<xsd:schema
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/sg-2" >
+<!-- ======================== Imports ============================ -->
+
+ <xsd:import
+ namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="WS-Addressing-2005_08.xsd"/>
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/bf-2"
+ schemaLocation="WS-BaseFaults-1_2.xsd" />
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/rp-2"
+ schemaLocation="WS-ResourceProperties-1_2.xsd" />
+
+<!-- =============== Resource Property Related =================== -->
+<!-- ============ Resource Properties for ServiceGroup ============ -->
+ <xsd:simpleType name="AbsoluteOrRelativeTimeType">
+ <xsd:union memberTypes="xsd:dateTime xsd:duration"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="ContentElementsType">
+ <xsd:list itemType="xsd:QName"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="MemberInterfacesType">
+ <xsd:list itemType="xsd:QName"/>
+ </xsd:simpleType>
+
+ <xsd:element name="MembershipContentRule">
+ <xsd:complexType>
+ <xsd:attribute name="MemberInterfaces"
+ type="wsrf-sg:MemberInterfacesType"/>
+ <xsd:attribute name="ContentElements"
+ type="wsrf-sg:ContentElementsType"
+ use="required"/>
+ <xsd:anyAttribute namespace="##other"
+ processContents="lax"/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="RPDocType">
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="lax"
+ minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other"
+ processContents="lax"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="ContentType">
+ <xsd:sequence>
+ <xsd:element name="RPDoc"
+ type="wsrf-sg:RPDocType"
+ minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other"
+ processContents="lax"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="EntryType">
+ <xsd:sequence>
+ <xsd:element name="ServiceGroupEntryEPR"
+ type="wsa:EndpointReferenceType"
+ minOccurs="1" maxOccurs="1"
+ nillable="true"/>
+ <xsd:element name="MemberServiceEPR"
+ type="wsa:EndpointReferenceType"
+ minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="wsrf-sg:Content"
+ minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+
+<!-- ========== Resource Properties for ServiceGroupEntry ========= -->
+
+ <xsd:element name="Entry"
+ type="wsrf-sg:EntryType"/>
+
+ <xsd:element name="Content"
+ type="wsrf-sg:ContentType"/>
+
+ <xsd:element name="MemberEPR"
+ type="wsa:EndpointReferenceType"/>
+
+ <xsd:element name="ServiceGroupEPR"
+ type="wsa:EndpointReferenceType"/>
+
+<!-- =============== Resource Property Related =================== -->
+<!-- ============ Resource Properties for ServiceGroup ============ -->
+ <xsd:element name="ServiceGroupRP">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:QueryExpressionDialect"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="wsrf-sg:MembershipContentRule"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="wsrf-sg:Entry"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ========== Resource Properties for ServiceGroupEntry ========= -->
+ <xsd:element name="ServiceGroupEntryRP">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-sg:ServiceGroupEPR"
+ minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="wsrf-sg:MemberEPR"
+ minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="wsrf-sg:Content"
+ minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ================= Message Specific Types ==================== -->
+<!-- ======== Message Types for ServiceGroupRegistration ========= -->
+ <xsd:element name="Add">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="MemberEPR"
+ type="wsa:EndpointReferenceType" />
+ <xsd:element ref="wsrf-sg:Content" />
+ <xsd:element name="InitialTerminationTime"
+ type="wsrf-sg:AbsoluteOrRelativeTimeType"
+ minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="AddResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="ServiceGroupEntryReference"
+ type="wsa:EndpointReferenceType"
+ minOccurs="1" maxOccurs="1" />
+ <xsd:element name="TerminationTime"
+ nillable="true"
+ type="xsd:dateTime"
+ minOccurs="1" maxOccurs="1" />
+ <xsd:element name="CurrentTime"
+ type="xsd:dateTime"
+ minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="ContentCreationFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ContentCreationFailedFault"
+ type="wsrf-sg:ContentCreationFailedFaultType"/>
+
+ <xsd:complexType name="UnsupportedMemberInterfaceFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnsupportedMemberInterfaceFault"
+ type="wsrf-sg:UnsupportedMemberInterfaceFaultType"/>
+
+ <xsd:complexType name="AddRefusedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="AddRefusedFault"
+ type="wsrf-sg:AddRefusedFaultType"/>
+
+<!-- = Messages Related to ServiceGroup Change Notification ======= -->
+ <xsd:complexType name="ServiceGroupModificationNotificationType">
+ <xsd:sequence>
+ <xsd:element name="ServiceGroupEntryEPR"
+ type="wsa:EndpointReferenceType"
+ minOccurs="1" maxOccurs="1"
+ nillable="true"/>
+ <xsd:element name="MemberServiceEPR"
+ type="wsa:EndpointReferenceType"
+ minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="wsrf-sg:Content"
+ minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="ServiceGroupRemovalNotificationType">
+ <xsd:complexContent>
+ <xsd:extension
+ base="wsrf-sg:ServiceGroupModificationNotificationType">
+ <xsd:sequence>
+ <xsd:element name="Reason"
+ type="xsd:string"
+ minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="EntryAdditionNotification"
+ type="wsrf-sg:ServiceGroupModificationNotificationType" />
+
+ <xsd:element name="EntryRemovalNotification"
+ type="wsrf-sg:ServiceGroupRemovalNotificationType" />
+
+</xsd:schema>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl
new file mode 100644
index 0000000000..379382c18d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions
+ targetNamespace="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns:tns="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2"
+ xmlns:wsrf-sgw="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl-soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ name="ServiceGroupEntry">
+ <wsdl:types>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <xsd:include schemaLocation="WS-MetadataExchange-2004_09.xsd"/>
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rp-2">
+ <xsd:include schemaLocation="WS-ResourceProperties-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/r-2">
+ <xsd:include schemaLocation="WS-Resource-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/sg-2">
+ <xsd:include schemaLocation="WS-ServiceGroup-1_2.xsd" />
+ </xsd:schema>
+ </wsdl:types>
+ <wsdl:message name="GetMetadataMsg">
+ <wsdl:part name="GetMetadataMsg" element="wsx:GetMetadata" />
+ </wsdl:message>
+ <wsdl:message name="GetMetadataResponseMsg">
+ <wsdl:part name="GetMetadataResponseMsg" element="wsx:Metadata" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnknownFault">
+ <wsdl:part name="ResourceUnknownFault" element="wsrf-r:ResourceUnknownFault" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnavailableFault">
+ <wsdl:part name="ResourceUnavailableFault" element="wsrf-r:ResourceUnavailableFault" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentRequest">
+ <wsdl:part name="GetResourcePropertyDocumentRequest" element="wsrf-rp:GetResourcePropertyDocument"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentResponse">
+ <wsdl:part name="GetResourcePropertyDocumentResponse" element="wsrf-rp:GetResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyRequest">
+ <wsdl:part name="GetResourcePropertyRequest" element="wsrf-rp:GetResourceProperty" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyResponse">
+ <wsdl:part name="GetResourcePropertyResponse" element="wsrf-rp:GetResourcePropertyResponse" />
+ </wsdl:message>
+ <wsdl:message name="InvalidResourcePropertyQNameFault">
+ <wsdl:part name="InvalidResourcePropertyQNameFault" element="wsrf-rp:InvalidResourcePropertyQNameFault" />
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesRequest">
+ <wsdl:part name="GetMultipleResourcePropertiesRequest" element="wsrf-rp:GetMultipleResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesResponse">
+ <wsdl:part name="GetMultipleResourcePropertiesResponse" element="wsrf-rp:GetMultipleResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:portType
+ name="ServiceGroupEntryPortType"
+ wsrf-rp:ResourceProperties="wsrf-sg:ServiceGroupEntryRP">
+ <wsdl:operation name="GetMetadata">
+ <wsdl:input wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata"
+ name="GetMetadataMsg" message="tns:GetMetadataMsg"/>
+ <wsdl:output wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse"
+ name="GetMetadataResponseMsg" message="tns:GetMetadataResponseMsg"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"
+ name="GetResourcePropertyDocumentRequest" message="tns:GetResourcePropertyDocumentRequest"/>
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse"
+ name="GetResourcePropertyDocumentResponse" message="tns:GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault name="ResourceUnknownFault" message="tns:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="tns:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"
+ name="GetResourcePropertyRequest" message="tns:GetResourcePropertyRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse"
+ name="GetResourcePropertyResponse" message="tns:GetResourcePropertyResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="tns:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="tns:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="tns:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"
+ name="GetMultipleResourcePropertiesRequest" message="tns:GetMultipleResourcePropertiesRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse"
+ name="GetMultipleResourcePropertiesResponse" message="tns:GetMultipleResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="tns:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="tns:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="tns:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="ServiceGroupEntryBinding" type="tns:ServiceGroupEntryPortType">
+ <wsdl-soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="GetMetadata" />
+ <wsdl:input>
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl-soap:operation soapAction="GetResourcePropertyDocument"/>
+ <wsdl:input name="GetResourcePropertyDocumentRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetResourcePropertyDocumentResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl-soap:operation soapAction="GetResourceProperty"/>
+ <wsdl:input name="GetResourcePropertyRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetResourcePropertyResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl-soap:operation soapAction="GetMultipleResourceProperties"/>
+ <wsdl:input name="GetMultipleResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetMultipleResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="ServiceGroupEntryService">
+ <wsdl:port name="ServiceGroupEntryPort" binding="tns:ServiceGroupEntryBinding">
+ <wsdl-soap:address location="http://localhost:8080/wsrf/services/ServiceGroupEntry"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-Topics-1_3.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-Topics-1_3.xsd
new file mode 100644
index 0000000000..df98513131
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-Topics-1_3.xsd
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2004-2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+
+
+<xsd:schema
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wstop = "http://docs.oasis-open.org/wsn/t-1"
+ targetNamespace = "http://docs.oasis-open.org/wsn/t-1"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+<!-- =============== utility type definitions ==================== -->
+ <xsd:complexType name="Documentation" mixed="true">
+ <xsd:sequence>
+ <xsd:any processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" namespace="##any"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="ExtensibleDocumented" abstract="true"
+ mixed="false">
+ <xsd:sequence>
+ <xsd:element name="documentation" type="wstop:Documentation"
+ minOccurs="0" />
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax" />
+</xsd:complexType>
+
+<xsd:complexType name="QueryExpressionType" mixed="true">
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="1" processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="Dialect" type="xsd:anyURI" use="required"/>
+</xsd:complexType>
+
+<!-- ================== Topic-Namespace Related ================ -->
+ <xsd:complexType name="TopicNamespaceType">
+ <xsd:complexContent>
+ <xsd:extension base="wstop:ExtensibleDocumented">
+ <xsd:sequence>
+ <xsd:element name="Topic"
+ minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wstop:TopicType">
+ <xsd:attribute name="parent" type="wstop:ConcreteTopicExpression" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:NCName"/>
+ <xsd:attribute name="targetNamespace" type="xsd:anyURI"
+ use="required"/>
+ <xsd:attribute name="final" type="xsd:boolean"
+ default="false"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="TopicNamespace" type="wstop:TopicNamespaceType">
+ <xsd:unique name="rootTopicUniqueness">
+ <xsd:selector xpath="wstop:Topic"/>
+ <xsd:field xpath="@name"/>
+ </xsd:unique>
+ </xsd:element>
+
+ <xsd:attribute name="topicNamespaceLocation" type="xsd:anyURI"/>
+
+
+
+<!-- ===================== Topic Related ========================= -->
+
+ <xsd:complexType name="TopicType">
+ <xsd:complexContent>
+ <xsd:extension base="wstop:ExtensibleDocumented">
+ <xsd:sequence>
+ <xsd:element name="MessagePattern"
+ type="wstop:QueryExpressionType"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element name="Topic" type="wstop:TopicType"
+ minOccurs="0" maxOccurs="unbounded">
+ <xsd:unique name="childTopicUniqueness">
+ <xsd:selector xpath="wstop:topic"/>
+ <xsd:field xpath="@name"/>
+ </xsd:unique>
+ </xsd:element>
+ <xsd:any namespace="##other" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:NCName"/>
+ <xsd:attribute name="messageTypes">
+ <xsd:simpleType>
+ <xsd:list itemType="xsd:QName"/>
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="final" type="xsd:boolean"
+ default="false"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+<!-- ================ Topic Set Related =================== -->
+
+ <xsd:complexType name="TopicSetType">
+ <xsd:complexContent>
+ <xsd:extension base="wstop:ExtensibleDocumented">
+ <xsd:sequence>
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="TopicSet" type="wstop:TopicSetType"/>
+<xsd:attribute name="topic" type="xsd:boolean" default="false"/>
+
+<!-- ================ Topic Expression Related =================== -->
+
+ <xsd:simpleType name="FullTopicExpression">
+ <xsd:restriction base="xsd:token">
+ <xsd:annotation>
+ <xsd:documentation>
+ TopicPathExpression ::= TopicPath ( '|' TopicPath )*
+ TopicPath ::= RootTopic ChildTopicExpression*
+ RootTopic ::= NamespacePrefix? ('//')? (NCName | '*')
+ NamespacePrefix ::= NCName ':'
+ ChildTopicExpression ::= '/' '/'? (QName | NCName | '*'| '.')
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:pattern value=
+ "([\i-[:]][\c-[:]]*:)?(//)?([\i-[:]][\c-[:]]*|\*)((/|//)(([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*|\*|[.]))*(\|([\i-[:]][\c-[:]]*:)?(//)?([\i-[:]][\c-[:]]*|\*)((/|//)(([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*|\*|[.]))*)*">
+ </xsd:pattern>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="ConcreteTopicExpression">
+ <xsd:restriction base="xsd:token">
+ <xsd:annotation>
+ <xsd:documentation>
+ The pattern allows strings matching the following EBNF:
+ ConcreteTopicPath ::= RootTopic ChildTopic*
+ RootTopic ::= QName
+ ChildTopic ::= '/' (QName | NCName)
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:pattern value=
+"(([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*)(/([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*)*" >
+ </xsd:pattern>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="SimpleTopicExpression">
+ <xsd:restriction base="xsd:QName">
+ <xsd:annotation>
+ <xsd:documentation>
+ The pattern allows strings matching the following EBNF:
+ RootTopic ::= QName
+
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+</xsd:schema> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part1-1_1.xsd b/qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part1-1_1.xsd
new file mode 100644
index 0000000000..c24e97a9ce
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part1-1_1.xsd
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<xs:schema
+ targetNamespace="http://docs.oasis-open.org/wsdm/muws1-2.xsd"
+ xmlns:muws1="http://docs.oasis-open.org/wsdm/muws1-2.xsd"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+ <xs:import namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="WS-Addressing-2005_08.xsd"/>
+
+
+ <xs:element name="ResourceId" type="xs:anyURI"/>
+ <xs:element name="ManageabilityCapability" type="xs:anyURI"/>
+
+
+ <xs:complexType name="CorrelatablePropertiesType">
+ <xs:sequence>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ <xs:attribute name="Dialect" type="xs:anyURI"/>
+ <xs:attribute name="NegativeAssertionPossible" type="xs:boolean"/>
+ <xs:anyAttribute namespace="##other"/>
+ </xs:complexType>
+
+ <xs:element name="CorrelatableProperties"
+ type="muws1:CorrelatablePropertiesType"/>
+
+
+ <xs:complexType name="ComponentAddressType">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ComponentType">
+ <xs:sequence>
+ <xs:element name="ResourceId" type="xs:anyURI"
+ minOccurs="0"/>
+ <xs:element name="ComponentAddress"
+ type="muws1:ComponentAddressType"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other"/>
+ </xs:complexType>
+
+
+ <xs:complexType name="ManagementEventType">
+ <xs:sequence>
+ <xs:element name="EventId" type="xs:anyURI"/>
+ <xs:element name="SourceComponent" type="muws1:ComponentType"/>
+ <xs:element name="ReporterComponent" type="muws1:ComponentType"
+ minOccurs="0"/>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ <xs:attribute name="ReportTime" type="xs:dateTime" use="optional"/>
+ <xs:anyAttribute namespace="##other"/>
+ </xs:complexType>
+
+ <xs:element name="ManagementEvent"
+ type="muws1:ManagementEventType"/>
+
+ <xs:element name="ManageabilityEndpointReference"
+ type="wsa:EndpointReferenceType"/>
+
+
+<!--
+ SCHEMA COPY Material
+Copy and paste element references below into the schema of a resource properties document.
+These references are provide to insure that the correct minOccurs/maxOccurs attributes are specified in a resource property document schema.
+
+NOTE: You must import the MUWS Part 1 schema namespace (MUWS1).
+
+ ** Identity Properties **
+ <xs:element ref="muws1:ResourceId"/>
+
+
+ ** ManageabilityCharacteristics Properties **
+ <xs:element ref="muws1:ManageabilityCapability"
+ minOccurs="0" maxOccurs="unbounded"/>
+
+ ** Correlatable Properties **
+ <xs:element ref="muws1:CorrelatableProperties"
+ minOccurs="0" maxOccurs="unbounded"/>
+
+-->
+
+</xs:schema>
+
diff --git a/qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part2-1_1.xsd b/qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part2-1_1.xsd
new file mode 100644
index 0000000000..5ea0954734
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part2-1_1.xsd
@@ -0,0 +1,677 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<xs:schema targetNamespace="http://docs.oasis-open.org/wsdm/muws2-2.xsd"
+ xmlns:muws2="http://docs.oasis-open.org/wsdm/muws2-2.xsd"
+ xmlns:muws1="http://docs.oasis-open.org/wsdm/muws1-2.xsd"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+ <xs:import namespace="http://docs.oasis-open.org/wsdm/muws1-2.xsd"
+ schemaLocation="WSDM-MUWS-Part1-1_1.xsd" />
+ <xs:import namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="WS-Addressing-2005_08.xsd" />
+ <xs:import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="XML-Namespace-1998.xsd" />
+ <xs:complexType name="LangString">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute ref="xml:lang" use="required" />
+ <xs:anyAttribute namespace="##other" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <!-- Begin properties for the Description capability -->
+ <xs:element name="Caption" type="muws2:LangString" />
+ <xs:element name="Description" type="muws2:LangString" />
+ <xs:element name="Version" type="xs:string" />
+ <!-- End properties for the Description capability -->
+ <xs:complexType name="CategoryType">
+ <xs:sequence>
+ <xs:any minOccurs="0" namespace="##any"
+ processContents="lax" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="StateType">
+ <xs:complexContent>
+ <xs:extension base="muws2:CategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="State" type="muws2:StateType" />
+ <xs:element name="EnteredState" type="muws2:StateType" />
+ <xs:element name="PreviousState" type="muws2:StateType" />
+ <xs:complexType name="StateTransitionType">
+ <xs:sequence>
+ <xs:element ref="muws2:EnteredState" />
+ <xs:element ref="muws2:PreviousState" minOccurs="0" />
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax" />
+ </xs:sequence>
+ <xs:attribute name="TransitionIdentifier" type="xs:anyURI"
+ use="optional" />
+ <xs:attribute name="Time" type="xs:dateTime" use="required" />
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ <xs:element name="StateTransition" type="muws2:StateTransitionType" />
+ <!-- Begin properties for the OperationalStatus capability -->
+ <xs:element name="OperationalStatus">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Available" />
+ <xs:enumeration value="PartiallyAvailable" />
+ <xs:enumeration value="Unavailable" />
+ <xs:enumeration value="Unknown" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <!-- End properties for the OperationalStatus capability -->
+ <xs:attributeGroup name="MetricAttributes">
+ <xs:attribute name="ResetAt" type="xs:dateTime" />
+ <xs:attribute name="LastUpdated" type="xs:dateTime" />
+ <xs:attribute name="Duration" type="xs:duration" />
+ </xs:attributeGroup>
+ <!-- Begin properties for the Metrics capability -->
+ <xs:element name="CurrentTime" type="xs:dateTime" />
+ <!-- End properties for the Metrics capability -->
+ <xs:complexType name="RelationshipTypeType">
+ <xs:complexContent>
+ <xs:extension base="muws2:CategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="Self">
+ <xs:complexType />
+ </xs:element>
+ <xs:complexType name="RelationshipParticipantType">
+ <xs:sequence>
+ <xs:element ref="muws2:Self" minOccurs="0" />
+ <xs:element ref="muws1:ManageabilityEndpointReference"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xs:element ref="wsa:EndpointReference" minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element ref="muws1:ResourceId" minOccurs="0" />
+ <xs:element name="Role" type="xs:anyURI" />
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ <!-- Begin properties for the RelationshipResource capability -->
+ <xs:element name="Name" type="xs:string" />
+ <xs:element name="Type" type="muws2:RelationshipTypeType" />
+ <xs:element name="Participant"
+ type="muws2:RelationshipParticipantType" />
+ <!-- End properties for the RelationshipResource capability -->
+ <xs:complexType name="RelationshipType">
+ <xs:sequence>
+ <xs:element ref="muws2:Name" minOccurs="0" />
+ <xs:element ref="muws2:Type" />
+ <xs:element ref="muws2:Participant" minOccurs="2"
+ maxOccurs="unbounded" />
+ <xs:element name="AccessEndpointReference"
+ type="wsa:EndpointReferenceType" minOccurs="0" />
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ <!-- Begin properties for the Relationship capability -->
+ <xs:element name="Relationship" type="muws2:RelationshipType" />
+ <!-- End properties for the Relationship capability -->
+ <xs:element name="RelationshipCreatedNotification">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="muws2:Relationship" />
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="RelationshipDeletedNotification">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="muws2:Relationship" />
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="QueryRelationshipsByType">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="RequestedType" type="xs:QName" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="QueryRelationshipsByTypeResponse">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="muws2:Relationship" minOccurs="0"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="CreationNotification">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="muws1:ManageabilityEndpointReference"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="DestructionNotification">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="muws1:ResourceId" minOccurs="0" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ </xs:element>
+ <xs:complexType name="SituationCategoryType">
+ <xs:complexContent>
+ <xs:extension base="muws2:CategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="SubstitutableMsgType">
+ <xs:sequence>
+ <xs:element name="Value" type="xs:anySimpleType"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="MsgId" type="xs:string" use="required" />
+ <xs:attribute name="MsgIdType" type="xs:anyURI" use="required" />
+ </xs:complexType>
+ <xs:complexType name="SituationType">
+ <xs:sequence>
+ <xs:element name="SituationCategory"
+ type="muws2:SituationCategoryType" />
+ <xs:element name="SuccessDisposition" minOccurs="0">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Successful" />
+ <xs:enumeration value="Unsuccessful" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="SituationTime" type="xs:dateTime" />
+ <xs:element name="Priority" type="xs:short" minOccurs="0" />
+ <xs:element name="Severity" type="xs:short" minOccurs="0" />
+ <xs:element name="Message" type="muws2:LangString"
+ minOccurs="0" />
+ <xs:element name="SubstitutableMsg"
+ type="muws2:SubstitutableMsgType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:element name="Situation" type="muws2:SituationType" />
+ <xs:complexType name="EventCorrelationPropertiesType">
+ <xs:sequence>
+ <xs:element name="repeatCount" minOccurs="0"
+ maxOccurs="1">
+ <xs:simpleType>
+ <xs:restriction base="xs:short">
+ <xs:minInclusive value="0" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="elapsedTime" minOccurs="0"
+ maxOccurs="1">
+ <xs:simpleType>
+ <xs:restriction base="xs:long">
+ <xs:minInclusive value="0" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="sequenceNumber" type="xs:unsignedLong" />
+ </xs:complexType>
+ <xs:element name="EventCorrelationProperties"
+ type="muws2:EventCorrelationPropertiesType" />
+ <xs:complexType name="MsgCatalogInformationType">
+ <xs:sequence>
+ <xs:element name="msgCatalog" type="xs:anyURI"
+ minOccurs="1" />
+ <xs:element name="msgCatalogType" type="xs:anyURI"
+ minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:element name="MsgCatalogInformation"
+ type="muws2:MsgCatalogInformationType" />
+ <!-- ##### Metadata description elements ##### -->
+ <xs:element name="Capability" type="xs:anyURI" />
+ <xs:complexType name="DialectableExpressionType" mixed="true">
+ <xs:sequence>
+ <xs:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="Dialect" type="xs:anyURI" use="required" />
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ <xs:element name="ValidWhile"
+ type="muws2:DialectableExpressionType" />
+ <xs:element name="Units" type="xs:string" />
+ <xs:element name="ChangeType">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Counter" />
+ <xs:enumeration value="Gauge" />
+ <xs:enumeration value="Unknown" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="TimeScope">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Interval" />
+ <xs:enumeration value="PointInTime" />
+ <xs:enumeration value="SinceReset" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="GatheringTime">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="OnChange" />
+ <xs:enumeration value="Periodic" />
+ <xs:enumeration value="OnDemand" />
+ <xs:enumeration value="Unknown" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="CalculationInterval" type="xs:duration" />
+ <xs:element name="MetricGroup" type="xs:anyURI" />
+ <xs:element name="PostCondition"
+ type="muws2:DialectableExpressionType" />
+ <!-- ========= StartSituation ============ -->
+ <xs:element name="StartSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="StartInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:StartSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="RestartInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:StartSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="StartCompleted">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:StartSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= StopSituation ============ -->
+ <xs:element name="StopSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="StopInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:StopSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="AbortInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:StopSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="PauseInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:StopSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="StopCompleted">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:StopSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= RequestSituation ============ -->
+ <xs:element name="RequestSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="RequestInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:RequestSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="RequestCompleted">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:RequestSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= DestroySituation ============ -->
+ <xs:element name="DestroySituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="DestroyInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:DestroySituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="DestroyCompleted">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:DestroySituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= CreateSituation ============ -->
+ <xs:element name="CreateSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="CreateInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:CreateSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="CreateCompleted">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:CreateSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= ConnectSituation ============ -->
+ <xs:element name="ConnectSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="ConnectInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ConnectSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="ReconnectInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ConnectSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="ConnectCompleted">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ConnectSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= ReportSituation ============ -->
+ <xs:element name="ReportSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="PerformanceReport">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ReportSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="SecurityReport">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ReportSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="HeartbeatReport">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ReportSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="StatusReport">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ReportSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="TraceReport">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ReportSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="DebugReport">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ReportSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="LogReport">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ReportSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= AvailabilitySituation ============ -->
+ <xs:element name="AvailabilitySituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= CapabilitySituation ============ -->
+ <xs:element name="CapabilitySituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= ConfigureSituation ============ -->
+ <xs:element name="ConfigureSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= OtherSituation ============ -->
+ <xs:element name="OtherSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!--
+ SCHEMA COPY Material
+ Copy and paste element references below into the schema of a resource properties document.
+ These references insure that the correct minOccurs/maxOccurs attributes are specified in a resource property document schema.
+
+ NOTE: You must import the MUWS Part 2 schema namespace (MUWS2).
+
+ ** Description Properties **
+ <xs:element ref="muws2:Caption"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element ref="muws2:Description"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element ref="muws2:Version"
+ minOccurs="0"/>
+
+ ** Operational Status **
+ <xs:element ref="muws2:OperationalStatus"/>
+
+ ** Metrics **
+ <xs:element ref="muws2:CurrentTime"/>
+
+ ** Relationship **
+ <xs:element ref="muws2:Relationship"
+ minOccurs="0" maxOccurs="unbounded"/>
+
+ ** Relationship Resource **
+ <xs:element ref="muws2:Name" minOccurs="0"/>
+ <xs:element ref="muws2:Type"/>
+ <xs:element ref="muws2:Participant"
+ minOccurs="2" maxOccurs="unbounded"/>
+
+ -->
+</xs:schema>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WsResource.rmd b/qpid/java/management/client/src/main/java/wsdl/WsResource.rmd
new file mode 100644
index 0000000000..b15f7eca1c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WsResource.rmd
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<Definitions xmlns="http://docs.oasis-open.org/wsrf/rmd-1" >
+
+ <MetadataDescriptor xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman" name="QManWsResourceMetadata"
+ interface="qman:QManWsResourcePortType"
+ wsdlLocation="http://ws.apache.org/muse/test/wsrf QManWsResource.wsdl" >
+
+ <Property name="wsrl:CurrentTime" modifiability="read-only" mutability="mutable" />
+
+ <Property name="wsrl:TerminationTime" modifiability="read-only" mutability="mutable" />
+ </MetadataDescriptor>
+
+</Definitions> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WsResourceFactory.wsdl b/qpid/java/management/client/src/main/java/wsdl/WsResourceFactory.wsdl
new file mode 100644
index 0000000000..83a7e5ad8c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WsResourceFactory.wsdl
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions
+ targetNamespace="http://ws.apache.org/muse/test/wsrf"
+ xmlns:tns="http://ws.apache.org/muse/test/wsrf"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl-soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ name="WsResourceFactory">
+ <wsdl:types>
+ </wsdl:types>
+ <wsdl:portType name="WsResourceFactoryPortType" >
+ </wsdl:portType>
+ <wsdl:binding name="WsResourceFactoryBinding" type="tns:WsResourceFactoryPortType">
+ <wsdl-soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+ </wsdl:binding>
+ <wsdl:service name="WsResourceFactoryService">
+ <wsdl:port name="WsResourceFactoryPort" binding="tns:WsResourceFactoryBinding">
+ <wsdl-soap:address location="http://romagazzarini:8080/wsrf/services/WsResourceFactory"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>
diff --git a/qpid/java/management/client/src/main/java/wsdl/XML-Namespace-1998.xsd b/qpid/java/management/client/src/main/java/wsdl/XML-Namespace-1998.xsd
new file mode 100644
index 0000000000..f51b67f78f
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/XML-Namespace-1998.xsd
@@ -0,0 +1,46 @@
+<?xml version='1.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.
+
+-->
+
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en">
+
+ <xs:attribute name="lang" type="xs:language">
+ </xs:attribute>
+
+ <xs:attribute name="space" default="preserve">
+ <xs:simpleType>
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="base" type="xs:anyURI">
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ </xs:attributeGroup>
+
+</xs:schema>
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java
new file mode 100644
index 0000000000..9abcd08eef
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.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.management;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.domain.model.DomainModel;
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Collects all literal constants used in test cases.
+ */
+public interface TestConstants
+{
+ UUID BROKER_ID = UUID.randomUUID();
+ Binary OBJECT_ID = new Binary(new byte []{1,2,3,2,1,1,2,3});
+
+ DomainModel DOMAIN_MODEL = new DomainModel(BROKER_ID);
+
+ String AGE_ATTRIBUTE_NAME = "age";
+ String AGE_ATTRIBUTE_DESCRIPTION = "The age of a person.";
+ String SURNAME_ATTRIBUTE_NAME = "surname";
+ String SURNAME_ATTRIBUTE_DESCRIPTION = "The surname of a person.";
+ Integer _1 = new Integer(1);
+
+ byte [] TEST_RAW_DATA= new byte []{1,4,5,7,8,9,4,44};
+ long NOW = System.currentTimeMillis();
+ int SEVERITY = _1;
+
+ String QPID_PACKAGE_NAME = "qpid";
+ String EXCHANGE_CLASS_NAME = "exchange";
+ String BIND_EVENT_NAME = "bind";
+ Binary HASH = new Binary(new byte []{1,2,3,4,5,6,7,8,9});
+ int VALID_CODE = _1;
+
+ List<Map<String, Object>> EMPTY_PROPERTIES_SCHEMA = new LinkedList<Map<String,Object>>();
+ List<Map<String, Object>> EMPTY_STATISTICS_SCHEMA = new LinkedList<Map<String,Object>>();
+ List<MethodOrEventDataTransferObject> EMPTY_METHODS_SCHEMA = new LinkedList<MethodOrEventDataTransferObject>();
+ List<Map<String, Object>> EMPTY_ARGUMENTS_SCHEMA = new LinkedList<Map<String,Object>>();
+ int _0 = 0;
+ int SAMPLE_ACCESS_CODE = 1;
+ String YEARS = "years";
+ int SAMPLE_MIN_VALUE = 1;
+ int SAMPLE_MAX_VALUE = 120;
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java
new file mode 100644
index 0000000000..72bd45f70f
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java
@@ -0,0 +1,181 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.configuration;
+
+import java.util.Map;
+import java.util.UUID;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.TestConstants;
+import org.apache.qpid.management.domain.handler.base.IMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.ConfigurationMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.InstrumentationMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.SchemaResponseMessageHandler;
+
+/**
+ * Test case for Configuration singleton.
+ */
+public class ConfigurationTest extends TestCase
+{
+ /**
+ * Tests the singleton behaviour of the configuration object.
+ */
+ public void testSingleton()
+ {
+ assertSame(Configuration.getInstance(),Configuration.getInstance());
+ }
+
+ /**
+ * Tests the execution of getType() method when a unknown code is supplied.
+ *
+ * <br>precondition : the requested type doesn't exist on the configuration.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testGetTypeKO()
+ {
+ try
+ {
+ Configuration.getInstance().getType(TestConstants.VALID_CODE*10001);
+ fail("If an unknwon code is supplied an exception must be thrown.");
+ } catch (UnknownTypeCodeException expected)
+ {
+ assertEquals(TestConstants.VALID_CODE*10001,expected.getCode());
+ }
+ }
+
+ /**
+ * Tests the execution of getAccessMode() method when a unknown code is supplied.
+ *
+ * <br>precondition : the requested access mode doesn't exist on the configuration.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testGetAccessModeKO()
+ {
+ try
+ {
+ Configuration.getInstance().getAccessMode(TestConstants.VALID_CODE*1528);
+ fail("If an unknwon code is supplied an exception must be thrown.");
+ } catch (UnknownAccessCodeException expected)
+ {
+ assertEquals(TestConstants.VALID_CODE*1528,expected.getCode());
+ }
+ }
+
+ /**
+ * Tests the execution of the getBrokerConnectionData when a valid broker id is supplied.
+ *
+ * <br>precondition : on configuration a connection data is stored and associated with the supplied id.
+ * <br>postcondition : the requested connection data is returned and no exception is thrown.
+ */
+ public void testGetBrokerConnectionDataOK() throws Exception
+ {
+ BrokerConnectionData connectionData = new BrokerConnectionData();
+ connectionData.setHost("host");
+ connectionData.setPort("7001");
+ connectionData.setInitialPoolCapacity("0");
+ connectionData.setMaxPoolCapacity("10");
+ connectionData.setMaxWaitTimeout("1");
+ Configuration.getInstance().addBrokerConnectionData(TestConstants.BROKER_ID, connectionData);
+
+ BrokerConnectionData result = Configuration.getInstance().getBrokerConnectionData(TestConstants.BROKER_ID);
+ assertSame(connectionData, result);
+ }
+
+ /**
+ * Tests the execution of the getBrokerConnectionData when a unknown broker id is supplied.
+ *
+ * <br>precondition : on configuration there's no connection data associated with the supplied id.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testGetBrokerConnectionDataKO_withUnknownBrokerId()
+ {
+ UUID brokerId = UUID.randomUUID();
+ try
+ {
+ Configuration.getInstance().getBrokerConnectionData(brokerId);
+ fail("If an unknown broker id is supplied then an exception must be thrown.");
+ } catch(UnknownBrokerException expected)
+ {
+ assertEquals(brokerId.toString(),expected.getMessage());
+ }
+ }
+
+ /**
+ * Tests the execution of the getBrokerConnectionData when a null id is supplied.
+ *
+ * <br>precondition : a null broker is given.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testGetBrokerConnectionDataKO_withNullBrokerId()
+ {
+ try
+ {
+ Configuration.getInstance().getBrokerConnectionData(null);
+ fail("If a null broker id is supplied then an exception must be thrown.");
+ } catch(UnknownBrokerException expected)
+ {
+ }
+ }
+
+ /**
+ * Tests the behaviour of the getManagementQueueHandlers() method.
+ *
+ * <br>precondition: 2 management handlers are in stored configuration
+ * <br>postcondition : 2 management handlers are returned.
+ */
+ public void testGetManagementQueueHandlersOk()
+ {
+ IMessageHandler instrMessageHandler = new InstrumentationMessageHandler();
+ IMessageHandler configMessageHandler = new ConfigurationMessageHandler();
+
+ MessageHandlerMapping instrMapping = new MessageHandlerMapping('i',instrMessageHandler);
+ MessageHandlerMapping configMapping = new MessageHandlerMapping('c',configMessageHandler);
+
+ Configuration.getInstance().addManagementMessageHandlerMapping(instrMapping);
+ Configuration.getInstance().addManagementMessageHandlerMapping(configMapping);
+
+ Map<Character, IMessageHandler> handlerMappings = Configuration.getInstance().getManagementQueueHandlers();
+
+ assertEquals(2,handlerMappings.size());
+ assertEquals(instrMessageHandler,handlerMappings.get(instrMapping.getOpcode()));
+ assertEquals(configMessageHandler,handlerMappings.get(configMapping.getOpcode()));
+ }
+
+ /**
+ * Tests the behaviour of the getManagementQueueHandlers() method.
+ *
+ * <br>precondition: 2 management handlers are in stored configuration
+ * <br>postcondition : 2 management handlers are returned.
+ */
+ public void testGetMethodReplyQueueHandlersOk()
+ {
+ IMessageHandler schemaMessageHandler = new SchemaResponseMessageHandler();
+
+ MessageHandlerMapping schemaMapping = new MessageHandlerMapping('s',schemaMessageHandler);
+
+ Configuration.getInstance().addMethodReplyMessageHandlerMapping(schemaMapping);
+
+ Map<Character, IMessageHandler> handlerMappings = Configuration.getInstance().getMethodReplyQueueHandlers();
+
+ assertEquals(schemaMessageHandler,handlerMappings.get(schemaMapping.getOpcode()));
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java
new file mode 100644
index 0000000000..1e464bf6ae
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java
@@ -0,0 +1,163 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.configuration;
+
+import java.util.Map;
+import java.util.UUID;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.domain.handler.base.IMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.ConfigurationMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.EventContentMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.HeartBeatIndicationMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.InstrumentationMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.MethodResponseMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.SchemaResponseMessageHandler;
+import org.apache.qpid.management.domain.model.AccessMode;
+import org.apache.qpid.management.domain.model.type.AbsTime;
+import org.apache.qpid.management.domain.model.type.DeltaTime;
+import org.apache.qpid.management.domain.model.type.ObjectReference;
+import org.apache.qpid.management.domain.model.type.Str16;
+import org.apache.qpid.management.domain.model.type.Str8;
+import org.apache.qpid.management.domain.model.type.Uint16;
+import org.apache.qpid.management.domain.model.type.Uint32;
+import org.apache.qpid.management.domain.model.type.Uint64;
+import org.apache.qpid.management.domain.model.type.Uint8;
+import org.xml.sax.SAXException;
+
+/**
+ * Test case for configurator.
+ *
+ * @author Andrea Gazzarini
+ *
+ */
+public class ConfiguratorTest extends TestCase
+{
+ /**
+ * Tests the execution of the configure() method when no configuration file is given.
+ *
+ * <br>precondition : configuration file option is not set
+ * <br>postcondition : no exception is thrown, the configuration is holding no broker data and the predefined mappings are
+ * stored in configuration.
+ */
+ public void testConfigureOK_WithNoConfigurationFile() throws Exception
+ {
+ Configurator configurator = new Configurator();
+ configurator.configure();
+ Configuration configuration = Configuration.getInstance();
+
+ assertEquals(new Uint8(), configuration.getType(1));
+ assertEquals(new Uint16(), configuration.getType(2));
+ assertEquals(new Uint32(), configuration.getType(3));
+ assertEquals(new Uint64(), configuration.getType(4));
+ assertEquals(new Str8(), configuration.getType(6));
+ assertEquals(new Str16(), configuration.getType(7));
+ assertEquals(new AbsTime(), configuration.getType(8));
+ assertEquals(new DeltaTime(), configuration.getType(9));
+ assertEquals(new ObjectReference(), configuration.getType(10));
+ assertEquals(new org.apache.qpid.management.domain.model.type.Boolean(), configuration.getType(11));
+ assertEquals(new org.apache.qpid.management.domain.model.type.Uuid(), configuration.getType(14));
+ assertEquals(new org.apache.qpid.management.domain.model.type.Map(), configuration.getType(15));
+
+ assertEquals(AccessMode.RC,configuration.getAccessMode(1));
+ assertEquals(AccessMode.RW,configuration.getAccessMode(2));
+ assertEquals(AccessMode.RO,configuration.getAccessMode(3));
+
+ Map<Character, IMessageHandler> managementHandlers = configuration.getManagementQueueHandlers();
+ assertEquals(4,managementHandlers.size());
+ assertEquals(
+ InstrumentationMessageHandler.class,
+ managementHandlers.get(Protocol.INSTRUMENTATION_CONTENT_RESPONSE_OPCODE).getClass());
+
+ assertEquals(
+ ConfigurationMessageHandler.class,
+ managementHandlers.get(Protocol.CONFIGURATION_CONTENT_RESPONSE_OPCDE).getClass());
+
+ assertEquals(
+ EventContentMessageHandler.class,
+ managementHandlers.get(Protocol.EVENT_CONTENT_RESPONSE_OPCDE).getClass());
+
+ assertEquals(
+ HeartBeatIndicationMessageHandler.class,
+ managementHandlers.get(Protocol.HEARTBEAT_INDICATION_RESPONSE_OPCODE).getClass());
+
+ Map<Character, IMessageHandler> methodReplyHandlers = configuration.getMethodReplyQueueHandlers();
+ assertEquals(2, methodReplyHandlers.size());
+
+ assertEquals(
+ MethodResponseMessageHandler.class,
+ methodReplyHandlers.get(Protocol.OPERATION_INVOCATION_RESPONSE_OPCODE).getClass());
+
+ assertEquals(
+ SchemaResponseMessageHandler.class,
+ methodReplyHandlers.get(Protocol.SCHEMA_RESPONSE_OPCODE).getClass());
+ }
+
+ /**
+ * Tests the changes of the configurator internal state while configuration file is parsed.
+ *
+ * <br>precondition: N.A.
+ * <br>postcondition: N.A.
+ */
+ public void testDirectorParsing() throws SAXException{
+ Configurator configurator = new Configurator();
+
+ assertSame(Configurator.DEFAULT_PARSER,configurator._currentParser);
+
+ configurator.startElement(null, null, Tag.BROKERS.toString(), null);
+ assertSame(configurator._brokerConfigurationParser,configurator._currentParser);
+ }
+
+ /**
+ * It's not possibile to add twice the same broker connection data.
+ * Is so an exception must be thrown indicating that the given broker is already connected.
+ *
+ * <br>precondition : the given data identifies an already connected broker.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testAddTwoIdenticalBrokers() throws ConfigurationException, BrokerConnectionException
+ {
+ Configurator configurator = new Configurator();
+ configurator.configure();
+
+ BrokerConnectionData data = new BrokerConnectionData("sofia.gazzax.com",5672,"virtualHost","user","pwd",1,4,-1);
+
+ Configuration.getInstance()._brokerConnectionInfos.put(UUID.randomUUID(),data);
+
+ try {
+ configurator.createAndReturnBrokerConnectionData(
+ UUID.randomUUID(),
+ data.getHost(),
+ data.getPort(),
+ "anotherUser",
+ "anotherPassword",
+ data.getVirtualHost(),
+ 33,
+ 12,
+ 1000);
+ fail("If a broker is added twice an exception must be thrown.");
+ } catch (BrokerAlreadyConnectedException expected) {
+ assertEquals(data,expected.getBrokerConnectionData());
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/MappingParsersTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/MappingParsersTest.java
new file mode 100644
index 0000000000..af261024bd
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/MappingParsersTest.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.management.configuration;
+
+import java.util.UUID;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.TestConstants;
+
+/**
+ * Test case for mapping parsers.
+ *
+ * @author Andrea Gazzarini.
+ */
+public class MappingParsersTest extends TestCase
+{
+ /**
+ * Tests the execution of the broker connection data mapping parser.
+ *
+ * <br>precondition: A broker connection datamapping is built by the parser;
+ * <br>postcondition: the corresponding connection data is available on the configuration.
+ */
+ public void testBrokerConnectionDataParser() throws UnknownBrokerException
+ {
+ String host = "127.0.0.1";
+ String port = "7001";
+ String virtualHost = "test";
+ String username = "username_guest";
+ String password ="password_guest";
+
+ BrokerConnectionDataParser parser = new BrokerConnectionDataParser()
+ {
+ @Override
+ UUID getUUId ()
+ {
+ return TestConstants.BROKER_ID;
+ }
+ };
+
+ parser.setCurrrentAttributeValue(host);
+ parser.setCurrentAttributeName(Tag.HOST.toString());
+ parser.setCurrrentAttributeValue(port);
+ parser.setCurrentAttributeName(Tag.PORT.toString());
+ parser.setCurrrentAttributeValue(virtualHost);
+ parser.setCurrentAttributeName(Tag.VIRTUAL_HOST.toString());
+ parser.setCurrrentAttributeValue(username);
+ parser.setCurrentAttributeName(Tag.USER.toString());
+ parser.setCurrrentAttributeValue(password);
+ parser.setCurrentAttributeName(Tag.PASSWORD.toString());
+ parser.setCurrentAttributeName(Tag.BROKER.toString());
+
+ BrokerConnectionData result = Configuration.getInstance().getBrokerConnectionData(TestConstants.BROKER_ID);
+
+ assertEquals(host,result.getHost());
+ assertEquals(Integer.parseInt(port),result.getPort());
+ assertEquals(virtualHost,result.getVirtualHost());
+ assertEquals(username,result.getUsername());
+ assertEquals(password,result.getPassword());
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandlerTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandlerTest.java
new file mode 100644
index 0000000000..d6b51b64fc
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandlerTest.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.management.domain.handler.base;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Test case for Content indication message handler (base class).
+ *
+ * @author Andrea Gazzarini
+ */
+public class ContentIndicationMessageHandlerTest extends TestCase
+{
+ /**
+ * Tests the behaviour of the objectHasBeenRemoved method().
+ */
+ public void testObjectHasBeenRemoved()
+ {
+ ContentIndicationMessageHandler mockHandler = new ContentIndicationMessageHandler()
+ {
+ @Override
+ protected void updateDomainModel (String packageName, String className, Binary classHash, Binary objectId,
+ long timeStampOfCurrentSample, long timeObjectWasCreated, long timeObjectWasDeleted, byte[] contentData)
+ {
+ }
+ };
+
+ long deletionTimestamp = 0;
+ long now = System.currentTimeMillis();
+
+ assertFalse(mockHandler.objectHasBeenRemoved(deletionTimestamp, now));
+
+ deletionTimestamp = now + 1000;
+ assertFalse(mockHandler.objectHasBeenRemoved(deletionTimestamp, now));
+
+ deletionTimestamp = now - 1000;
+ assertTrue(mockHandler.objectHasBeenRemoved(deletionTimestamp, now));
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseDomainModelTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseDomainModelTestCase.java
new file mode 100644
index 0000000000..c528392a93
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseDomainModelTestCase.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.management.domain.model;
+
+import org.apache.qpid.management.configuration.Configurator;
+
+import junit.framework.TestCase;
+
+/**
+ * Layer supertype for all domain model related test cases.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class BaseDomainModelTestCase extends TestCase
+{
+ /**
+ * Set up fixture for this test case.
+ * In order to execute tests on domain model we need to build the configuration.
+ */
+ @Override
+ protected void setUp () throws Exception
+ {
+ Configurator configurator = new Configurator();
+ configurator.configure();
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseQpidFeatureBuilderTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseQpidFeatureBuilderTestCase.java
new file mode 100644
index 0000000000..3d3783eb04
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseQpidFeatureBuilderTestCase.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.management.domain.model;
+
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.desc;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.name;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.configuration.Configurator;
+import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute;
+
+/**
+ * Layer supertype for feature builder test cases.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class BaseQpidFeatureBuilderTestCase extends TestCase
+{
+ protected final static String NAME = "aName";
+
+ protected final static String DESCRIPTION = "A description.";
+
+ protected Map <String,Object> _featureDefinition;
+ protected QpidFeatureBuilder _builder;
+
+ /**
+ * Set up fixture for all concrete builder test cases.
+ */
+ @Override
+ protected void setUp () throws Exception
+ {
+ Configurator configurator = new Configurator();
+ configurator.configure();
+ _featureDefinition = new HashMap<String, Object>();
+ _featureDefinition.put(name.name(),NAME);
+ _featureDefinition.put(desc.name(), DESCRIPTION);
+ }
+
+ // Internal test used to avoid code duplication.
+ protected void internalTestForMissingMandatoryAttribute(Attribute ...toBeRemoved)
+ {
+ try
+ {
+ for (Attribute attribute : toBeRemoved)
+ {
+ _featureDefinition.remove(attribute.name());
+ }
+ _builder.build();
+ fail("If a mandatory attribute is missing an exception must be thrown!");
+ } catch (UnableToBuildFeatureException expected)
+ {
+ assertTrue(expected instanceof MissingFeatureAttributesException);
+ for (Attribute attribute : toBeRemoved)
+ {
+ assertTrue(expected.getMessage().contains(attribute.name()));
+ }
+ }
+ }
+
+ // Internal test used to avoid code duplication.
+ protected void internalTestForMissingOptionalAttribute(Attribute ...toBeRemoved) throws UnableToBuildFeatureException
+ {
+ for (Attribute attribute : toBeRemoved)
+ {
+ _featureDefinition.remove(attribute.name());
+ }
+ _builder.build();
+
+ assertNotNull(_builder.getQpidFeature());
+ assertNotNull(_builder.getManagementFeature());
+ }
+
+
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/DomainModelTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/DomainModelTest.java
new file mode 100644
index 0000000000..578fa36bc7
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/DomainModelTest.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.management.domain.model;
+
+import java.util.UUID;
+
+import org.apache.qpid.management.TestConstants;
+
+/**
+ * Test case for domain model entity.
+ *
+ * @author Andrea Gazzarini
+ */
+public class DomainModelTest extends BaseDomainModelTestCase
+{
+ private DomainModel _model;
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ _model = new DomainModel(UUID.randomUUID());
+ }
+
+ /**
+ * Tests the execution of the getPackage() method.
+ */
+ public void testGetPackage()
+ {
+ assertFalse(_model.containsPackage(TestConstants.QPID_PACKAGE_NAME));
+
+ QpidPackage qpidPackage = _model.getPackageByName(TestConstants.QPID_PACKAGE_NAME);
+ assertEquals(TestConstants.QPID_PACKAGE_NAME,qpidPackage.getName());
+
+ QpidPackage theSameAsPreviousOne = _model.getPackageByName(TestConstants.QPID_PACKAGE_NAME);
+ assertSame(qpidPackage, theSameAsPreviousOne);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/OptionalPropertiesTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/OptionalPropertiesTest.java
new file mode 100644
index 0000000000..553c1c21de
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/OptionalPropertiesTest.java
@@ -0,0 +1,187 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model;
+
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.domain.model.type.Uint64;
+import org.apache.qpid.transport.codec.BBDecoder;
+
+public class OptionalPropertiesTest extends TestCase
+{
+ public void testDecoderStateChange()
+ {
+ QpidProperty property = new QpidProperty();
+ assertSame(
+ "Default decoder for properties is the one for mandatory properties.",
+ property._mandatoryPropertyDecoder,
+ property._decoder);
+
+ property.markAsOptional(1);
+ assertSame(
+ "After a property has been marked as optional the corresponding decoder must be installed.",
+ property._optionalPropertyDecoder,
+ property._decoder);
+ }
+
+ /**
+ * Tests the execution of the decode() method when the current property is optional but in the presence bitmask
+ * there's no the corresponding bit set.
+ *
+ * <br>precondition : property is optional and corresponding presence bit is not set.
+ * <br>postcondition : result must be null.
+ */
+ public void testDecodeValueWithOptionalPropertyAndMissingValue()
+ {
+ byte [] presenceBytes = {2};
+
+ QpidProperty property = new QpidProperty();
+
+ // We don't need a decoder so in order to be sure that it won't be invoked set it to null.
+ BBDecoder nullDecoder = null;
+
+ for (int i = 0; i < 8; i++)
+ {
+ // Property number 1 is declaring a value so skip it!
+ if (i != 1)
+ {
+ property.markAsOptional(i);
+ assertNull(property.decodeValue(nullDecoder, presenceBytes));
+ }
+ }
+ }
+
+ /**
+ * Tests the execution of the decode() method when the current property is optional but in the presence bitmask
+ * there's no the corresponding bit set.
+ *
+ * <br>precondition : property is optional and corresponding presence bit is not set.
+ * <br>postcondition : result must be null.
+ */
+ public void testDecodeValueWithOptionalPropertyAndDeclaredValue()
+ {
+ byte [] presenceBytes = {4};
+ Long _44 = new Long(44);
+
+ QpidProperty property = new QpidProperty();
+ property.setType(new Uint64());
+ property.markAsOptional(2);
+
+ ByteBuffer buffer = ByteBuffer.allocate(8);
+ buffer.putLong(_44);
+ buffer.rewind();
+ BBDecoder decoder = new BBDecoder();
+
+ decoder.init(buffer);
+ assertEquals(_44,property.decodeValue(decoder, presenceBytes));
+ }
+
+ /**
+ * Tests the execution of the decode() method with a real scenario where there are mandatory and optional
+ * properties.
+ */
+ public void testDecodeValueWithOptionalAndMandatoryProperties()
+ {
+ // With this bitset :
+ //
+ // 1th opt property is null;
+ // 2th opt property is null;
+ // 3th opt property is not null;
+ // 4th opt property is null;
+ // 5th opt propertyis null;
+ // 6th opt property is null;
+ // 7th opt property is null;
+ // 8th opt property is not null;
+ byte [] presenceBytes = {4,1};
+
+ List<QpidProperty> properties = new LinkedList<QpidProperty>();
+
+ properties.add(createProperty(false, -1));
+ properties.add(createProperty(false, -1));
+ properties.add(createProperty(true, 0));
+ properties.add(createProperty(false, -1));
+ properties.add(createProperty(false, -1));
+ properties.add(createProperty(true, 1));
+ properties.add(createProperty(false, -1));
+ properties.add(createProperty(false, -1));
+ properties.add(createProperty(true, 2));
+ properties.add(createProperty(true, 3));
+ properties.add(createProperty(true, 4));
+ properties.add(createProperty(true, 5));
+ properties.add(createProperty(true, 6));
+ properties.add(createProperty(true, 7));
+ properties.add(createProperty(false, -1));
+ properties.add(createProperty(true, 8));
+
+ Long expectedResults [] = {
+ 1L, // p1
+ 22L, // p2
+ null, // p3
+ 232L, // p4
+ 211L, // p5
+ null, // p6
+ 232L, // p7
+ 211L, // p8
+ 999L, // p9
+ null, // p10
+ null, // p11
+ null, // p12
+ null, // p13
+ null, // p14
+ 626L, // p15
+ 969L // p16
+ };
+
+
+ ByteBuffer buffer = ByteBuffer.allocate(expectedResults.length * 8);
+ for (Long expected : expectedResults)
+ {
+ if (expected != null)
+ {
+ buffer.putLong(expected);
+ }
+ }
+ buffer.rewind();
+ BBDecoder decoder = new BBDecoder();
+
+ decoder.init(buffer);
+ int index = 0;
+ for (QpidProperty property : properties)
+ {
+ assertEquals(expectedResults[index++],property.decodeValue(decoder, presenceBytes));
+ }
+ }
+
+ private QpidProperty createProperty(boolean isOptional, int optionalIndex)
+ {
+ QpidProperty property = new QpidProperty();
+ property.setType(new Uint64());
+ if (isOptional)
+ {
+ property.markAsOptional(optionalIndex);
+ }
+ return property;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java
new file mode 100644
index 0000000000..9d6e176912
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java
@@ -0,0 +1,408 @@
+/*
+*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.TestConstants;
+import org.apache.qpid.management.configuration.ConfigurationException;
+import org.apache.qpid.management.configuration.Configurator;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.domain.model.QpidClass.QManManagedObject;
+
+/**
+ * Test case for Qpid Class.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidClassTest extends TestCase
+{
+ private QpidClass _class;
+ private QpidPackage _package;
+
+ @Override
+ protected void setUp () throws ConfigurationException
+ {
+ Configurator configurator = new Configurator();
+ configurator.configure();
+ _package = new QpidPackage(TestConstants.QPID_PACKAGE_NAME,TestConstants.DOMAIN_MODEL);
+ _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package);
+ }
+
+ /**
+ * Tests the execution of the getObjectInstance() method.
+ * Basically it tests the addition of a new object instance.
+ *
+ * <br>precondition: class has no object instances.
+ * <br>precondition : class contains the added object instance.
+ */
+ public void testGetObjectInstance()
+ {
+ assertFalse (
+ "Nobody set instance #"+TestConstants.OBJECT_ID+" into this class so why is it there?",
+ _class._objectInstances.containsKey(TestConstants.OBJECT_ID));
+
+ QManManagedObject instance = _class.getObjectInstance(TestConstants.OBJECT_ID, false);
+
+ assertTrue (
+ "Now the instance #"+TestConstants.OBJECT_ID+" should be there...",
+ _class._objectInstances.containsKey(TestConstants.OBJECT_ID));
+
+ assertEquals(instance,_class.getObjectInstance(TestConstants.OBJECT_ID, false));
+ }
+
+ /**
+ * Tests the injection of instrumentation and configuration data (related to a specific object instance) before the
+ * schema is installed.
+ *
+ * <br>precondition : the schema hasn't yet installed on this class.
+ * <br>postcondition : incoming configuration & instrumentation data is stored into the corresponding object instance.
+ */
+ public void testAddInstrumentationAndConfigurationDataBeforeSchemaInstallation()
+ {
+ _class._state = _class._schemaRequestedButNotYetInjected;
+ QManManagedObject objectInstance = _class.getObjectInstance(TestConstants.OBJECT_ID,false);
+
+ assertTrue(
+ "This object instance is a new one so how is it possible that it has already instrumentation data? ",
+ objectInstance._rawInstrumentationData.isEmpty());
+ assertTrue(
+ "This object instance is a new one so how is it possible that it has already configuration data? ",
+ objectInstance._rawConfigurationData.isEmpty());
+
+ byte [] dummyConfigurationData = {1,2,3,4,5,6,7,8};
+ byte [] dummyInstrumentationData = {11,21,31,41,51,61,71,81};
+
+ _class.addConfigurationData(TestConstants.OBJECT_ID, dummyConfigurationData);
+ _class.addInstrumentationData(TestConstants.OBJECT_ID, dummyInstrumentationData);
+
+ assertEquals("Now configuration data should be there...",1,objectInstance._rawConfigurationData.size());
+ assertEquals("Now instrumentation data should be there...",1,objectInstance._rawInstrumentationData.size());
+
+ assertTrue(
+ "Object instance configuration data should be the previously set...",
+ Arrays.equals(objectInstance._rawConfigurationData.get(0),
+ dummyConfigurationData));
+
+ assertTrue(
+ "Object instance instrumentation data should be the previously set...",
+ Arrays.equals(objectInstance._rawInstrumentationData.get(0),
+ dummyInstrumentationData));
+ }
+
+ /**
+ * Tests the internal state change of a class definition.
+ */
+ public void testStateChange() throws UnableToBuildFeatureException
+ {
+ _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ _state = _schemaRequestedButNotYetInjected;
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException {
+ _state = _schemaInjected;
+ }
+ };
+
+ assertSame(
+ "Initial state doesn't match.",
+ _class._schemaNotRequested,
+ _class._state);
+
+ _class.addConfigurationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
+ _class.addInstrumentationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
+
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _class._schemaRequestedButNotYetInjected,
+ _class._state);
+
+ _class.setSchema(
+ TestConstants.EMPTY_PROPERTIES_SCHEMA,
+ TestConstants.EMPTY_STATISTICS_SCHEMA,
+ new LinkedList<MethodOrEventDataTransferObject>());
+
+ assertSame(
+ "Request schema has been injected. The current state is not indicating that!",
+ _class._schemaInjected,
+ _class._state);
+ }
+
+ /**
+ * Tests the injection of a valid schema on a QpidClass.
+ *
+ * <br>precondition : a valid arguments is injected on the qpid class.
+ * <br>postcondition : class definition is built successfully.
+ */
+ public void testSchemaInjectionOk() throws UnableToBuildFeatureException
+ {
+ _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package)
+ {
+ @Override
+ void requestSchema() throws Exception
+ {
+ // DO NOTHING : QMan is not running and therefore the schema will be manually injected.
+ }
+
+ @Override
+ void updateInstanceWithConfigurationData(QManManagedObject instance, byte[] rawData)
+ {
+ // DO NOTHING Given raw data is not valid so it cannot be converted.
+ }
+ };
+
+ // Incoming configuration data : that will fire the schema request and a state change
+ // from schema-not-requested to schema-requested-but-not-injected
+ _class.addConfigurationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
+
+ // I must be sure that what is obvious for me it's obvious for QMan... :)
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _class._schemaRequestedButNotYetInjected,
+ _class._state);
+
+ List<Map<String,Object>> propertyDefinitions = new ArrayList<Map<String,Object>>(2);
+ propertyDefinitions.add(
+ createProperty(
+ TestConstants.AGE_ATTRIBUTE_NAME,
+ 1,
+ TestConstants.YEARS,
+ TestConstants.SAMPLE_MIN_VALUE,
+ TestConstants.SAMPLE_MAX_VALUE,
+ null,
+ TestConstants.AGE_ATTRIBUTE_DESCRIPTION,
+ TestConstants._1,
+ false,
+ TestConstants._0));
+
+ propertyDefinitions.add(
+ createProperty(
+ TestConstants.SURNAME_ATTRIBUTE_NAME,
+ TestConstants.SAMPLE_ACCESS_CODE,
+ null,
+ null,
+ null,
+ TestConstants.SAMPLE_MAX_VALUE,
+ TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,
+ TestConstants._1,
+ true,
+ TestConstants._1));
+
+ _class.setSchema(propertyDefinitions, TestConstants.EMPTY_STATISTICS_SCHEMA, TestConstants.EMPTY_METHODS_SCHEMA);
+
+ assertEquals(2,_class._properties.size());
+
+ QpidProperty property = _class._properties.get(TestConstants.AGE_ATTRIBUTE_NAME);
+ assertEquals(TestConstants.AGE_ATTRIBUTE_NAME,property.getName());
+ assertEquals(AccessMode.RC,property.getAccessMode());
+ assertEquals(TestConstants.YEARS,property.getUnit());
+ assertEquals(TestConstants.SAMPLE_MIN_VALUE,property.getMinValue());
+ assertEquals(TestConstants.SAMPLE_MAX_VALUE,property.getMaxValue());
+ assertEquals(Integer.MIN_VALUE,property.getMaxLength());
+ assertEquals(TestConstants.AGE_ATTRIBUTE_DESCRIPTION,property.getDescription());
+ assertEquals(Short.class,property.getJavaType());
+ assertFalse(property.isOptional());
+
+ property = _class._properties.get(TestConstants.SURNAME_ATTRIBUTE_NAME);
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_NAME,property.getName());
+ assertEquals(AccessMode.RC,property.getAccessMode());
+ assertNull(property.getUnit());
+ assertEquals(Integer.MIN_VALUE,property.getMinValue());
+ assertEquals(Integer.MIN_VALUE,property.getMaxValue());
+ assertEquals(TestConstants.SAMPLE_MAX_VALUE,property.getMaxLength());
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,property.getDescription());
+ assertEquals(Short.class,property.getJavaType());
+ assertTrue(property.isOptional());
+
+ MBeanInfo mbeanInfo = _class._metadata;
+ assertEquals(TestConstants.EXCHANGE_CLASS_NAME,mbeanInfo.getClassName());
+
+ MBeanAttributeInfo [] attributes = mbeanInfo.getAttributes();
+ assertEquals(2,attributes.length);
+
+ MBeanAttributeInfo attribute = attributes[0];
+ assertEquals(TestConstants.AGE_ATTRIBUTE_NAME,attribute.getName());
+ assertEquals(TestConstants.AGE_ATTRIBUTE_DESCRIPTION,attribute.getDescription());
+ assertFalse(attribute.isWritable());
+ assertTrue(attribute.isReadable());
+ assertEquals(Short.class.getName(),attribute.getType());
+
+ attribute = attributes[1];
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_NAME,attribute.getName());
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,attribute.getDescription());
+ assertFalse(attribute.isWritable());
+ assertTrue(attribute.isReadable());
+ assertEquals(Short.class.getName(),attribute.getType());
+ }
+
+ /**
+ * Tests the behaviour of the class when a schema request can't be made.
+ *
+ * <br>precondition : class must be in "schema-not-requested" state when incoming data arrives.
+ * <br>postcondition : no exception is thrown and no state transition happens.
+ */
+ public void testStateChange_withRequestSchemaFailure()
+ {
+ _class= new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ throw new Exception();
+ }
+
+ @Override
+ void setSchema(
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
+ {
+ }
+ };
+
+ assertSame(
+ "Initial state must be schema-not-requested.",
+ _class._schemaNotRequested,
+ _class._state);
+
+ _class.addInstrumentationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
+
+ assertSame(
+ "Current state must be still schema-not-requested.",
+ _class._schemaNotRequested,
+ _class._state);
+ }
+
+ /**
+ * Tests the behaviour of the class when a schema injection fails.
+ *
+ * <br>precondition : class must be in "schema-not-requested" state when incoming data arrives.
+ * <br>postcondition : an exception is thrown and no state transition happens.
+ */
+ public void testStateChange_withSchemaInjectionFailure()
+ {
+ _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package)
+ {
+ @Override
+ void requestSchema() throws Exception
+ {
+ // DO NOTHING.
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions)
+ throws UnableToBuildFeatureException
+ {
+ throw new UnableToBuildFeatureException("");
+ }
+ };
+
+ assertSame(
+ "Initial state must be schema-not-requested.",
+ _class._schemaNotRequested,
+ _class._state);
+
+ _class.addInstrumentationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
+
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _class._schemaRequestedButNotYetInjected,
+ _class._state);
+
+ try {
+ _class.setSchema(
+ TestConstants.EMPTY_PROPERTIES_SCHEMA,
+ TestConstants.EMPTY_STATISTICS_SCHEMA,
+ TestConstants.EMPTY_METHODS_SCHEMA);
+ fail("If we are here something was wrong becuase the setSchema() of this event is throwing an exception...");
+ } catch (UnableToBuildFeatureException expected) {
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _class._schemaRequestedButNotYetInjected,
+ _class._state);
+ }
+ }
+
+ private Map<String,Object> createProperty(
+ String name,
+ Integer accessCode,
+ String unit,
+ Integer min,
+ Integer max,
+ Integer maxLength,
+ String description,
+ Integer type,
+ boolean optional,
+ Integer index)
+ {
+ Map <String,Object> result = new HashMap<String, Object>();
+ result.put(QpidFeatureBuilder.Attribute.name.name(),name);
+ result.put(QpidFeatureBuilder.Attribute.access.name(), accessCode);
+
+ if (unit != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.unit.name(),unit);
+ }
+
+ if (min != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.min.name(), min);
+ }
+
+ if (max != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.max.name(),max);
+ }
+
+ if (maxLength != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.maxlen.name(),maxLength);
+ }
+
+ result.put(QpidFeatureBuilder.Attribute.desc.name(), description);
+ result.put(QpidFeatureBuilder.Attribute.type.name(), type);
+ result.put(QpidFeatureBuilder.Attribute.optional.name(),optional ? 1 : 0);
+
+ if (index != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.index.name(), index);
+ }
+ return result;
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java
new file mode 100644
index 0000000000..4b36d9e5cc
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java
@@ -0,0 +1,293 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.TestConstants;
+import org.apache.qpid.management.configuration.ConfigurationException;
+import org.apache.qpid.management.configuration.Configurator;
+import org.apache.qpid.management.domain.model.QpidEvent.QManManagedEvent;
+
+/**
+ * Test case for qpid class entity.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidEventTest extends TestCase
+{
+ private QpidEvent _event;
+ private QpidPackage _qpidPackage;
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ _qpidPackage = new QpidPackage(TestConstants.QPID_PACKAGE_NAME,TestConstants.DOMAIN_MODEL);
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage);
+ }
+
+ /**
+ * Tests the execution of the createEventInstance() method.
+ * Basically it tests the addition of a new event instance.
+ *
+ * <br>precondition: event deifinition has no object instances.
+ * <br>precondition : event definition contains the new object instance.
+ */
+ public void testCreateEventInstance()
+ {
+ assertTrue(
+ "A just created event should be empty. I mean there shouldn't be event instances inside.",
+ _event.hasNoInstances());
+
+ QManManagedEvent instance = createEventInstance();
+
+ assertFalse (
+ "Now a new instance should be there...",
+ _event.hasNoInstances());
+
+ assertEquals(TestConstants.TEST_RAW_DATA,instance._rawEventData);
+ assertEquals(TestConstants.NOW,instance._timestamp);
+ assertEquals(TestConstants.SEVERITY, instance._severity);
+ }
+
+ /**
+ * Tests the internal state change of an event definition.
+ */
+ public void testStateChange() throws UnableToBuildFeatureException
+ {
+ // Let's override this class because this is not an online tests and therefore
+ // QMan is not supposed to be up.
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ // Do Nothing.
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> argumentDefinitions)throws UnableToBuildFeatureException {
+ _state = _schemaInjected;
+ }
+ };
+
+ assertSame(
+ "Initial state doesn't match.",
+ _event._schemaNotRequested,
+ _event._state);
+
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+
+ _event.setSchema(TestConstants.EMPTY_ARGUMENTS_SCHEMA);
+
+ assertSame(
+ "Request schema has been injected. The current state is not indicating that!",
+ _event._schemaInjected,
+ _event._state);
+ }
+
+ /**
+ * Tests the injection of a valid schema on a QpidEvent.
+ *
+ * <br>precondition : a valid arguments is injected on the qpid event.
+ * <br>postcondition : event definition is built successfully.
+ */
+ public void testSchemaInjectionOK() throws UnableToBuildFeatureException, ConfigurationException, InstanceNotFoundException, MBeanException, ReflectionException
+ {
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception
+ {
+ // DO NOTHING : QMan is not running and therefore the schema will be manually injected.
+ }
+
+ @Override
+ void updateEventInstanceWithData(QManManagedEvent instance)
+ {
+ // DO NOTHING : otherwise we should supply a valid raw data to be converted. ;-)
+ }
+ };
+
+ Configurator configurator = new Configurator();
+ configurator.configure();
+
+ List<Map<String,Object>> arguments = new ArrayList<Map<String, Object>>();
+ arguments.add(createArgument(TestConstants.AGE_ATTRIBUTE_NAME, TestConstants.AGE_ATTRIBUTE_DESCRIPTION));
+ arguments.add(createArgument(TestConstants.SURNAME_ATTRIBUTE_NAME, TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION));
+
+ // Incoming data : that will fire the schema request and a state change from schema-not-requested to schema-requested-but-not-injected
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ // I must be sure that what is obvious for me it's obvious for QMan... :)
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+
+ // Inject schema
+ _event.setSchema(arguments);
+
+ // Arguments must be 2 + 2 (severity)
+ assertEquals(2,_event._arguments.size());
+
+ QpidProperty argument = _event._arguments.get(TestConstants.AGE_ATTRIBUTE_NAME);
+ assertEquals(TestConstants.AGE_ATTRIBUTE_NAME,argument.getName());
+ assertEquals(AccessMode.RO,argument.getAccessMode());
+ assertEquals(TestConstants.AGE_ATTRIBUTE_DESCRIPTION,argument.getDescription());
+ assertEquals(Short.class,argument.getJavaType());
+ assertFalse(argument.isOptional());
+
+ argument = _event._arguments.get(TestConstants.SURNAME_ATTRIBUTE_NAME);
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_NAME,argument.getName());
+ assertEquals(AccessMode.RO,argument.getAccessMode());
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,argument.getDescription());
+ assertEquals(Short.class,argument.getJavaType());
+ assertFalse(argument.isOptional());
+
+ assertEquals(1,_event._eventInstances.size());
+
+ JmxService service = new JmxService();
+ Set<ObjectName> objectNames = service.getEventMBeans();
+
+ assertEquals(1,objectNames.size());
+ }
+
+ /**
+ * Tests the behaviour of the event class when a schema request can't be made.
+ *
+ * <br>precondition : event must be in "schema-not-requested" state when incoming data arrives.
+ * <br>postcondition : no exception is thrown and no state transition happens.
+ */
+ public void testStateChange_withRequestSchemaFailure()
+ {
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ throw new Exception();
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> argumentDefinitions)throws UnableToBuildFeatureException {
+ _state = _schemaInjected;
+ }
+ };
+
+ assertSame(
+ "Initial state must be schema-not-requested.",
+ _event._schemaNotRequested,
+ _event._state);
+
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ assertSame(
+ "Current state must be still schema-not-requested.",
+ _event._schemaNotRequested,
+ _event._state);
+ }
+
+ /**
+ * Tests the behaviour of the event class when a schema injection fails.
+ *
+ * <br>precondition : event must be in "schema-not-requested" state when incoming data arrives.
+ * <br>postcondition : an exception is thrown and no state transition happens.
+ */
+ public void testStateChange_withSchemaInjectionFailure()
+ {
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ // DO NOTHING.
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> argumentDefinitions)throws UnableToBuildFeatureException {
+ throw new UnableToBuildFeatureException("");
+ }
+ };
+
+ assertSame(
+ "Initial state must be schema-not-requested.",
+ _event._schemaNotRequested,
+ _event._state);
+
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+
+ try {
+ _event.setSchema(TestConstants.EMPTY_ARGUMENTS_SCHEMA);
+ fail("If we are here something was wrong becuase the setSchema() of this event is throwing an exception...");
+ } catch (UnableToBuildFeatureException expected) {
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+ }
+ }
+
+ /**
+ * Factory method for qpid managed event instances.
+ *
+ * @return a new QpidManagedEvent with test data inside.
+ */
+ private QManManagedEvent createEventInstance()
+ {
+ return _event.createEventInstance(
+ TestConstants.TEST_RAW_DATA,
+ TestConstants.NOW,
+ TestConstants.SEVERITY);
+ }
+
+ /**
+ * Factory method for event argument.
+ *
+ * @return a new argument metadata.
+ */
+ private Map<String,Object> createArgument(String name,String desc)
+ {
+ Map <String,Object> argument = new HashMap<String, Object>();
+ argument.put(QpidFeatureBuilder.Attribute.name.name(),name);
+ argument.put(QpidFeatureBuilder.Attribute.desc.name(), desc);
+ argument.put(QpidFeatureBuilder.Attribute.type.name(), TestConstants._1);
+ return argument;
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidMethodBuilderTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidMethodBuilderTest.java
new file mode 100644
index 0000000000..06dc35b0b1
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidMethodBuilderTest.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.management.domain.model;
+
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.dir;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.name;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.type;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.unit;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.management.MBeanOperationInfo;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute;
+
+/**
+ * Test case for Qpid Statistic builder.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidMethodBuilderTest extends BaseQpidFeatureBuilderTestCase
+{
+ private final static Integer ARG_COUNT = 3;
+ private MethodOrEventDataTransferObject _methodDefinition;
+
+ private List<Map<String,Object>> _argumentsDefinitons = new ArrayList<Map<String, Object>>();
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ super.setUp();
+ _featureDefinition.put(Names.ARG_COUNT_PARAM_NAME, ARG_COUNT);
+
+ Map<String,Object> arg1 = new HashMap<String,Object>();
+ arg1.put(name.name(), "arg1");
+ arg1.put(type.name(),1);
+ arg1.put(dir.name(),Direction.I.name());
+ arg1.put(unit.name(), "bytes");
+
+ Map<String,Object> arg2 = new HashMap<String,Object>();
+ arg2.put(name.name(), "arg2");
+ arg2.put(type.name(),1);
+ arg2.put(dir.name(),Direction.O.name());
+ arg2.put(unit.name(), "bytes");
+
+ Map<String,Object> arg3 = new HashMap<String,Object>();
+ arg3.put(name.name(), "arg3");
+ arg3.put(type.name(),1);
+ arg3.put(dir.name(),Direction.IO.name());
+ arg3.put(unit.name(), "bytes");
+
+ /*
+ dir yes no yes Direction code for method arguments
+ unit yes yes yes Units for numeric values (i.e. seconds, bytes, etc.)
+ min yes no yes Minimum value for numerics
+ max yes no yes Maximum value for numerics
+ maxlen yes no yes Maximum length for strings
+ desc yes yes yes Description of the argument
+ default yes no yes Default value for the argument
+ */
+ _argumentsDefinitons.add(arg1);
+ _argumentsDefinitons.add(arg2);
+
+ _methodDefinition = new MethodOrEventDataTransferObject(_featureDefinition,_argumentsDefinitons);
+ _builder = QpidFeatureBuilder.createMethodBuilder(_methodDefinition);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map doesn't contains type attribute.
+ *
+ * <br>precondition: definition map doesn't contains type attribute.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attribute.
+ */
+ public void testMethodBuilderKO_WithMissingName()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.name);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map doesn't contain type, name, index & optional attributes.
+ *
+ * <br>precondition: definition map doesn't contain type, name, index & optional attributes.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attributes.
+ */
+ public void testMethodBuilderOK_WithMissingUnit() throws UnableToBuildFeatureException
+ {
+ internalTestForMissingOptionalAttribute(Attribute.unit);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map doesn't unit attribute.
+ * Note that this attribute is optional and therefore the build must succeed.
+ *
+ * <br>precondition: definition map doesn't contain unit attribute.
+ * <br>postcondition : no exception is thrown and the statistic is built.
+ */
+ public void testMethodBuilderOK_WithMissingDescription() throws UnableToBuildFeatureException
+ {
+ internalTestForMissingOptionalAttribute(Attribute.desc);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map contains valid values.
+ *
+ * <br>precondition : the statistic definiton map contains valid values.
+ * <br>postcondition : no exception is thrown and the statistisc is built as expected.
+ */
+ public void testMethodBuilderOK() throws UnableToBuildFeatureException
+ {
+ _builder.build();
+
+ QpidMethod method = (QpidMethod) _builder.getQpidFeature();
+ MBeanOperationInfo info = (MBeanOperationInfo) _builder.getManagementFeature();
+
+ assertEquals(NAME,method.getName());
+
+ assertEquals(DESCRIPTION,method.getDescription());
+
+ assertEquals(method.getDescription(),info.getDescription());
+ assertEquals(method.getName(),info.getName());
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidNumberPropertyTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidNumberPropertyTest.java
new file mode 100644
index 0000000000..374011d150
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidNumberPropertyTest.java
@@ -0,0 +1,171 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.model;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.configuration.Configurator;
+import org.apache.qpid.management.domain.model.type.Uint8;
+
+public class QpidNumberPropertyTest extends TestCase
+{
+ private QpidProperty _property;
+ private Long _value = 55432L;
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ Configurator configurator = new Configurator();
+ configurator.configure();
+ _property = new QpidProperty();
+ _property.setName("average");
+ _property.setAccessMode(AccessMode.RW);
+ _property.setType(new Uint8());
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a number and no constraint has been set.
+ *
+ * <br>precondition : property type is a string, no constraint has been set.
+ * <br>postcondition : no exception is thrown and the validation succeeds.
+ */
+ public void testValidationWithoutConstraints() {
+ try
+ {
+ _property.validate(_value);
+ } catch (ValidationException notExpected)
+ {
+ fail("If no constraint has been set on this property why the validation is failing?");
+ }
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a number and a max value constraint has been set.
+ *
+ * <br>precondition : property type is a number, max value has been set and property value is greater than max value.
+ * <br>postcondition : an exception is thrown indicating the validation failure.
+ */
+ public void testValidationKO_withMaxValue() {
+ int maxValue = (int)(_value-1);
+ _property.setMaxValue(maxValue);
+
+ try
+ {
+ _property.validate(_value);
+ fail("The given value is violating the installed constraint so an exception must be thrown.");
+ } catch (ValidationException expected)
+ {
+ assertEquals(ValidationException.MAX_VALUE,expected.getConstraintName());
+ assertEquals(maxValue,expected.getConstraintValue());
+ assertEquals((double)_value,expected.getFeatureValue());
+ assertEquals(_property.getName(),expected.getFeatureName());
+ }
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a number and a min value constraint has been set.
+ *
+ * <br>precondition : property type is a number, min value has been set and property value is lesser than min value.
+ * <br>postcondition : an exception is thrown indicating the validation failure.
+ */
+ public void testValidationKO_withMinValue() {
+ int minValue = (int)(_value+1);
+ _property.setMinValue(minValue);
+
+ try
+ {
+ _property.validate(_value);
+ fail("The given value is violating the installed constraint so an exception must be thrown.");
+ } catch (ValidationException expected)
+ {
+ assertEquals(ValidationException.MIN_VALUE,expected.getConstraintName());
+ assertEquals(minValue,expected.getConstraintValue());
+ assertEquals((double)_value,expected.getFeatureValue());
+ assertEquals(_property.getName(),expected.getFeatureName());
+ }
+ }
+
+
+ /**
+ * Tests the validation of a qpid property when the number is a string and the property value is null.
+ *
+ * <br>precondition : property type is a number and property value is null..
+ * <br>postcondition : no exception is thrown. That is : the validation succeeds.
+ */
+ public void testValidationOK_withNullValue() {
+ try
+ {
+ _property.validate(null);
+ } catch (ValidationException notExpected)
+ {
+ fail("No constraint has been violated so validate() shouldn't raise an exception.");
+ }
+
+ _property.setMinValue(1);
+ _property.setMaxValue(10);
+
+ try
+ {
+ _property.validate(null);
+ } catch (ValidationException notExpected)
+ {
+ fail("No constraint has been violated so validate() shouldn't raise an exception.");
+ }
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a number and a max / min constraints have been set.
+ *
+ * <br>precondition : property type is a number, max / min constraint have been set and property value is wrong.
+ * <br>postcondition : an exception is thrown indicating the validation failure.
+ */
+ public void testValidationOK_withMinAndMaxConstraint() {
+ int minValue = (int)(_value+1);
+ int maxValue = (int)(_value-1);
+ _property.setMinValue(minValue);
+ _property.setMaxValue(maxValue);
+
+ try
+ {
+ _property.validate(_value);
+ fail("The given value is violating the installed constraint so an exception must be thrown.");
+ } catch (ValidationException expected)
+ {
+ assertEquals(ValidationException.MIN_VALUE,expected.getConstraintName());
+ assertEquals(minValue,expected.getConstraintValue());
+ assertEquals((double)_value,expected.getFeatureValue());
+ assertEquals(_property.getName(),expected.getFeatureName());
+ }
+
+ _property.setMinValue(0);
+ try
+ {
+ _property.validate(_value);
+ fail("The given value is violating the installed constraint so an exception must be thrown.");
+ } catch (ValidationException expected)
+ {
+ assertEquals(ValidationException.MAX_VALUE,expected.getConstraintName());
+ assertEquals(maxValue,expected.getConstraintValue());
+ assertEquals((double)_value,expected.getFeatureValue());
+ assertEquals(_property.getName(),expected.getFeatureName());
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPackageTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPackageTest.java
new file mode 100644
index 0000000000..b7eb9055ba
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPackageTest.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.management.domain.model;
+
+import org.apache.qpid.management.TestConstants;
+
+/**
+ * Test case for Qpid package entity.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidPackageTest extends BaseDomainModelTestCase
+{
+ private QpidPackage _qpidPackage;
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ _qpidPackage = new QpidPackage(TestConstants.QPID_PACKAGE_NAME, TestConstants.DOMAIN_MODEL);
+ }
+
+ /**
+ * Tests the association of a new class with a qpid package.
+ *
+ * <br>precondition : the package is not associated with any class.
+ * <br>postcondition : the package is now associated with the given class.
+ */
+ public void testAddClass() throws UnableToBuildFeatureException {
+ assertFalse(_qpidPackage.alreadyContainsClassDefinition(TestConstants.EXCHANGE_CLASS_NAME, TestConstants.HASH));
+
+ _qpidPackage.getQpidClass(TestConstants.EXCHANGE_CLASS_NAME, TestConstants.HASH, true);
+
+ assertTrue(_qpidPackage.alreadyContainsClassDefinition(TestConstants.EXCHANGE_CLASS_NAME, TestConstants.HASH));
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPropertyBuilderTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPropertyBuilderTest.java
new file mode 100644
index 0000000000..8ad177645c
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPropertyBuilderTest.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.management.domain.model;
+
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.access;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.index;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.max;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.min;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.optional;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.type;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.unit;
+
+import javax.management.MBeanAttributeInfo;
+
+import org.apache.qpid.management.configuration.UnknownTypeCodeException;
+import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute;
+
+/**
+ * Test case for Qpid Property builder.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidPropertyBuilderTest extends BaseQpidFeatureBuilderTestCase
+{
+ private final static Integer MIN = 0;
+ private final static Integer MAX = 120;
+ private final static String UNIT = "bytes";
+
+ private Integer _access;
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ super.setUp();
+
+ _access = 1;
+ _featureDefinition.put(access.name(), _access);
+ _featureDefinition.put(unit.name(),UNIT);
+ _featureDefinition.put(min.name(), MIN);
+ _featureDefinition.put(max.name(),MAX);
+
+ _featureDefinition.put(type.name(), 1);
+ _featureDefinition.put(optional.name(),0);
+ _featureDefinition.put(index.name(), 0);
+
+ _builder = QpidFeatureBuilder.createPropertyBuilder(_featureDefinition);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map contains an unknown type code.
+ *
+ * <br>precondition : the statistic definiton map contains an unknown type code.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testStatisticBuilderKO_WithUnknownType()
+ {
+ int unknownTypeCode =999;
+ try
+ {
+ _featureDefinition.put(type.name(), unknownTypeCode);
+ _builder.build();
+ fail("An unknown type code should raise an exception to indicate a failure.");
+ } catch (UnableToBuildFeatureException expected)
+ {
+ assertEquals(unknownTypeCode,((UnknownTypeCodeException)expected.getCause()).getCode());
+ }
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map contains a null value for a metadata attribute.
+ *
+ * <br>precondition : the statistic definiton map contains a null value for a metadata attribute.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testMethodBuilderKO_WithNullMetadataValue()
+ {
+ try
+ {
+ _featureDefinition.put(type.name(), null);
+ _builder.build();
+ fail("An null value for a metadata attribute should raise an exception to indicate a failure.");
+ } catch (UnableToBuildFeatureException expected)
+ {
+ assertTrue(expected.getCause() instanceof NullPointerException);
+ }
+ }
+
+ /**
+ * Tests the build process for a property when the definition map contains an invalid metadata type.
+ *
+ * <br>precondition : the property definiton map contains a wrong type for a metadata attribute.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testPropertyBuilderKO_WithClassCastException()
+ {
+ try
+ {
+ _featureDefinition.put(access.name(), new String("a"));
+ _builder.build();
+ fail("A wrong metadata attribute type should raise an exception to indicate a failure.");
+ } catch (UnableToBuildFeatureException expected)
+ {
+ assertTrue(expected.getCause() instanceof ClassCastException);
+ }
+ }
+
+ /**
+ * Tests the build process for a property when the definition map contains an unknown type code.
+ *
+ * <br>precondition : the property definiton map contains an unknown type code.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testPropertyBuilderKO_WithUnknownType()
+ {
+ int unknownTypeCode = 999;
+ try
+ {
+ _featureDefinition.put(type.name(), unknownTypeCode);
+ _builder.build();
+ fail("An unknown type code should raise an exception to indicate a failure.");
+ } catch (UnableToBuildFeatureException expected)
+ {
+ assertEquals(unknownTypeCode,((UnknownTypeCodeException)expected.getCause()).getCode());
+ }
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't contains type attribute.
+ *
+ * <br>precondition: definition map doesn't contains type attribute.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attribute.
+ */
+ public void testPropertyBuilderKO_WithMissingType()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.type);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't contain type & name attributes.
+ *
+ * <br>precondition: definition map doesn't contain type & name attributes.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attributes.
+ */
+ public void testPropertyBuilderKO_WithMissingTypeAndName()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't contain type & name & index attributes.
+ *
+ * <br>precondition: definition map doesn't contain type & name & index attributes.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attributes.
+ */
+ public void testPropertyBuilderKO_WithMissingTypeAndNameAndIndex()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name,Attribute.index);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't contain type, name, index & optional attributes.
+ *
+ * <br>precondition: definition map doesn't contain type, name, index & optional attributes.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attributes.
+ */
+ public void testPropertyBuilderKO_WithMissingTypeAndNameAndIndexAndOptional()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name,Attribute.index,Attribute.optional);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't contain type, name, index, optional and access
+ * attributes.
+ *
+ * <br>precondition: definition map doesn't contain type, name, index, optional and access attributes.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attributes.
+ */
+ public void testPropertyBuilderKO_WithMissingTypeAndNameAndIndexAndOptionalAndAccess()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name,Attribute.index,Attribute.optional,Attribute.access);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't unit attribute.
+ * Note that this attribute is optional and therefore the build must succeed.
+ *
+ * <br>precondition: definition map doesn't contain unit attribute.
+ * <br>postcondition : no exception is thrown and the property is built.
+ */
+ public void testBuilderOK_WithMissingUnit() throws UnableToBuildFeatureException
+ {
+ internalTestForMissingOptionalAttribute(Attribute.unit);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't min and max attributes.
+ * Note that those attributes are optional and therefore the build must succeed.
+ *
+ * <br>precondition: definition map doesn't contain min and max attributes.
+ * <br>postcondition : no exception is thrown and the property is built.
+ */
+ public void testBuilderOK_WithMissingMinAndMax() throws UnableToBuildFeatureException
+ {
+ internalTestForMissingOptionalAttribute(Attribute.min,Attribute.max);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't description attribute.
+ * Note that this attribute is optional and therefore the build must succeed.
+ *
+ * <br>precondition: definition map doesn't contain description attribute.
+ * <br>postcondition : no exception is thrown and the property is built.
+ */
+ public void testBuilderOK_WithMissingDescription() throws UnableToBuildFeatureException
+ {
+ internalTestForMissingOptionalAttribute(Attribute.desc);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map contains valid values.
+ *
+ * <br>precondition : the property definiton map contains valid values.
+ * <br>postcondition : no exception is thrown and the property is built as expected.
+ */
+ public void testPropertyBuilderOK() throws UnableToBuildFeatureException
+ {
+ _builder.build();
+
+ QpidProperty property = (QpidProperty) _builder.getQpidFeature();
+ MBeanAttributeInfo info = (MBeanAttributeInfo) _builder.getManagementFeature();
+
+ assertEquals(NAME,property.getName());
+ assertEquals(AccessMode.RC,property.getAccessMode());
+ assertEquals(UNIT,property.getUnit());
+ assertEquals(MIN.intValue(),property.getMinValue());
+ assertEquals(MAX.intValue(),property.getMaxValue());
+ assertEquals(Integer.MIN_VALUE,property.getMaxLength());
+ assertEquals(DESCRIPTION,property.getDescription());
+ assertEquals(Short.class,property.getJavaType());
+ assertFalse(property.isOptional());
+
+ assertEquals(property.getDescription(),info.getDescription());
+ assertEquals(property.getName(),info.getName());
+ assertEquals(property.getJavaType().getName(),info.getType());
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStatisticBuilderTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStatisticBuilderTest.java
new file mode 100644
index 0000000000..b7a8540b2d
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStatisticBuilderTest.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.management.domain.model;
+
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.type;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.unit;
+
+import javax.management.MBeanAttributeInfo;
+
+import org.apache.qpid.management.configuration.UnknownTypeCodeException;
+import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute;
+
+/**
+ * Test case for Qpid Statistic builder.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidStatisticBuilderTest extends BaseQpidFeatureBuilderTestCase
+{
+ private final static String UNIT = "bytes";
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ super.setUp();
+ _featureDefinition.put(unit.name(),UNIT);
+ _featureDefinition.put(type.name(), 1);
+
+ _builder = QpidFeatureBuilder.createStatisticBuilder(_featureDefinition);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map contains an unknown type code.
+ *
+ * <br>precondition : the statistic definiton map contains an unknown type code.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testStatisticBuilderKO_WithUnknownType()
+ {
+ int unknownTypeCode = 999;
+ try
+ {
+ _featureDefinition.put(type.name(), unknownTypeCode);
+ _builder.build();
+ fail("An unknown type code should raise an exception to indicate a failure.");
+ } catch (UnableToBuildFeatureException expected)
+ {
+ assertEquals(unknownTypeCode,((UnknownTypeCodeException)expected.getCause()).getCode());
+ }
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map contains a null value for a metadata attribute.
+ *
+ * <br>precondition : the statistic definiton map contains a null value for a metadata attribute.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testMethodBuilderKO_WithNullMetadataValue()
+ {
+ try
+ {
+ _featureDefinition.put(type.name(), null);
+ _builder.build();
+ fail("An null value for a metadata attribute should raise an exception to indicate a failure.");
+ } catch (UnableToBuildFeatureException expected)
+ {
+ assertTrue(expected.getCause() instanceof NullPointerException);
+ }
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map doesn't contains type attribute.
+ *
+ * <br>precondition: definition map doesn't contains type attribute.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attribute.
+ */
+ public void testStatisticBuilderKO_WithMissingType()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.type);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map doesn't contain type & name attributes.
+ *
+ * <br>precondition: definition map doesn't contain type & name attributes.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attributes.
+ */
+ public void testStatisticBuilderKO_WithMissingTypeAndName()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map doesn't contain type, name, index & optional attributes.
+ *
+ * <br>precondition: definition map doesn't contain type, name, index & optional attributes.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attributes.
+ */
+ public void testStatisticBuilderOK_WithMissingUnit() throws UnableToBuildFeatureException
+ {
+ internalTestForMissingOptionalAttribute(Attribute.unit);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map doesn't unit attribute.
+ * Note that this attribute is optional and therefore the build must succeed.
+ *
+ * <br>precondition: definition map doesn't contain unit attribute.
+ * <br>postcondition : no exception is thrown and the statistic is built.
+ */
+ public void testBuilderOK_WithMissingDescription() throws UnableToBuildFeatureException
+ {
+ internalTestForMissingOptionalAttribute(Attribute.desc);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map contains valid values.
+ *
+ * <br>precondition : the statistic definiton map contains valid values.
+ * <br>postcondition : no exception is thrown and the statistisc is built as expected.
+ */
+ public void testStatisticBuilderOK() throws UnableToBuildFeatureException
+ {
+ _builder.build();
+
+ QpidStatistic statistic= (QpidStatistic) _builder.getQpidFeature();
+ MBeanAttributeInfo info = (MBeanAttributeInfo) _builder.getManagementFeature();
+
+ assertEquals(NAME,statistic.getName());
+ assertEquals(UNIT,statistic.getUnit());
+ assertEquals(DESCRIPTION,statistic.getDescription());
+ assertEquals(Short.class,statistic.getJavaType());
+
+ assertEquals(statistic.getDescription(),info.getDescription());
+ assertEquals(statistic.getName(),info.getName());
+ assertEquals(statistic.getJavaType().getName(),info.getType());
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStringPropertyTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStringPropertyTest.java
new file mode 100644
index 0000000000..8aeb7c8550
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStringPropertyTest.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.management.domain.model;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.configuration.Configurator;
+import org.apache.qpid.management.domain.model.type.Str16;
+
+public class QpidStringPropertyTest extends TestCase
+{
+ private QpidProperty _property;
+ private final String _5LettersString = "12345";
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ Configurator configurator = new Configurator();
+ configurator.configure();
+ _property = new QpidProperty();
+ _property.setName("name");
+ _property.setAccessMode(AccessMode.RW);
+ _property.setType(new Str16());
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a string and a max length constraint hasn't been set.
+ *
+ * <br>precondition : property type is a string, max length hasn't been set.
+ * <br>postcondition : no exception is thrown. That is : the validation succeeds.
+ */
+ public void testValidationWithoutMaxLength() {
+ try
+ {
+ _property.validate(_5LettersString);
+ } catch (ValidationException notExpected)
+ {
+ fail("No max length has been set on property so validation must succeed.");
+ }
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a string and a max length constraint has been set.
+ *
+ * <br>precondition : property type is a string, max length has been set and property value is longer than max length.
+ * <br>postcondition : an exception is thrown indicating the validation failure.
+ */
+ public void testValidationKO_withMaxLength() {
+ int maxLength = 2;
+ _property.setMaxLength(maxLength);
+
+ try
+ {
+ _property.validate(_5LettersString);
+ fail("No max length has been set on property so validation must proceed.");
+ } catch (ValidationException expected)
+ {
+ assertEquals(ValidationException.MAX_LENGTH,expected.getConstraintName());
+ assertEquals(maxLength,expected.getConstraintValue());
+ assertEquals(_5LettersString.length(),expected.getFeatureValue());
+ assertEquals(_property.getName(),expected.getFeatureName());
+ }
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a string and the property value is null.
+ *
+ * <br>precondition : property type is a string and property value is null..
+ * <br>postcondition : no exception is thrown. That is : the validation succeeds.
+ */
+ public void testValidationOK_withNullValue() {
+ try
+ {
+ _property.validate(null);
+ } catch (ValidationException notExpected)
+ {
+ fail("No constraint has been violated so validate() shouldn't raise an exception.");
+ }
+
+ _property.setMaxLength(1);
+
+ try
+ {
+ _property.validate(null);
+ } catch (ValidationException notExpected)
+ {
+ fail("No constraint has been violated so validate() shouldn't raise an exception.");
+ }
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a string and a max length constraint has been set.
+ *
+ * <br>precondition : property type is a string, max length has been set and property value is not violating that.
+ * <br>postcondition : no exception is thrown. That is : the validation succeeds.
+ */
+ public void testValidationOK_withMaxLength() {
+ int maxLength = (_5LettersString.length()+1);
+ _property.setMaxLength(maxLength);
+
+ try
+ {
+ _property.validate(_5LettersString);
+ } catch (ValidationException notExpected)
+ {
+ fail("No constraint has been violated so validate() shouldn't raise an exception.");
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/type/BinaryTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/type/BinaryTest.java
new file mode 100644
index 0000000000..6636c08710
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/type/BinaryTest.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.management.domain.model.type;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for "Binary" type.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BinaryTest extends TestCase
+{
+ /**
+ * Tests the lazy & once hash code computation behaviour of the binary type.
+ */
+ public void testHashCodeComputation(){
+ Binary binary = new Binary(new byte[]{1,2,3,4,5,6,7,6,3,3});
+ assertSame(binary.state,binary.hashCodeNotYetComputed);
+
+ int firstResult = binary.hashCode();
+ assertSame(binary.state,binary.hashCodeAlreadyComputed);
+
+ int secondResult = binary.hashCode();
+ assertSame(binary.state,binary.hashCodeAlreadyComputed);
+ assertEquals(firstResult,secondResult);
+ }
+
+ /**
+ * Tests the equals() method of the binary class.
+ * Two binary must be equals only if they contain the same array (that is, two arrays with the same size & content)
+ */
+ public void testIdentity() {
+ Binary binary = new Binary(new byte[]{1,2,3,4,5,6,7,6,3,3});
+ Binary theSame= new Binary(new byte[]{1,2,3,4,5,6,7,6,3,3});
+ Binary aDifferentOne = new Binary(new byte[]{4,2,3,3,4,4,5,3,3,2});
+
+ assertTrue(binary.equals(theSame));
+ assertFalse(binary.equals(aDifferentOne));
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java
new file mode 100644
index 0000000000..805c039a6f
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java
@@ -0,0 +1,241 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.domain.services;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.api.Message;
+import org.apache.qpid.management.TestConstants;
+import org.apache.qpid.management.domain.handler.base.IMessageHandler;
+import org.apache.qpid.management.domain.model.DomainModel;
+import org.apache.qpid.nclient.util.ByteBufferMessage;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * Test case for Broker Message Listener.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BrokerMessageListenerTest extends TestCase
+{
+ // An empty message handler user for test.
+ private IMessageHandler _emptyMessageHandler = new IMessageHandler()
+ {
+ public void process (Decoder decoder, int sequenceNumber)
+ {
+ }
+ public void setDomainModel (DomainModel domainModel)
+ {
+ }
+ };
+
+ // Another empty message handler user for test.
+ private IMessageHandler _anotherEmptyMessageHandler = new IMessageHandler()
+ {
+ public void process (Decoder decoder, int sequenceNumber)
+ {
+ }
+ public void setDomainModel (DomainModel domainModel)
+ {
+ }
+ };
+
+ private Map<Character,IMessageHandler> _handlers = new HashMap<Character, IMessageHandler>();
+ private BrokerMessageListener _listener;
+ private final char opcode1 = 'x';
+ private final char opcode2 = 'y';
+
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ DomainModel domainModel = new DomainModel(TestConstants.BROKER_ID);
+ _listener = new BrokerMessageListener(domainModel);
+
+ _handlers.put(opcode1, _emptyMessageHandler);
+ _handlers.put(opcode2, _anotherEmptyMessageHandler);
+ }
+
+ /**
+ * Tests the installation of message handlers on a broker message listener.
+ *
+ * <br>precondition : no message handler has been installed on message listener.
+ * <br>postcondition : two message handlers are installed on message listener.
+ */
+ public void testSetHandlersOK()
+ {
+ assertTrue(
+ "No handler has yet been installed so how is it possible that the handlers map is not empty?",
+ _listener._handlers.isEmpty());
+
+ _listener.setHandlers(_handlers);
+
+ assertEquals("Now we should have two handlers configured.",2,_listener._handlers.size());
+ assertSame(_listener._handlers.get(opcode1),_emptyMessageHandler);
+ assertSame(_listener._handlers.get(opcode2),_anotherEmptyMessageHandler);
+ }
+
+ /**
+ * Tests the installation of message handlers on a broker message listener.
+ * Specifically it tries to install three message handlers and one of them is throwing an exception at installation time.
+ *
+ * <br>precondition : no message handler has been installed on message listener.
+ * <br>postcondition : two message handlers are installed on message listener. (the one that thrown exception has been
+ * discarded).
+ */
+ public void testSetHandlerOK()
+ {
+ IMessageHandler wrongMessageHandler = new IMessageHandler()
+ {
+
+ public void process (Decoder decoder, int sequenceNumber)
+ {
+ }
+
+ public void setDomainModel (DomainModel domainModel)
+ {
+ throw new RuntimeException();
+ }
+ };
+
+ char opcodeForWrongHandler = 'k';
+
+ assertTrue(
+ "No handler has yet been installed so how is it possible that the handlers map is not empty?",
+ _listener._handlers.isEmpty());
+
+ _handlers.put(opcodeForWrongHandler,wrongMessageHandler);
+
+ _listener.setHandlers(_handlers);
+
+ assertEquals("Now we should have two handlers configured.",2,_listener._handlers.size());
+ assertSame(_listener._handlers.get(opcode1),_emptyMessageHandler);
+ assertSame(_listener._handlers.get(opcode2),_anotherEmptyMessageHandler);
+ assertNull(_listener._handlers.get(opcodeForWrongHandler));
+ }
+
+ /**
+ * Tests the execution of the onMessage() method when a message with a bad magic number is received.
+ *
+ * <br>precondition : a message with a bad magic number is received.
+ * <br>postcondition : the processing of the incoming message is skipped and therefore no handler will be called.
+ */
+ public void testOnMessageKO_withBadMagicNumber() throws IOException
+ {
+ IMessageHandler neverCallMe = new IMessageHandler()
+ {
+
+ public void process (Decoder decoder, int sequenceNumber)
+ {
+ fail("This test shouldn't never arrive at this point...");
+ }
+
+ public void setDomainModel (DomainModel domainModel)
+ {
+ }
+ };
+
+ String opcodeForNeverCallMeHandler = "w";
+
+ _handlers.put('w',neverCallMe);
+ _listener.setHandlers(_handlers);
+
+ Message message = new ByteBufferMessage();
+ message.appendData( ("AMG"+opcodeForNeverCallMeHandler).getBytes());
+
+ _listener.onMessage(message);
+ }
+
+ /**
+ * Tests the execution of the onMessage() method when the incoming message is a compound message.
+ *
+ * <br>precondition : the incoming message is a compound message.
+ * <br>postcondition : each tokenized message is forwarded to the appropriate handler.
+ */
+ public void testOnMessageOK_WithCompoundMessage() throws Exception
+ {
+ final Map<Character,IMessageHandler> handlersMap = new HashMap<Character,IMessageHandler>();
+ char [] opcodes = {'a','b','c','d','e'};
+
+ class MockMessageHandler implements IMessageHandler
+ {
+ private final char _opcode;
+
+ public MockMessageHandler(char opcode)
+ {
+ this._opcode = opcode;
+ }
+
+ public void process (Decoder decoder, int sequenceNumber)
+ {
+ handlersMap.remove(_opcode);
+ }
+
+ public void setDomainModel (DomainModel domainModel)
+ {
+ // Do nothing here. It's just a mock handler.
+ }
+ };
+
+ for (char opcode : opcodes)
+ {
+ handlersMap.put(opcode, new MockMessageHandler(opcode));
+ }
+
+ // Removes previously injected handlers (i.e. x & y)
+ _listener._handlers.clear();
+ _listener.setHandlers(handlersMap);
+
+ Message compoundMessage = createCompoundMessage(opcodes);
+ _listener.onMessage(compoundMessage);
+
+ assertTrue(handlersMap.isEmpty());
+ }
+
+ // Creates a (non valid) compound message.
+ private Message createCompoundMessage(char[] opcodes) throws IOException {
+ byte [] compoundMessageData = new byte [12 * opcodes.length];
+ Random randomizer = new Random();
+ int position = 0;
+
+ for (char opcode : opcodes) {
+ System.arraycopy(MessageTokenizer.MAGIC_NUMBER_BYTES, 0, compoundMessageData, position, MessageTokenizer.MAGIC_NUMBER_BYTES.length);
+ position+=MessageTokenizer.MAGIC_NUMBER_BYTES.length;
+
+ compoundMessageData[position++] = (byte)opcode;
+
+ for (int c = 4; c < 12; c++)
+ {
+ byte aByte = (byte)randomizer.nextInt(127);
+ compoundMessageData[position++] = aByte;
+ }
+ }
+
+ Message compoundMessage = new ByteBufferMessage();
+ compoundMessage.appendData(compoundMessageData);
+ return compoundMessage;
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/MessageTokenizerTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/MessageTokenizerTest.java
new file mode 100644
index 0000000000..55b8b17f9d
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/MessageTokenizerTest.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.management.domain.services;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.*;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.api.Message;
+import org.apache.qpid.nclient.util.ByteBufferMessage;
+import org.apache.qpid.transport.codec.BBDecoder;
+
+/**
+ * Tests case for messaeg tokenizer.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MessageTokenizerTest extends TestCase {
+
+ /**
+ * Tests the execution of the message tokenizer when the given message is not a valid AMQP message.
+ *
+ * <br>precondition : the incoming message is not a valid AMQP message.
+ * <br>postcondition : no exception is thrown and there will be exactly one token with the given message.
+ */
+ public void testOK_WithNoMessage() throws IOException{
+ byte [] noMessage = {2,10,120,23,23,23,4,10,11,12,2,1,3,-22};
+
+ Message multiMessage = new ByteBufferMessage();
+ multiMessage.appendData(noMessage);
+ MessageTokenizer tokenizer = new MessageTokenizer(multiMessage);
+
+ assertEquals(1, tokenizer.countTokens());
+ assertEquals(tokenizer.nextElement(),noMessage);
+ assertFalse(tokenizer.hasMoreElements());
+ }
+
+ /**
+ * Tests the execution of the message tokenizer when the given message contains only one message.
+ *
+ * <br>precondition : the incoming message contains only one message.
+ * <br>postcondition : no exception is thrown and there will be exactly one token with the given message.
+ */
+ public void testOK_WithOneMessage() throws IOException{
+ byte [] oneEncodedMessage = {'A','M','2',23,23,23,4,10,11,12,2,1,3,-22};
+
+ Message multiMessage = new ByteBufferMessage();
+ multiMessage.appendData(oneEncodedMessage);
+ MessageTokenizer tokenizer = new MessageTokenizer(multiMessage);
+
+ assertEquals(1, tokenizer.countTokens());
+ assertEquals(tokenizer.nextElement(),oneEncodedMessage);
+ assertFalse(tokenizer.hasMoreElements());
+ }
+
+ /**
+ * Tests the execution of the message tokenizer when the given message contains a random number of messages.
+ *
+ * <br>precondition : the incoming message contains a random number of messages.
+ * <br>postcondition : no exception is thrown and each built token is a valid message starting with right header.
+ */
+ public void testOK_WithRandomNUmberOfMessages() throws IOException{
+ Random randomizer = new Random();
+
+ int howManyLoops = randomizer.nextInt(10000);
+ howManyLoops = (howManyLoops == 0) ? 10 : howManyLoops;
+ byte [] compoundMessageData = new byte [12 * howManyLoops];
+
+ List<byte []> messages = new ArrayList<byte[]>(howManyLoops);
+
+ int position = 0;
+ for (int i = 0; i < howManyLoops; i++)
+ {
+ byte [] message = new byte[12];
+ System.arraycopy(MessageTokenizer.MAGIC_NUMBER_BYTES, 0, compoundMessageData, position, MessageTokenizer.MAGIC_NUMBER_BYTES.length);
+ System.arraycopy(MessageTokenizer.MAGIC_NUMBER_BYTES, 0, message, 0, MessageTokenizer.MAGIC_NUMBER_BYTES.length);
+ position+=MessageTokenizer.MAGIC_NUMBER_BYTES.length;
+
+ for (int c = 3; c < 12; c++)
+ {
+ byte aByte = (byte)randomizer.nextInt(127);
+ aByte = (aByte == 77) ? (byte)c : aByte;
+ compoundMessageData[position++] = aByte;
+ message[c] = aByte;
+ }
+ messages.add(message);
+ }
+
+ Message multiMessage = new ByteBufferMessage();
+ multiMessage.appendData(compoundMessageData);
+ MessageTokenizer tokenizer = new MessageTokenizer(multiMessage);
+
+ int howManyTokens = tokenizer.countTokens();
+ assertEquals(howManyLoops, howManyTokens);
+
+ int index = 0;
+ while (tokenizer.hasMoreElements())
+ {
+ assertEquals(tokenizer.nextElement(),messages.get(index++));
+ }
+
+ assertEquals((index),howManyTokens);
+ }
+
+ /**
+ * Internal method used for comparison of two messages.
+ *
+ * @param message the token message just built by the tokenizer.
+ * @param expected the expected result.
+ */
+ private void assertEquals(Message message, byte [] expected) throws IOException
+ {
+ ByteBuffer messageContent = message.readData();
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(messageContent);
+ byte [] content = decoder.readReaminingBytes();
+ assertTrue(Arrays.equals(content, expected));
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/BaseWsDmAdapterTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/BaseWsDmAdapterTestCase.java
new file mode 100644
index 0000000000..900d14c72e
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/BaseWsDmAdapterTestCase.java
@@ -0,0 +1,143 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm;
+
+import java.lang.management.ManagementFactory;
+import java.net.URI;
+import java.util.UUID;
+
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import junit.framework.TestCase;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.TestConstants;
+
+/**
+ * Test case for WS-Resource lifecycle management.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class BaseWsDmAdapterTestCase extends TestCase implements TestConstants{
+
+ protected MBeanServer _managementServer;
+ protected ObjectName _resourceObjectName;
+
+ protected WsResourceClient _resourceClient;
+ protected MBeanInfo _mbeanInfo;
+
+ /**
+ * Set up fixture for this test case.
+ *
+ * @throws Exception when the test case intialization fails.
+ */
+ protected void setUp() throws Exception
+ {
+ _managementServer = ManagementFactory.getPlatformMBeanServer();
+
+ ServiceGroupClient serviceGroup = getServiceGroupClient();
+ WsResourceClient [] members = serviceGroup.getMembers();
+
+ assertEquals(
+ "No resource has been yet created so how is " +
+ "it possible that service group children list is not empty?",
+ 0,
+ members.length);
+
+ _managementServer.invoke(
+ Names.QPID_EMULATOR_OBJECT_NAME,
+ "createQueue",
+ new Object[]{_resourceObjectName = createResourceName()},
+ new String[]{ObjectName.class.getName()});
+
+ members = serviceGroup.getMembers();
+ assertEquals(
+ "One resource has just been created so " +
+ "I expect to find it on service group children list...",
+ 1,
+ members.length);
+
+ _resourceClient = members[0];
+ _mbeanInfo = _managementServer.getMBeanInfo(_resourceObjectName);
+ }
+
+ /**
+ * Shutdown procedure for this test case.
+ *
+ * @throws Exception when either the server or some resource fails to shutdown.
+ */
+ @Override
+ protected void tearDown() throws Exception
+ {
+ ServiceGroupClient serviceGroup = getServiceGroupClient();
+ WsResourceClient [] members = serviceGroup.getMembers();
+
+ _managementServer.invoke(
+ Names.QPID_EMULATOR_OBJECT_NAME,
+ "unregister",
+ new Object[]{_resourceObjectName},
+ new String[]{ObjectName.class.getName()});
+
+ members = serviceGroup.getMembers();
+
+ assertEquals(
+ "No resource has been yet created so how is it possible that service group children list is not empty?",
+ 0,
+ members.length);
+ }
+
+ /**
+ * Creates a service group client reference.
+ *
+ * @return a service group client reference.
+ */
+ private ServiceGroupClient getServiceGroupClient()
+ {
+ URI address = URI.create(
+ Protocol.DEFAULT_ENDPOINT_URI.replaceFirst("8080",System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME)));
+ return new ServiceGroupClient(new EndpointReference(address));
+ }
+
+ /**
+ * In order to test the behaviour of the WS-DM adapter, at
+ * least one resource must be created. This is the method that
+ * returns the name (ObjectName on JMX side, Resource-ID on WSDM side)
+ * of that resource
+ *
+ * @return the name of the MBean instance that will be created.
+ * @throws Exception when the name if malformed. Practically never.
+ */
+ private ObjectName createResourceName() throws Exception
+ {
+ return new ObjectName(
+ "Q-MAN:objectId="+UUID.randomUUID()+
+ ", brokerID="+UUID.randomUUID()+
+ ",class=queue"+
+ ",package=org.apache.qpid"+
+ ",name="+System.currentTimeMillis());
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/EnhancedReflectionProxyHandler.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/EnhancedReflectionProxyHandler.java
new file mode 100644
index 0000000000..615d744546
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/EnhancedReflectionProxyHandler.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.management.wsdm;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.wsdm.muse.serializer.ByteArraySerializer;
+import org.w3c.dom.Element;
+
+/**
+ * Custom implementation of Muse ReflectionProxyHandler
+ * that uses a base64 serializer for byte arrays.
+ * Note that this proxy handler is only needed for tests because it provides
+ * client side Base64 serializer capability.
+ * In a concrete scenario we don't mind what instrument the client is using in order to
+ * propertly serialize byte arrays.
+ *
+ * @author Andrea Gazzarini
+ */
+public class EnhancedReflectionProxyHandler extends ReflectionProxyHandler
+{
+ @Override
+ protected Element serialize(Object obj, QName qname) throws SoapFault
+ {
+ if (obj == null)
+ {
+ return XmlUtils.createElement(qname);
+ }
+
+ if (obj.getClass() == byte[].class)
+ {
+ return new ByteArraySerializer().toXML(obj, qname);
+ } else
+ {
+ return super.serialize(obj, qname);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected Object deserialize(Element xml, Class theClass) throws SoapFault
+ {
+ if (theClass == byte[].class)
+ {
+ return new ByteArraySerializer().fromXML(xml);
+ } else
+ {
+ return super.deserialize(xml, theClass);
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetMultipleResourcePropertiesTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetMultipleResourcePropertiesTestCase.java
new file mode 100644
index 0000000000..d59e7a39e5
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetMultipleResourcePropertiesTestCase.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.management.wsdm;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.management.MBeanAttributeInfo;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+
+/**
+ * Test case for Web Service Resource Properties interfaces.
+ * Those interfaces are defined on http://docs.oasis-open.org/wsrf/wsrf-ws_resource_properties-1.2-spec-os.pdf
+ * (Web Services Resource Properties 1.2 - (WS-ResourceProperties).
+ * For a better explanation see chapter 5 of the specification above.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetMultipleResourcePropertiesTestCase extends BaseWsDmAdapterTestCase
+{
+ /**
+ * Tests the GetMultipleResourceProperties interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the GetMultipleResourceProperties request contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testGetMultipleResourcePropertiesKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.getMultipleResourceProperties(new QName[]{});
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+
+ /**
+ * Test the WS-RP GetResourceProperties interface of the WS-DM adapter.
+ *
+ * <br>precondition : a ws resource exists and is registered.
+ * <br>postcondition : Properties are correctly returned according to WSRP interface and they (their value)
+ * are matching with corresponding MBean properties.
+ */
+ public void testGetMultipleResourcePropertiesOK() throws Exception
+ {
+ MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
+ QName[] names = new QName[attributesMetadata.length];
+
+ int index = 0;
+ for (MBeanAttributeInfo attributeMetadata : _mbeanInfo.getAttributes())
+ {
+ QName qname = new QName(Names.NAMESPACE_URI,attributeMetadata.getName(),Names.PREFIX);
+ names[index++] = qname;
+ }
+
+ Element[] properties =_resourceClient.getMultipleResourceProperties(names);
+ for (Element element : properties)
+ {
+ String name = element.getLocalName();
+ Object value = _managementServer.getAttribute(_resourceObjectName, name);
+ if ("Name".equals(name))
+ {
+ assertEquals(
+ value,
+ element.getTextContent());
+ } else if ("Durable".equals(name))
+ {
+ assertEquals(
+ value,
+ Boolean.valueOf(element.getTextContent()));
+ } else if ("ExpireTime".equals(name))
+ {
+ assertEquals(
+ value,
+ new Date(Long.valueOf(element.getTextContent())));
+ } else if ("MsgTotalEnqueues".equals(name))
+ {
+ assertEquals(
+ value,
+ Long.valueOf(element.getTextContent()));
+ } else if ("ConsumerCount".equals(name))
+ {
+ assertEquals(
+ value,
+ Integer.valueOf(element.getTextContent()));
+ }else if ("VhostRef".equals(name))
+ {
+ assertEquals(
+ value,
+ UUID.fromString(element.getTextContent()));
+ }
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertiesTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertiesTestCase.java
new file mode 100644
index 0000000000..e18e928cf4
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertiesTestCase.java
@@ -0,0 +1,105 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm;
+
+import java.lang.reflect.Array;
+
+import javax.management.MBeanAttributeInfo;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.qpid.management.Names;
+
+/**
+ * Test case for Web Service Resource Properties interfaces.
+ * Those interfaces are defined on http://docs.oasis-open.org/wsrf/wsrf-ws_resource_properties-1.2-spec-os.pdf
+ * (Web Services Resource Properties 1.2 - (WS-ResourceProperties).
+ * For a better explanation see chapter 5 of the specification above.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetResourcePropertiesTestCase extends BaseWsDmAdapterTestCase
+{
+
+ /**
+ * Test the WS-RP GetResourceProperty interface of the WS-DM adapter.
+ *
+ * <br>precondition : a ws resource exists and is registered.
+ * <br>postcondition : property values coming from WS-DM resource are the same of the JMX interface.
+ */
+ public void testGetResourcePropertiesOK() throws Exception
+ {
+ MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
+ for (MBeanAttributeInfo attributeMetadata : attributesMetadata)
+ {
+ String name = attributeMetadata.getName();
+ Object propertyValues = _resourceClient.getPropertyAsObject(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ Class.forName(attributeMetadata.getType()));
+
+ int length = Array.getLength(propertyValues);
+ if (length != 0)
+ {
+ Object propertyValue = Array.get(propertyValues, 0);
+
+ assertEquals(
+ "Comparison failed for property "+name,
+ _managementServer.getAttribute(_resourceObjectName,name),
+ propertyValue);
+ } else {
+ assertNull(
+ String.format(
+ "\"%s\" property value shouldn't be null. Its value is %s",
+ name,
+ _managementServer.getAttribute(_resourceObjectName,name)),
+ _managementServer.getAttribute(_resourceObjectName,name));
+ }
+ }
+ }
+
+ /**
+ * Tests the GetMultipleResourceProperties interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the GetMultipleResourceProperties request contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testGetResourcePropertiesKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.getResourceProperty(new QName("a","b","c"));
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertyDocumentTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertyDocumentTestCase.java
new file mode 100644
index 0000000000..862115f841
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertyDocumentTestCase.java
@@ -0,0 +1,134 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+
+/**
+ * Test case for Web Service Resource Properties interfaces.
+ * Those interfaces are defined on http://docs.oasis-open.org/wsrf/wsrf-ws_resource_properties-1.2-spec-os.pdf
+ * (Web Services Resource Properties 1.2 - (WS-ResourceProperties).
+ * For a better explanation see chapter 5 of the specification above.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetResourcePropertyDocumentTestCase extends BaseWsDmAdapterTestCase
+{
+ /**
+ * Tests the GetResourcePropertyDocument interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the GetResourcePropertyDocument contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testGetResourcePropertyDocumentKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+ _resourceClient.setTrace(true);
+
+ _resourceClient.getResourcePropertyDocument();
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+
+ /**
+ * Tests the WS-RP PutResourcePropertyDocument interface of the WS-DM adapter.
+ *
+ * <br>precondition : a ws resource exists and is registered.
+ * <br>postcondition : A read / write property is correctly set according to WSRP interface.
+ */
+ public void testGetAndPutResourcePropertyDocumentOK() throws Exception
+ {
+ String expectedMgmtPubIntervalValue = "4321";
+ String propertyName = "MgmtPubInterval";
+
+ Element propertiesDocument = _resourceClient.getResourcePropertyDocument();
+ Element [] properties = XmlUtils.getAllElements(propertiesDocument);
+
+ for (Element element : properties)
+ {
+ if (propertyName.equals(element.getLocalName())) {
+ element.setTextContent(expectedMgmtPubIntervalValue);
+ } else {
+ propertiesDocument.removeChild(element);
+ }
+ }
+
+ _resourceClient.putResourcePropertyDocument(propertiesDocument);
+
+ Element newProperties = _resourceClient.getResourcePropertyDocument();
+
+ Element mgmtPubInterval = XmlUtils.getElement(
+ newProperties, new QName(
+ Names.NAMESPACE_URI,
+ propertyName,
+ Names.PREFIX));
+
+ assertEquals(expectedMgmtPubIntervalValue,mgmtPubInterval.getTextContent());
+ }
+
+ /**
+ * Tests the WS-RP PutResourcePropertyDocument interface of the WS-DM adapter.
+ * Specifically it tries to update the value of a read-only property.
+ *
+ * <br>precondition : a ws resource exists, it is registered and has at least one read-only property.
+ * <br>postcondition : An exception is thrown indicating the failure.
+ */
+ public void testGetAndPutResourcePropertyDocumentKO_WithReadOnlyProperty() throws Exception
+ {
+ String propertyName = "Name";
+
+ Element propertiesDocument = _resourceClient.getResourcePropertyDocument();
+ Element [] properties = XmlUtils.getAllElements(propertiesDocument);
+
+ for (Element element : properties)
+ {
+ if (propertyName.equals(element.getLocalName())) {
+ element.setTextContent("ThisIsTheNewValueOfNameProperty");
+ } else {
+ propertiesDocument.removeChild(element);
+ }
+ }
+
+ try
+ {
+ _resourceClient.putResourcePropertyDocument(propertiesDocument);
+ fail("It's not possible to update the value of a read-only property.");
+ } catch (SoapFault expected)
+ {
+
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/MetadataExchangeInterfaceTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/MetadataExchangeInterfaceTestCase.java
new file mode 100644
index 0000000000..046f2226e6
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/MetadataExchangeInterfaceTestCase.java
@@ -0,0 +1,169 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.metadata.WsxConstants;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.muse.ws.resource.metadata.WsrmdConstants;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+
+/**
+ * Test case for QMan metadata exchange interface.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MetadataExchangeInterfaceTestCase extends BaseWsDmAdapterTestCase
+{
+ /**
+ * Test the MetadataExchange interface when the corresponding
+ * request doesn't contain a dialect. According to WS-MetadataExchange specs this should be
+ * intended as a "give-me-all-metadata" for that resource.
+ *
+ * <br>precondition : the GetMetadata request doesn't contain a dialect.
+ * <br>postcondition : the whole metadata document is returned with all metadata .
+ * It will contain both WSDL and RMD.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataOK_WithoutDialect() throws Exception
+ {
+ Element[] result = (Element[]) _resourceClient.invoke(
+ getProxyHandler(),
+ new Object[]{""});
+
+ assertEquals(2,result.length);
+
+ Element rmdMetadataSection = result[0];
+ Element wsdlMetadataSection = result[1];
+
+ Element rmd = XmlUtils.getFirstElement(rmdMetadataSection);
+ Element wsdl = XmlUtils.getFirstElement(wsdlMetadataSection);
+
+ assertEquals("MetadataDescriptor",rmd.getLocalName());
+ assertEquals("definitions",wsdl.getLocalName());
+ }
+
+ /**
+ * Test the MetadataExchange interface when the WSDL dialect is specified on the request.
+ *
+ * <br>precondition : the GetMetadata request contains WSDL dialect.
+ * <br>postcondition : the resource WSDL metadata document is returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataOK_WithWSDLDialect() throws Exception
+ {
+ Element[] result = (Element[]) _resourceClient.invoke(
+ getProxyHandler(),
+ new Object[]{WsxConstants.WSDL_DIALECT});
+
+ assertEquals(1,result.length);
+
+ Element wsdlMetadataSection = result[0];
+
+ Element wsdl = XmlUtils.getFirstElement(wsdlMetadataSection);
+
+ assertEquals("definitions",wsdl.getLocalName());
+ }
+
+ /**
+ * Test the MetadataExchange interface when the RMD dialect is specified on the request.
+ *
+ * <br>precondition : the GetMetadata request contains RMD dialect.
+ * <br>postcondition : the RMD metadata document is returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataOK_WithRMDDialect() throws Exception
+ {
+ Element[] result = (Element[]) _resourceClient.invoke(
+ getProxyHandler(),
+ new Object[]{WsrmdConstants.NAMESPACE_URI});
+
+ assertEquals(1,result.length);
+
+ Element rmdMetadataSection = result[0];
+
+ Element wsdl = XmlUtils.getFirstElement(rmdMetadataSection);
+
+ assertEquals("MetadataDescriptor",wsdl.getLocalName());
+ }
+
+ /**
+ * Test the MetadataExchange interface with an unknown metadata dialect.
+ *
+ * <br>precondition : the GetMetadata request contains an unknown dialect.
+ * <br>postcondition : the returned metadata section is empty.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataKO_WithoutUnknownDialect() throws Exception
+ {
+ Element [] metadata = (Element[]) _resourceClient.invoke(
+ getProxyHandler(),
+ new Object[]{"HopeThisIsAnUnknownDialect"});
+
+ assertEquals(0,metadata.length);
+ }
+
+ /**
+ * Test the MetadataExchange interface with an unknown metadata dialect.
+ *
+ * <br>precondition : the GetMetadata request contains an unknown dialect.
+ * <br>postcondition : the returned metadata section is empty.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataKO_WithoutUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.invoke(getProxyHandler(), new Object[]{""});
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+
+ /**
+ * Returns a proxy handler used for working with metadata exchange
+ * interface.
+ *
+ * @return a metadata proxy handler.
+ */
+ private ProxyHandler getProxyHandler()
+ {
+ ProxyHandler getMetadataHandler = new ReflectionProxyHandler();
+ getMetadataHandler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ getMetadataHandler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", "wsx"));
+ getMetadataHandler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", "wsx")});
+ getMetadataHandler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", "wsx"));
+ getMetadataHandler.setReturnType(Element[].class);
+ return getMetadataHandler;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/OperationInvocationInterfaceTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/OperationInvocationInterfaceTestCase.java
new file mode 100644
index 0000000000..afc4a62085
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/OperationInvocationInterfaceTestCase.java
@@ -0,0 +1,580 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.wsdm.capabilities.Result;
+
+/**
+ * Test case for QMan operation invocation interface.
+ *
+ * @author Andrea Gazzarini
+ */
+public class OperationInvocationInterfaceTestCase extends BaseWsDmAdapterTestCase
+{
+ private Map<String, ProxyHandler> _invocationHandlers = createInvocationHandlers();
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of a byte type array between requestor
+ * and service provider.
+ *
+ * <br>precondition : a WS-Resource exists and is registered and the requested
+ * operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown
+ * and byte array are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withByteArray() throws Exception
+ {
+ byte [] expectedByteResult = {1,3,4,2,2,44,22,3,3,55,66};
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithByteArray"),
+ new Object[]{expectedByteResult});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 1.",1,out.size());
+ assertArrayEquals(expectedByteResult, out.get(byte[].class.getName()));
+ }
+
+ /**
+ * Test a simple operation invocation on a WS-Resource.
+ * This method tests a simple operation without any input and output parameters.
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation
+ * is available on that.
+ * <br>postcondition : invocations are executed successfully an no exception is thrown.
+ */
+ @SuppressWarnings("unchecked")
+ public void testSimpleOperationInvocationOK() throws Exception
+ {
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("voidWithoutArguments"),
+ null);
+
+ assertNotNull(result);
+ }
+
+ /**
+ * Test a the invocation on a WS-Resource with a method that throws an exception..
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested
+ * operation is available on that.
+ * <br>postcondition : an exception is thrown by the requested method.
+ */
+ @SuppressWarnings("unchecked")
+ public void testInvocationException_OK() throws Exception
+ {
+ try
+ {
+ _resourceClient.invoke(
+ _invocationHandlers.get("throwsException"),
+ null);
+ fail("The requested operation has thrown an exception so a Soap Fault is expected...");
+ } catch(SoapFault expected)
+ {
+ }
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of UUID type between requestor and service provider.
+ *
+ * <br>precondition : a WS-Resource exists and is registered and the requested operation
+ * is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown
+ * and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withUUID() throws Exception
+ {
+ UUID expectedUuid = UUID.randomUUID();
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithUUID"),
+ new Object[]{expectedUuid});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 1.",1,out.size());
+ assertEquals(expectedUuid, out.get("uuid"));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of Map type between requestor and service provider.
+ * For this test exchanged arrays contain :
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested
+ * operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is
+ * thrown and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withMap() throws Exception
+ {
+ Map<String,Object> expectedMap = new HashMap<String, Object>();
+ expectedMap.put("p1", new Long(1));
+ expectedMap.put("p2", Boolean.TRUE);
+ expectedMap.put("p3", 1234d);
+ expectedMap.put("p4", 11.2f);
+ expectedMap.put("p5", 1272);
+ expectedMap.put("p6", (short)12);
+ expectedMap.put("p7", "aString");
+ expectedMap.put("p8", "http://qpid.apache.org");
+ expectedMap.put("p9", new Date(12383137128L));
+ expectedMap.put("p10", new byte[]{1,2,2,3,3,4});
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithMap"),
+ new Object[]{expectedMap});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+
+ Map<String,Object> out = (Map<String, Object>) ((Map<String, Object>) getOutputParameters.invoke(result)).get("map");
+
+ assertEquals("Output parameters must be 10.",10,out.size());
+ assertEquals(expectedMap.get("p1"),out.get("p1"));
+ assertEquals(expectedMap.get("p2"),out.get("p2"));
+ assertEquals(expectedMap.get("p3"),out.get("p3"));
+ assertEquals(expectedMap.get("p4"),out.get("p4"));
+ assertEquals(expectedMap.get("p5"),out.get("p5"));
+ assertEquals(expectedMap.get("p6"),out.get("p6"));
+ assertEquals(expectedMap.get("p7"),out.get("p7"));
+ assertEquals(expectedMap.get("p8"),out.get("p8"));
+ assertEquals(expectedMap.get("p9"),out.get("p9"));
+ assertTrue( Arrays.equals((byte[])expectedMap.get("p10"),(byte[])out.get("p10")));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of simple types between requestor and
+ * service provider.
+ *
+ * With simple types we mean :
+ *
+ * <ul>
+ * <li>java.lang.Long / long (xsd:long)
+ * <li>java.lang.Integer / int (xsd:int / xsd:integer)
+ * <li>java.lang.Double/ double (xsd:double)
+ * <li>java.lang.Float / float (xsd:float)
+ * <li>java.lang.Short / short (xsd:short)
+ * <li>java.lang.Boolean / boolean (xsd:boolean)
+ * <li>java.lang.String (xsd:string)
+ * <li>java.net.URI (xsd:anyURI)
+ * <li>java.util.Date(xsd:dateTime)
+ * </ul>
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is
+ * available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and
+ * parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withSimpleTypes() throws Exception
+ {
+ Long expectedLongResult = new Long(1373);
+ Boolean expectedBooleanResult = Boolean.TRUE;
+ Double expectedDoubleResult = new Double(12763.44);
+ Float expectedFloatResult = new Float(2727.233f);
+ Integer expectedIntegerResult = new Integer(28292);
+ Short expectedShortResult = new Short((short)227);
+ String expectedStringResult = "expectedStringResult";
+ URI expectedUriResult = URI.create("http://qpid.apache.org/");
+ Date expectedDateResult = new Date();
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithSimpleTypes"),
+ new Object[]{
+ expectedLongResult,
+ expectedBooleanResult,
+ expectedDoubleResult,
+ expectedFloatResult,
+ expectedIntegerResult,
+ expectedShortResult,
+ expectedStringResult,
+ expectedUriResult,
+ expectedDateResult});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 9.",9,out.size());
+ assertTrue("Long output parameter not found on result object.",out.containsValue(expectedLongResult));
+ assertTrue("Boolean output parameter not found on result object.",out.containsValue(expectedBooleanResult));
+ assertTrue("Double output parameter not found on result object.",out.containsValue(expectedDoubleResult));
+ assertTrue("Float output parameter not found on result object.",out.containsValue(expectedFloatResult));
+ assertTrue("Integer output parameter not found on result object.",out.containsValue(expectedIntegerResult));
+ assertTrue("Short output parameter not found on result object.",out.containsValue(expectedShortResult));
+ assertTrue("String output parameter not found on result object.",out.containsValue(expectedStringResult));
+ assertTrue("URI output parameter not found on result object.",out.containsValue(expectedUriResult));
+ assertTrue("Date output parameter not found on result object.",out.containsValue(expectedDateResult));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of arrays between requestor and service provider.
+ * For this test exchanged arrays contain :
+ *
+ * <ul>
+ * <li>java.lang.Long (xsd:long)
+ * <li>java.lang.Integer (xsd:int / xsd:integer)
+ * <li>java.lang.Double (xsd:double)
+ * <li>java.lang.Float (xsd:float)
+ * <li>java.lang.Short (xsd:short)
+ * <li>java.lang.Boolean (xsd:boolean)
+ * <li>java.lang.String (xsd:string)
+ * <li>java.net.URI (xsd:anyURI)
+ * <li>java.util.Date(xsd:dateTime)
+ * </ul>
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withWrapperArrays() throws Exception
+ {
+ Long [] expectedLongResult = {new Long(2),new Long(1),new Long(3),new Long(4)};
+ Boolean [] expectedBooleanResult = { Boolean.TRUE,Boolean.FALSE,Boolean.FALSE};
+ Double [] expectedDoubleResult = {12763.44d,2832.33d,2292.33d,22293.22d};
+ Float [] expectedFloatResult = {2727.233f,1f,2f,4f,5.4f,33.2f};
+ Integer [] expectedIntegerResult = {1,2,3,4,55,66,77,88,99};
+ Short [] expectedShortResult = {(short)227,(short)23,(short)9};
+ String [] expectedStringResult = {"s1","s2","s333","s4"};
+ URI [] expectedUriResult = {
+ URI.create("http://qpid.apache.org/"),
+ URI.create("http://www.apache.org"),
+ URI.create("http://projects.apache.org")};
+
+ Date [] expectedDateResult = {
+ new Date(),
+ new Date(38211897),
+ new Date(903820382)};
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithArrays"),
+ new Object[]{
+ expectedLongResult,
+ expectedBooleanResult,
+ expectedDoubleResult,
+ expectedFloatResult,
+ expectedIntegerResult,
+ expectedShortResult,
+ expectedStringResult,
+ expectedUriResult,
+ expectedDateResult});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 9.",9,out.size());
+ assertTrue("Long array doesn't match.",Arrays.equals(expectedLongResult, (Long[])out.get(Long.class.getName())));
+ assertTrue("Boolean array doesn't match.",Arrays.equals(expectedBooleanResult, (Boolean[])out.get(Boolean.class.getName())));
+ assertTrue("Double array doesn't match.",Arrays.equals(expectedDoubleResult, (Double[])out.get(Double.class.getName())));
+ assertTrue("Float array doesn't match.",Arrays.equals(expectedFloatResult, (Float[])out.get(Float.class.getName())));
+ assertTrue("Integer array doesn't match.", Arrays.equals(expectedIntegerResult, (Integer[])out.get(Integer.class.getName())));
+ assertTrue("Short array doesn't match.",Arrays.equals(expectedShortResult, (Short[])out.get(Short.class.getName())));
+ assertTrue("String array doesn't match.",Arrays.equals(expectedStringResult, (String[])out.get(String.class.getName())));
+ assertTrue("URI array doesn't match.",Arrays.equals(expectedUriResult, (URI[])out.get(URI.class.getName())));
+ assertTrue("Date array doesn't match.",Arrays.equals(expectedDateResult, (Date[])out.get(Date.class.getName())));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of primitive type arrays between requestor and service provider.
+ * NOte that even the sent array contain primtiive type QMan deals only with objects so in the result
+ * object you will find the corresponding wrapper types.
+ *
+ * For this test exchanged arrays contain :
+ *
+ * <ul>
+ * <li>java.lang.Long / long (xsd:long)
+ * <li>java.lang.Integer / int (xsd:int / xsd:integer)
+ * <li>java.lang.Double/ double (xsd:double)
+ * <li>java.lang.Float / float (xsd:float)
+ * <li>java.lang.Short / short (xsd:short)
+ * <li>java.lang.Boolean / boolean (xsd:boolean)
+ * </ul>
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withPrimitiveArrays() throws Exception
+ {
+ long [] expectedLongResult = {1L,2L,3L,4L};
+ boolean [] expectedBooleanResult = { true,false,false};
+ double [] expectedDoubleResult = {12763.44d,2832.33d,2292.33d,22293.22d};
+ float [] expectedFloatResult = {2727.233f,1f,2f,4f,5.4f,33.2f};
+ int [] expectedIntegerResult = {1,2,3,4,55,66,77,88,99};
+ short [] expectedShortResult = {(short)227,(short)23,(short)9};
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithSimpleTypeArrays"),
+ new Object[]{
+ expectedLongResult,
+ expectedBooleanResult,
+ expectedDoubleResult,
+ expectedFloatResult,
+ expectedIntegerResult,
+ expectedShortResult});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 6.",6,out.size());
+ assertArrayEquals(expectedLongResult, out.get(long.class.getName()));
+ assertArrayEquals(expectedBooleanResult, out.get(boolean.class.getName()));
+ assertArrayEquals(expectedDoubleResult, out.get(double.class.getName()));
+ assertArrayEquals(expectedFloatResult, out.get(float.class.getName()));
+ assertArrayEquals(expectedIntegerResult, out.get(int.class.getName()));
+ assertArrayEquals(expectedShortResult, out.get(short.class.getName()));
+ }
+
+ /**
+ * Internal method used for array comparison using reflection.
+ *
+ * @param expectedArray the expected array.
+ * @param resultArray the array that must match the expected one.
+ */
+ private void assertArrayEquals(Object expectedArray, Object resultArray)
+ {
+ int expectedArrayLength = Array.getLength(expectedArray);
+ int resultArrayLength = Array.getLength(resultArray);
+
+ assertEquals(expectedArrayLength,resultArrayLength);
+
+ for (int index = 0; index < expectedArrayLength; index++)
+ {
+ Object expected = Array.get(expectedArray, index);
+ Object result = Array.get(resultArray, index);
+
+ assertEquals(expected,result);
+ }
+ }
+
+ private Map<String,ProxyHandler> createInvocationHandlers()
+ {
+ Map<String, ProxyHandler> handlers = new HashMap<String, ProxyHandler>();
+
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction(Names.NAMESPACE_URI+"/"+"voidWithoutArguments");
+ handler.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "voidWithoutArgumentsRequest",
+ Names.PREFIX));
+ handler.setRequestParameterNames(new QName[]{});
+ handler.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "voidWithoutArgumentsResponse",
+ Names.PREFIX));
+ handler.setReturnType(Result.class);
+
+ ProxyHandler exceptionHandler = new ReflectionProxyHandler();
+ exceptionHandler.setAction(Names.NAMESPACE_URI+"/"+"throwsException");
+ exceptionHandler.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "throwsExceptionRequest",
+ Names.PREFIX));
+
+ exceptionHandler.setRequestParameterNames(new QName[]{});
+ exceptionHandler.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "throwsExceptionResponse",
+ Names.PREFIX));
+
+ exceptionHandler.setReturnType(Result.class);
+
+ ProxyHandler echoWithWrapperTypesHandler = new ReflectionProxyHandler();
+ echoWithWrapperTypesHandler.setAction(Names.NAMESPACE_URI+"/"+"echoWithSimpleTypes");
+ echoWithWrapperTypesHandler.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypesRequest",
+ Names.PREFIX));
+
+ echoWithWrapperTypesHandler.setRequestParameterNames(new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p7",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p8",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p9",Names.PREFIX),
+ });
+
+ echoWithWrapperTypesHandler.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypesResponse",
+ Names.PREFIX));
+
+ echoWithWrapperTypesHandler.setReturnType(Result.class);
+
+ ProxyHandler echoWithArrayOfWrapperTypes = new ReflectionProxyHandler();
+ echoWithArrayOfWrapperTypes.setAction(Names.NAMESPACE_URI+"/"+"echoWithArrays");
+ echoWithArrayOfWrapperTypes.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithArraysRequest",
+ Names.PREFIX));
+
+ echoWithArrayOfWrapperTypes.setRequestParameterNames(new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p7",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p8",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p9",Names.PREFIX),
+ });
+
+ echoWithArrayOfWrapperTypes.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithArraysResponse",
+ Names.PREFIX));
+
+ echoWithArrayOfWrapperTypes.setReturnType(Result.class);
+
+ ProxyHandler echoWithArrayOfPrimitiveTypes = new ReflectionProxyHandler();
+ echoWithArrayOfPrimitiveTypes.setAction(Names.NAMESPACE_URI+"/"+"echoWithSimpleTypeArrays");
+ echoWithArrayOfPrimitiveTypes.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypeArraysRequest",
+ Names.PREFIX));
+
+ echoWithArrayOfPrimitiveTypes.setRequestParameterNames(new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX)});
+
+ echoWithArrayOfPrimitiveTypes.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypeArraysResponse",
+ Names.PREFIX));
+
+ echoWithArrayOfPrimitiveTypes.setReturnType(Result.class);
+
+ ProxyHandler echoWithByteArray = new EnhancedReflectionProxyHandler();
+ echoWithByteArray.setAction(Names.NAMESPACE_URI+"/"+"echoWithByteArray");
+ echoWithByteArray.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithByteArrayRequest",
+ Names.PREFIX));
+
+ echoWithByteArray.setRequestParameterNames(
+ new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
+
+ echoWithByteArray.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithByteArrayResponse",
+ Names.PREFIX));
+
+ echoWithByteArray.setReturnType(Result.class);
+
+ ProxyHandler echoWithUUID = new EnhancedReflectionProxyHandler();
+ echoWithUUID.setAction(Names.NAMESPACE_URI+"/"+"echoWithUUID");
+ echoWithUUID.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithUUIDRequest",
+ Names.PREFIX));
+
+ echoWithUUID.setRequestParameterNames(
+ new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
+
+ echoWithUUID.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithUUIDResponse",
+ Names.PREFIX));
+
+ echoWithUUID.setReturnType(Result.class);
+
+ ProxyHandler echoWithMap = new EnhancedReflectionProxyHandler();
+ echoWithMap.setAction(Names.NAMESPACE_URI+"/"+"echoWithMap");
+ echoWithMap.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithMapRequest",
+ Names.PREFIX));
+
+ echoWithMap.setRequestParameterNames(
+ new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
+
+ echoWithMap.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithMapResponse",
+ Names.PREFIX));
+
+ echoWithMap.setReturnType(Result.class);
+
+ handlers.put("voidWithoutArguments",handler);
+ handlers.put("echoWithSimpleTypes",echoWithWrapperTypesHandler);
+ handlers.put("echoWithArrays",echoWithArrayOfWrapperTypes);
+ handlers.put("echoWithSimpleTypeArrays", echoWithArrayOfPrimitiveTypes);
+ handlers.put("echoWithByteArray", echoWithByteArray);
+ handlers.put("echoWithUUID", echoWithUUID);
+ handlers.put("echoWithMap", echoWithMap);
+ handlers.put("throwsException",exceptionHandler);
+ return handlers;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/ServerThread.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/ServerThread.java
new file mode 100644
index 0000000000..6574c278ff
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/ServerThread.java
@@ -0,0 +1,118 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm;
+
+import java.io.File;
+
+import org.apache.qpid.management.Names;
+import org.mortbay.component.LifeCycle.Listener;
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.jetty.webapp.WebAppContext;
+import org.mortbay.start.Monitor;
+
+/**
+ * Web Server startup thread.
+ * It is used on adapter test case in order to start the embedded
+ * web server as a separated thread.
+ *
+ * @author Andrea Gazzarini
+ */
+class ServerThread extends Thread
+{
+ private final Listener _lifecycleListener;
+ private Server _server;
+
+ private SelectChannelConnector _connector;
+
+ /**
+ * Builds a new server thread with the given lifecycle listener.
+ *
+ * @param listener the lifecycle listener.
+ */
+ ServerThread(Listener listener)
+ {
+ this._lifecycleListener = listener;
+ }
+
+ /**
+ * Starts the server.
+ */
+ @Override
+ public void run()
+ {
+ try
+ {
+ Monitor.monitor();
+ _server = new Server();
+ _server.setStopAtShutdown(true);
+
+ _connector=new SelectChannelConnector();
+ _connector.setPort(Integer.parseInt(System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME)));
+ _connector.setHost(System.getProperty(Names.ADAPTER_HOST_PROPERTY_NAME));
+
+
+ _server.setConnectors(new Connector[]{_connector});
+
+ WebAppContext webapp = new WebAppContext();
+ webapp.setContextPath("/qman");
+
+ // Additional web application descriptor containing test components.
+ webapp.setDefaultsDescriptor("/org/apache/qpid/management/wsdm/web.xml");
+
+ String webApplicationPath = System.getProperty("qman.war");
+ File rootFolderPath = (webApplicationPath != null) ? new File(webApplicationPath) : new File(".");
+
+ webapp.setWar(rootFolderPath.toURI().toURL().toExternalForm());
+ webapp.addLifeCycleListener(_lifecycleListener);
+ _server.setHandler(webapp);
+ _server.start();
+ System.setProperty(Names.ADAPTER_PORT_PROPERTY_NAME,String.valueOf( _connector.getLocalPort()));
+ _server.join();
+
+ } catch(Exception exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ /**
+ * Shutdown the server.
+ *
+ * @throws Exception when a problem is encountered during shutdown.
+ */
+ void shutdown() throws Exception
+ {
+ _server.stop();
+ }
+
+ /**
+ * Returns the port number where the server is running.
+ *
+ * @return the port number where the server is running.
+ */
+ int getPort()
+ {
+ return _connector.getLocalPort();
+ }
+
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/SetResourcePropertiesTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/SetResourcePropertiesTestCase.java
new file mode 100644
index 0000000000..87f8905e01
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/SetResourcePropertiesTestCase.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.management.wsdm;
+
+import java.lang.reflect.Array;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.management.MBeanAttributeInfo;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.qpid.management.Names;
+
+/**
+ * Test case for Set Resource Properties interfaces.
+ *
+ * @author Andrea Gazzarini
+ */
+public class SetResourcePropertiesTestCase extends BaseWsDmAdapterTestCase
+{
+ /**
+ * Test the WS-RP SetResourceProperty interface of the WS-DM adapter.
+ *
+ * <br>precondition : a WS-Resource exists and is registered.
+ * <br>postcondition : property values are correctly updated on the target WS-Resource..
+ */
+ public void testSetResourcePropertiesOK() throws Exception
+ {
+ Map<String, Object> sampleMap = new HashMap<String, Object>();
+ sampleMap.put("Key1", "BLABALABLABALBAL");
+ sampleMap.put("Key2", 182838484l);
+ sampleMap.put("Key3", -928376362);
+ sampleMap.put("Key4", 23762736276.33D);
+ sampleMap.put("Key4", 2327363.2F);
+
+ Map<String, Object> sampleValues = new HashMap<String, Object>();
+ sampleValues.put(String.class.getName(),"SAMPLE_STRING");
+ sampleValues.put(UUID.class.getName(),UUID.randomUUID());
+ sampleValues.put(Boolean.class.getName(),Boolean.FALSE);
+ sampleValues.put(Map.class.getName(),sampleMap);
+ sampleValues.put(Long.class.getName(),283781273L);
+ sampleValues.put(Integer.class.getName(),12727);
+ sampleValues.put(Short.class.getName(),new Short((short)22));
+ sampleValues.put(Date.class.getName(),new Date());
+
+ MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
+ boolean atLeastThereIsOneWritableProperty = false;
+
+ for (MBeanAttributeInfo attributeMetadata : attributesMetadata)
+ {
+ String name = attributeMetadata.getName();
+
+ if (attributeMetadata.isWritable())
+ {
+ atLeastThereIsOneWritableProperty = true;
+ Object sampleValue = sampleValues.get(attributeMetadata.getType());
+ Object []values = new Object[]{sampleValue};
+
+ Object result = _managementServer.getAttribute(_resourceObjectName, name);
+ if (result == null)
+ {
+ _resourceClient.insertResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ values);
+ } else
+ {
+ _resourceClient.updateResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ values);
+ }
+
+ Object propertyValues = _resourceClient.getPropertyAsObject(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ Class.forName(attributeMetadata.getType()));
+ int length = Array.getLength(propertyValues);
+ if (length != 0)
+ {
+ Object propertyValue = Array.get(propertyValues, 0);
+
+ assertEquals(
+ "Comparison failed for property "+name,
+ sampleValue,
+ propertyValue);
+ } else {
+ assertNull(
+ String.format(
+ "\"%s\" property value shouldn't be null. Its value is %s",
+ name,
+ _managementServer.getAttribute(_resourceObjectName,name)),
+ sampleValue);
+ }
+ }
+ }
+ assertTrue(
+ "It's not possibile to run successfully this test case if " +
+ "the target WS-Resource has no at least one writable property",
+ atLeastThereIsOneWritableProperty);
+ }
+
+ /**
+ * Test the WS-RP SetResourceProperty interface of the WS-DM adapter when the
+ * target property is null.
+ * According to WS-RP specs this operation is not allowed because in this case a SetResourceProperty with an "Insert"
+ * message should be sent in order to initialize the property.
+ *
+ * <br>precondition : a ws resource exists and is registered. The value of the target property is null.
+ * <br>postcondition : a Soap fault is received indicating the failuire.
+ */
+ public void testSetResourcePropertiesKO() throws Exception
+ {
+ Object typePropertyValue = _managementServer.getAttribute(_resourceObjectName, "Type");
+ assertNull(typePropertyValue);
+
+ try
+ {
+ _resourceClient.updateResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ "Type",
+ Names.PREFIX),
+ new Object[]{"sampleValue"});
+ fail(
+ "If the property is null on the target ws resource, according " +
+ "to WS-RP specs, an update of its value is not possible.");
+ } catch(SoapFault expected)
+ {
+
+ }
+ }
+
+ /**
+ * Tests the SetResourceProperties (update) interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the SetResourceProperties contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testUpdateResourcePropertiesKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.updateResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ "Type",
+ Names.PREFIX),
+ new Object[]{"sampleValue"});
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+
+ /**
+ * Tests the SetResourceProperties (insert) interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the SetResourceProperties contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testInsertResourcePropertiesKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.insertResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ "Type",
+ Names.PREFIX),
+ new Object[]{"sampleValue"});
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WebApplicationLifeCycleListener.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WebApplicationLifeCycleListener.java
new file mode 100644
index 0000000000..91c646467e
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WebApplicationLifeCycleListener.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.management.wsdm;
+
+import org.mortbay.component.LifeCycle;
+import org.mortbay.component.LifeCycle.Listener;
+
+/**
+ * Adapter class used to provide an empty (base) implementation of
+ * Lifecycle listener interface.
+ *
+ * Adapter test case needs to be informed about the lifecycle of the
+ * deployed QMan application. Only when its deployment is completed the test
+ * case can run successfully.
+ *
+ * So, following the same logic of Swng event model, this is an adapter that provides
+ * empty implementation of the listener interface (see for example MouseAdapter
+ * for mouse events listener)
+ *
+ * @author Andrea Gazzarini
+ */
+public class WebApplicationLifeCycleListener implements Listener
+{
+ public void lifeCycleFailure(LifeCycle event, Throwable cause)
+ {
+ }
+
+ public void lifeCycleStarted(LifeCycle event)
+ {
+ }
+
+ public void lifeCycleStarting(LifeCycle event)
+ {
+ }
+
+ public void lifeCycleStopped(LifeCycle event)
+ {
+ }
+
+ public void lifeCycleStopping(LifeCycle event)
+ {
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java
new file mode 100644
index 0000000000..f12288c91d
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.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.management.wsdm;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.wsdm.capabilities.Result;
+import org.apache.qpid.management.wsdm.muse.serializer.DateSerializer;
+import org.apache.qpid.management.wsdm.muse.serializer.InvocationResultSerializer;
+import org.apache.qpid.management.wsdm.muse.serializer.MapSerializer;
+import org.apache.qpid.management.wsdm.muse.serializer.ObjectSerializer;
+import org.apache.qpid.management.wsdm.muse.serializer.UUIDSerializer;
+import org.mortbay.component.LifeCycle;
+import org.mortbay.component.LifeCycle.Listener;
+
+import junit.extensions.TestSetup;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class WsDmAdapterTest
+{
+
+ /**
+ * Test case wide set up.
+ * Provides Server startup & shutdown global procedure.
+ *
+ * @author Andrea Gazzarini
+ */
+ private static class WsDmAdapterTestSetup extends TestSetup
+ {
+ private Object _serverMonitor = new Object();
+
+ Listener listener = new WebApplicationLifeCycleListener()
+ {
+ public void lifeCycleStarted(LifeCycle event)
+ {
+ synchronized (_serverMonitor)
+ {
+ _serverMonitor.notify();
+ }
+ }
+ };
+
+ private ServerThread _server;
+
+ /**
+ * Builds a new test setup with for the given test.
+ *
+ * @param test the decorated test.
+ */
+ public WsDmAdapterTestSetup(Test test)
+ {
+ super(test);
+ }
+
+ /**
+ * Starts up Web server.
+ *
+ * @throws Exception when the server startup fails.
+ */
+ @Override
+ protected void setUp() throws Exception
+ {
+ SerializerRegistry.getInstance().registerSerializer(Object.class, new ObjectSerializer());
+ SerializerRegistry.getInstance().registerSerializer(Date.class, new DateSerializer());
+ SerializerRegistry.getInstance().registerSerializer(Map.class, new MapSerializer());
+ SerializerRegistry.getInstance().registerSerializer(HashMap.class, new MapSerializer());
+ SerializerRegistry.getInstance().registerSerializer(UUID.class, new UUIDSerializer());
+ SerializerRegistry.getInstance().registerSerializer(Result.class, new InvocationResultSerializer());
+
+ System.setProperty(
+ Names.ADAPTER_HOST_PROPERTY_NAME,
+ Protocol.DEFAULT_QMAN_HOSTNAME);
+
+ System.setProperty(
+ Names.ADAPTER_PORT_PROPERTY_NAME,
+ String.valueOf(getFreePort()));
+
+ _server = new ServerThread(listener);
+ _server.start();
+
+ synchronized(_serverMonitor) {
+ _serverMonitor.wait();
+ Thread.sleep(2000);
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ _server.shutdown();
+ }
+ };
+
+ /**
+ * Gets the test suite composition.
+ *
+ * @return the test suite composition.
+ */
+ public static Test suite()
+ {
+ TestSuite suite = new TestSuite("Test suite for QMan WS-DM.");
+ /*suite.addTestSuite(MetadataExchangeInterfaceTestCase.class);
+ suite.addTestSuite(OperationInvocationInterfaceTestCase.class);
+ suite.addTestSuite(GetResourcePropertyDocumentTestCase.class);
+ suite.addTestSuite(SetResourcePropertiesTestCase.class);
+ suite.addTestSuite(GetMultipleResourcePropertiesTestCase.class);
+ suite.addTestSuite(GetResourcePropertiesTestCase.class); */
+ return new WsDmAdapterTestSetup(suite);
+ }
+
+ /**
+ * Finds a free port that will be used to run the embedded
+ * web server.
+ *
+ * @return a free port that will be used to run the
+ * embedded web server.
+ */
+ private static int getFreePort() throws IOException {
+ ServerSocket server = null;
+ try
+ {
+ server = new ServerSocket(0);
+ return server.getLocalPort();
+ } finally
+ {
+ server.close();
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilderTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilderTest.java
new file mode 100644
index 0000000000..68c9930ecd
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilderTest.java
@@ -0,0 +1,335 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.capabilities;
+
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javassist.CtClass;
+import javassist.CtMethod;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.xml.namespace.QName;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObject;
+import org.apache.qpid.management.wsdm.common.EntityInstanceNotFoundFault;
+import org.apache.qpid.management.wsdm.common.MethodInvocationFault;
+import org.apache.qpid.management.wsdm.common.NoSuchAttributeFault;
+import org.apache.qpid.management.wsdm.common.QManFault;
+
+/**
+ * Test case for MBean capability builder.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MBeanCapabilityBuilderTest extends TestCase
+{
+
+ /**
+ * Management interface for an mbean that has no properties and no
+ * methods.
+ *
+ * @author Andrea Gazzarini
+ */
+ public interface NoPropertiesNoMethodsMBean
+ {
+ }
+
+ /**
+ * Implementation of the managenent interface described above.
+ *
+ * @author Andrea Gazzarini
+ */
+ public class NoPropertiesNoMethods implements NoPropertiesNoMethodsMBean
+ {
+ }
+
+ private MBeanCapabilityBuilder _builder;
+ private ObjectName _objectName;
+
+ /**
+ * Set up fixture for this test case.
+ */
+ protected void setUp() throws Exception
+ {
+ _builder = new MBeanCapabilityBuilder();
+ _objectName = new ObjectName("Test:Name=aName,class=DomainObject");
+ }
+
+ /**
+ * Tests that state change that occcurs on the begin() method when the requested
+ * class has not been defined.
+ */
+ public void testBegin_withClassNotYetDefined() throws Exception
+ {
+ _builder.begin(_objectName);
+ assertEquals(_builder._state,_builder._classNotAvailable);
+ }
+
+ /**
+ * Tests that state change that occcurs on the begin() method when the requested
+ * class has not been defined.
+ */
+ public void testBegin_withClassAlreadyDefined() throws Exception
+ {
+ _objectName = new ObjectName("Test:Name=aString,class=MBeanCapabilityBuilder");
+ _builder.begin(_objectName);
+
+ assertTrue(_builder._state instanceof DummyCapabilityBuilder);
+ assertSame(_builder._endAttributeHandler, _builder._noPropertyHasBeenDefined);
+ }
+
+ /**
+ * Tests the generateGetter method().
+ */
+ public void testGenerateGetter()
+ {
+ String name ="MyProperty";
+ String type = Long.class.getName();
+ String expected =
+ "public "+
+ type+
+ " get"+
+ name+
+ "() throws NoSuchAttributeFault,EntityInstanceNotFoundFault,QManFault { return ("+
+ type+
+ ") getAttribute(\""+
+ name+
+ "\"); }";
+
+ String result = _builder.generateGetter(type, name,name);
+ assertEquals(expected,result);
+ }
+
+ /**
+ * Tests the generateGetter method().
+ */
+ public void testGenerateSetter()
+ {
+ String name ="MyProperty";
+ String type = Long.class.getName();
+ String expected =
+ "public void setMyProperty("+
+ type+
+ " newValue) throws NoSuchAttributeFault,EntityInstanceNotFoundFault,QManFault { setAttribute(\""+
+ name+
+ "\", newValue); }";
+
+ String result = _builder.generateSetter(type, name,name);
+ assertEquals(expected,result);
+ }
+
+ /**
+ * Tests buils of a capability that has no properties and methods
+ *
+ * <br>precondition : the incoming entity definition is empty (no properties and no methods)
+ * <br>postcondition : the capability class is built successfully and has no props and methods.
+ * The getPropertyNames returns an empty QName array.
+ */
+ public void testOK_WithNoPropertiesNoMethods() throws Exception {
+
+ ObjectName name = new ObjectName("Test:Name=NoPropertiesNoMethods");
+
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+ server.registerMBean(new NoPropertiesNoMethods(), name);
+
+ _builder.begin(name);
+ _builder.endAttributes();
+ _builder.endOperations();
+ Class<MBeanCapability> capabilityClass = _builder.getCapabilityClass();
+
+ Field[] fields = capabilityClass.getDeclaredFields();
+ Method [] methods = capabilityClass.getDeclaredMethods();
+
+ assertEquals(Arrays.toString(fields),0,fields.length);
+ assertEquals(Arrays.toString(methods),1,methods.length);
+
+ Method getPropertyNames = methods[0];
+ assertEquals("getPropertyNames",getPropertyNames.getName());
+
+
+ MBeanCapability capability = capabilityClass.newInstance();
+ QName [] properties = (QName[]) getPropertyNames.invoke(capability);
+ assertEquals(0,properties.length);
+ }
+
+ /**
+ * Tests the whole execution of the builder.
+ */
+ @SuppressWarnings("unchecked")
+ public void testBuildOK() throws Exception
+ {
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+ QpidDomainObject mbean = new QpidDomainObject();
+ server.registerMBean(mbean, _objectName);
+
+ _builder.begin(_objectName);
+
+ CtClass definition = _builder._capabilityClassDefinition;
+ assertEquals(
+ MBeanCapability.class.getName(),
+ definition.getSuperclass().getName());
+
+ MBeanInfo metadata = server.getMBeanInfo(_objectName);
+
+ for (MBeanAttributeInfo attribute : metadata.getAttributes())
+ {
+ _builder.onAttribute(attribute);
+ checkAttribute(attribute, definition);
+
+ assertSame(
+ _builder._endAttributeHandler,
+ _builder._atLeastThereIsOneProperty);
+ }
+
+ for (MBeanOperationInfo operation : metadata.getOperations())
+ {
+ _builder.onOperation(operation);
+ checkOperation(operation,definition);
+ }
+
+ _builder.endAttributes();
+ _builder.endOperations();
+
+ assertNotNull(_builder.getCapabilityClass());
+ }
+
+ /**
+ * Checks an operation / method after that it has been declared on
+ * capability definition.
+ *
+ * @param operation the (JMX) operation metadata.
+ * @param definition the capability class definition.
+ * @throws Exception when something goes wrong during introspection.
+ */
+ private void checkOperation(MBeanOperationInfo operation, CtClass definition) throws Exception
+ {
+ CtMethod method = definition.getDeclaredMethod(operation.getName());
+ assertNotNull(method);
+
+ checkExceptionTypes(
+ method.getExceptionTypes(),
+ new String[]{
+ QManFault.class.getName(),
+ EntityInstanceNotFoundFault.class.getName(),
+ MethodInvocationFault.class.getName()});
+
+ assertEquals(Result.class.getName(),method.getReturnType().getName());
+
+ CtClass [] parameterTypes = method.getParameterTypes();
+ MBeanParameterInfo [] parameterMetadata = operation.getSignature();
+
+ assertEquals(parameterTypes.length, parameterMetadata.length);
+ for (int i = 0; i < parameterMetadata.length; i++)
+ {
+ assertEquals(
+ parameterTypes[i].getName(),
+ Class.forName(parameterMetadata[i].getType()).getCanonicalName());
+ }
+ }
+
+ /**
+ * Checks the exception types associated with a method.
+ *
+ * @param exceptionTypes the exception types actually thrown.
+ * @param expectedExceptionNames the expected exception types (as strings).
+ */
+ private void checkExceptionTypes(CtClass [] exceptionTypes, String [] expectedExceptionNames)
+ {
+ List<String> exceptionNames = new ArrayList<String>(exceptionTypes.length);
+ for (CtClass exception : exceptionTypes)
+ {
+ exceptionNames.add(exception.getName());
+ }
+
+ for (String expectedExceptionName : expectedExceptionNames)
+ {
+ exceptionNames.remove(expectedExceptionName);
+ }
+
+ assertTrue(exceptionNames.isEmpty());
+ }
+
+ /**
+ * Checks an attribute after that it has been declared on capability definition.
+ *
+ * @param attribute the (JMX) attribute metadata.
+ * @param definition the capability class definition.
+ * @throws Exception when something goes wrong during introspection.
+ */
+ private void checkAttribute(MBeanAttributeInfo attribute, CtClass definition) throws Exception
+ {
+ String name = _builder.getNameForAccessors(attribute.getName());
+
+ String newPropertyDeclaration =
+ new StringBuilder("new QName(Names.NAMESPACE_URI, \"")
+ .append(attribute.getName())
+ .append("\", Names.PREFIX),")
+ .toString();
+ assertTrue(_builder._properties.indexOf(newPropertyDeclaration) != -1);
+
+ if (attribute.isReadable())
+ {
+ CtMethod getter = definition.getDeclaredMethod("get"+name);
+ assertNotNull(getter);
+
+ checkExceptionTypes(
+ getter.getExceptionTypes(),
+ new String[]{
+ QManFault.class.getName(),
+ NoSuchAttributeFault.class.getName(),
+ EntityInstanceNotFoundFault.class.getName()});
+
+ assertEquals(0,getter.getParameterTypes().length);
+ assertEquals(attribute.getType(),getter.getReturnType().getName());
+ }
+
+ if (attribute.isWritable())
+ {
+ CtMethod setter = definition.getDeclaredMethod("set"+name);
+ assertNotNull(setter);
+
+ checkExceptionTypes(
+ setter.getExceptionTypes(),
+ new String[]{
+ QManFault.class.getName(),
+ NoSuchAttributeFault.class.getName(),
+ EntityInstanceNotFoundFault.class.getName()});
+
+ CtClass [] parameterTypes = setter.getParameterTypes();
+
+ assertEquals(1,parameterTypes.length);
+ assertEquals(attribute.getType(),parameterTypes[0].getName());
+ assertEquals(void.class.getName(),setter.getReturnType().getName());
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityTest.java
new file mode 100644
index 0000000000..a9a6491209
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityTest.java
@@ -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.
+ *
+ */
+package org.apache.qpid.management.wsdm.capabilities;
+
+import java.lang.management.ManagementFactory;
+import java.net.URI;
+
+import javax.management.ObjectName;
+
+import junit.framework.TestCase;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.WsResource;
+import org.apache.muse.ws.resource.impl.SimpleWsResource;
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObject;
+import org.apache.qpid.management.wsdm.common.EntityInstanceNotFoundFault;
+import org.apache.qpid.management.wsdm.common.NoSuchAttributeFault;
+import org.apache.qpid.management.wsdm.common.QManFault;
+
+/**
+ * Test case for MBeanCapability supertype layer..
+ *
+ * @author Andrea Gazzarini
+ */
+public class MBeanCapabilityTest extends TestCase
+{
+ private final String _typeAttributeName = "Type";
+ private final String _newTypeValue = "DomainObject";
+
+ private ObjectName _objectName;
+ private ObjectName _unknownObjectName;
+
+ private MBeanCapability _capability;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ _objectName = new ObjectName("Test:Name=aName");
+ _unknownObjectName = new ObjectName("Test:Type=unknown");
+
+ _capability = new MBeanCapability(){
+ @Override
+ public WsResource getWsResource()
+ {
+ return new SimpleWsResource(){
+ @Override
+ public EndpointReference getEndpointReference()
+ {
+ return new EndpointReference(URI.create("http://qpid.apache.org/qman"));
+ }
+ };
+ }
+ };
+ _capability.setResourceObjectName(_objectName);
+ ManagementFactory.getPlatformMBeanServer().registerMBean(new QpidDomainObject(), _objectName);
+ }
+
+ /**
+ * Tests the execution of the getAttribute() and setAttribute() method.
+ *
+ * <br>precondition : the mbean is registered and a _capability is associated with it.
+ * <br>postcondition : the set value of the requested attribute is correctly returned.
+ */
+ public void testGetAndSetAttributeOK() throws Exception
+ {
+ Object name = _capability.getAttribute(_typeAttributeName);
+ assertNull("Name has an initial value of null so how is possibile that is not null?",name);
+
+ _capability.setAttribute(_typeAttributeName,_newTypeValue);
+
+ name = _capability.getAttribute(_typeAttributeName);
+ assertEquals("Now the name attribute must be set to \""+_newTypeValue+"\"",_newTypeValue,name);
+ }
+
+ /**
+ * Tests the execution of the getAttribute() and setAttribte() methods when an unknown attribute is given..
+ *
+ * <br>precondition : the mbean is registered, a _capability is associated with it and the requested attribute doesn't exist.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testNoSuchAttributeFault() throws Exception
+ {
+ // I suppose that we shouldn't have an attribute with this name...
+ String unknownAttribute = String.valueOf(System.currentTimeMillis());
+
+ try
+ {
+ _capability.getAttribute(unknownAttribute);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(NoSuchAttributeFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.setAttribute(unknownAttribute,null);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(NoSuchAttributeFault expected)
+ {
+ }
+ }
+
+ /**
+ * Tests the execution of the setAttribute,getAttribute and invoke methods when the target mbean
+ * doesn't exists.
+ *
+ * <br>precondition : the object name associated with the capability is not pointing to an existent MBean.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testEntityInstanceNotFoundFault() throws Exception
+ {
+ _capability.setResourceObjectName(_unknownObjectName);
+
+ try
+ {
+ _capability.getAttribute(_typeAttributeName);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(EntityInstanceNotFoundFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.setAttribute(_typeAttributeName,_newTypeValue);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(EntityInstanceNotFoundFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.invoke("operationName", null,null);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(EntityInstanceNotFoundFault expected)
+ {
+ }
+ }
+
+ /**
+ * Tests the execution of the setAttribute,getAttribute and invoke methods when an unknown / unexpected
+ * exception is thrown.
+ *
+ * <br>precondition : the mbean is registered and a capability is associated with it. Something
+ * unexpected happens during method invocation.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testQManFault() throws Exception
+ {
+ // Emulate a RuntimeException (which is the best example of uncaught exception... :) )
+ _capability.setResourceObjectName(null);
+
+ try
+ {
+ _capability.getAttribute(_typeAttributeName);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(QManFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.setAttribute(_typeAttributeName,_newTypeValue);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(QManFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.invoke("operationName", null,null);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(QManFault expected)
+ {
+ }
+ }
+
+
+ /**
+ * Shutdown procedure for this test case.
+ */
+ @Override
+ protected void tearDown() throws Exception
+ {
+ ManagementFactory.getPlatformMBeanServer().unregisterMBean(_objectName);
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapabilityTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapabilityTest.java
new file mode 100644
index 0000000000..648c7b2f60
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapabilityTest.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.management.wsdm.capabilities;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import org.apache.muse.ws.notification.NotificationProducer;
+import org.apache.qpid.management.Names;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for QMan adapter capability.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QManAdapterCapabilityTest extends TestCase
+{
+ /**
+ * Tests the execution of the getTopicName() method.
+ *
+ * <br>precondition : an object type is given to the method (null is allowed).
+ * <br>postcondition : according to getTopicName() specs, the name of the
+ * topic associated with the given object type must be returned.
+ */
+ public void testGetTopicName()
+ {
+ final InvocationHandler invocationHandler = new InvocationHandler(){
+
+ public Object invoke(Object proxy, Method method, Object[] args)
+ {
+ return null;
+ }
+ };
+
+ QManAdapterCapability capability = new QManAdapterCapability(){
+ @Override
+ NotificationProducer getPublisherCapability()
+ {
+ return (NotificationProducer) Proxy.newProxyInstance(
+ getClass().getClassLoader(),
+ new Class[]{NotificationProducer.class},
+ invocationHandler);
+ }
+ };
+
+ capability.createLifeCycleTopics();
+
+ assertEquals(
+ Names.EVENTS_LIFECYLE_TOPIC_NAME,
+ capability.getTopicName(Names.EVENT));
+
+ assertEquals(
+ Names.OBJECTS_LIFECYLE_TOPIC_NAME,
+ capability.getTopicName(Names.CLASS));
+
+ assertEquals(
+ Names.UNKNOWN_OBJECT_TYPE_LIFECYLE_TOPIC_NAME,
+ capability.getTopicName("This is an unknown object Type @#!--!!@#"));
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilderTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilderTest.java
new file mode 100644
index 0000000000..77cda1c2c1
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilderTest.java
@@ -0,0 +1,110 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.wsdm.capabilities;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObject;
+import org.w3c.dom.Element;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for Resource Metadata Descriptor Builder.
+ *
+ * @author Andrea Gazzarini
+ */
+public class RmdBuilderTest extends TestCase
+{
+ private MBeanInfo _metadata;
+ private RmdBuilder _builder;
+ private ObjectName _objectName;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+ _objectName = new ObjectName("Test:Name=QpidDomainObject");
+
+ server.registerMBean(new QpidDomainObject(), _objectName);
+ _metadata = server.getMBeanInfo(_objectName);
+
+ _builder = new RmdBuilder();
+ _builder.begin(_objectName);
+
+ assertEquals(_objectName,_builder._objectName);
+ }
+
+ /**
+ * Tests the execution of the onOperation() method.
+ */
+ public void testOnOperation() throws Exception
+ {
+ MBeanAttributeInfo [] attributes = _metadata.getAttributes();
+ for (MBeanAttributeInfo attribute : attributes)
+ {
+ _builder.onAttribute(attribute);
+ }
+
+ Element [] rmd = _builder.getResourceMetadataDescriptor();
+
+ assertEquals(attributes.length,rmd.length);
+
+ for (MBeanAttributeInfo attribute: _metadata.getAttributes())
+ {
+ Element propertyMetadataDescriptor = getPropertyMetadatDescriptor(attribute.getName(), rmd);
+
+ String modifiability = propertyMetadataDescriptor.getAttribute(Names.MODIFIABILITY);
+ String expectedValue =
+ attribute.isWritable()
+ ? Names.READ_WRITE
+ : Names.READ_ONLY;
+ assertEquals(expectedValue,modifiability);
+ }
+ }
+
+ /**
+ * Returns the property metadata descriptor associated with the given attribute name.
+ *
+ * @param name the attribute name.
+ * @param rmd the resource metadata descriptor.
+ * @return the property metadata descriptor associated with the given attribute name.
+ * @throws RuntimeException if metadata for the given attribute is not found.
+ */
+ private Element getPropertyMetadatDescriptor(String name, Element [] rmd)
+ {
+ for (Element propertyMetadataDescriptor : rmd)
+ {
+ if ((Names.PREFIX+":"+name).equals(
+ propertyMetadataDescriptor.getAttribute(Names.NAME_ATTRIBUTE)))
+ {
+ return propertyMetadataDescriptor;
+ }
+ }
+ throw new RuntimeException("Property MetadataDescriptor not found for attribute "+name);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/web.xml b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/web.xml
new file mode 100644
index 0000000000..df273bd841
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/web.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+ <servlet>
+ <display-name>Qpid emulator startip</display-name>
+ <servlet-name>QEmu</servlet-name>
+ <servlet-class>org.apache.qpid.management.wsdm.QEmuInitializer</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+</web-app>
diff --git a/qpid/java/management/client/web.xml b/qpid/java/management/client/web.xml
new file mode 100644
index 0000000000..881fc82f46
--- /dev/null
+++ b/qpid/java/management/client/web.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<web-app id="qman" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+ <description>
+ Q-Man is a Management bridge that exposes one (or several) Qpid
+ broker domain model as MBeans that are accessible through the
+ Java Management Extensions (JMX) and / or WS-DM.
+ </description>
+ <display-name>QManEE</display-name>
+ <listener>
+ <description>
+ Provides lifecycle management for QMan module.
+ </description>
+ <display-name>QMan Lifecycle manager</display-name>
+ <listener-class>org.apache.qpid.management.servlet.QManLifeCycleManager</listener-class>
+ </listener>
+ <servlet>
+ <display-name>QMan Proxy Servlet</display-name>
+ <servlet-name>Proxy</servlet-name>
+ <servlet-class>org.apache.qpid.management.servlet.WSDMAdapter</servlet-class>
+ <load-on-startup>2</load-on-startup>
+ </servlet>
+ <servlet>
+ <display-name>View Console (System Overview) Action</display-name>
+ <servlet-name>ViewConsole</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.ConsoleAction</servlet-class>
+ <load-on-startup>5</load-on-startup>
+ </servlet>
+ <servlet>
+ <display-name>View Resources</display-name>
+ <servlet-name>ResourceManagement</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.ResourcesManagementAction</servlet-class>
+ </servlet>
+ <servlet>
+ <display-name>JMX Perspective</display-name>
+ <servlet-name>JmxPerspective</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.JmxPerspectiveAction</servlet-class>
+ </servlet>
+ <servlet>
+ <display-name>WSDM Properties Perspective</display-name>
+ <servlet-name>WsdmPropertiesPerspective</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.WsdmPropertiesPerspectiveAction</servlet-class>
+ </servlet>
+ <servlet>
+ <display-name>WSDM Operations Perspective</display-name>
+ <servlet-name>WsdmOperationsPerspective</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.WsdmOperationsPerspectiveAction</servlet-class>
+ </servlet>
+ <servlet>
+ <display-name>WSDM WSDL Perspective</display-name>
+ <servlet-name>WsdmWsdlPerspective</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.WsdmWsdlPerspectiveAction</servlet-class>
+ </servlet>
+ <servlet>
+ <display-name>WSDM RMD Perspective</display-name>
+ <servlet-name>WsdmRmdPerspective</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.WsdmRmdPerspectiveAction</servlet-class>
+ </servlet>
+ <servlet>
+ <display-name>Logging Configurator</display-name>
+ <servlet-name>LoggingConfiguration</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.LoggingConfigurationAction</servlet-class>
+ </servlet>
+ <servlet>
+ <display-name>Brokers Management</display-name>
+ <servlet-name>BrokersManagement</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.BrokersManagementAction</servlet-class>
+ </servlet>
+ <servlet>
+ <description>
+ Connects QMAn to one or more brokers depending from what is
+ specified on the given (via system property) configuration
+ file.
+ </description>
+ <display-name>Connect QMan to Broker</display-name>
+ <servlet-name>ConnectQManToBroker</servlet-name>
+ <servlet-class>org.apache.qpid.management.servlet.ConnectQManToBroker</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>ResourceManagement</servlet-name>
+ <url-pattern>/resources_management</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>WsdmWsdlPerspective</servlet-name>
+ <url-pattern>/wsdm_wsdl_perspective</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>WsdmRmdPerspective</servlet-name>
+ <url-pattern>/wsdm_rmd_perspective</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>WsdmOperationsPerspective</servlet-name>
+ <url-pattern>/wsdm_operations_perspective</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>WsdmPropertiesPerspective</servlet-name>
+ <url-pattern>/wsdm_properties_perspective</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>BrokersManagement</servlet-name>
+ <url-pattern>/brokers_management</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>JmxPerspective</servlet-name>
+ <url-pattern>/jmx_perspective</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>LoggingConfiguration</servlet-name>
+ <url-pattern>/logging_configuration</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>ViewConsole</servlet-name>
+ <url-pattern>/console</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>ConnectQManToBroker</servlet-name>
+ <url-pattern>/test/*</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>Proxy</servlet-name>
+ <url-pattern>/services/*</url-pattern>
+ </servlet-mapping>
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ </login-config>
+</web-app>
diff --git a/qpid/java/management/common/src/main/java/management-common.bnd b/qpid/java/management/common/src/main/java/management-common.bnd
index 5c39329f2f..cb28d309a6 100644
--- a/qpid/java/management/common/src/main/java/management-common.bnd
+++ b/qpid/java/management/common/src/main/java/management-common.bnd
@@ -17,7 +17,7 @@
# under the License.
#
-ver: 0.13.0
+ver: 0.9.0
Bundle-SymbolicName: qpid-management-common
Bundle-Version: ${ver}
diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedBroker.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedBroker.java
index b5c80a4fed..c0e7293611 100644
--- a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedBroker.java
+++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedBroker.java
@@ -36,8 +36,8 @@ import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParame
* The ManagedBroker is the management interface to expose management
* features of the Broker.
*
- * @version Qpid JMX API 2.2
- * @since Qpid JMX API 1.3
+ * @author Bhupendra Bhardwaj
+ * @version 0.1
*/
public interface ManagedBroker
{
@@ -131,118 +131,4 @@ public interface ManagedBroker
impact= MBeanOperationInfo.ACTION)
void deleteQueue(@MBeanOperationParameter(name= ManagedQueue.TYPE, description="Queue Name")String queueName)
throws IOException, JMException, MBeanException;
-
- /**
- * Resets all message and data statistics for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanOperation(name="resetStatistics",
- description="Resets all message and data statistics for the virtual host",
- impact= MBeanOperationInfo.ACTION)
- void resetStatistics() throws Exception;
-
- /**
- * Peak rate of messages delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakMessageDeliveryRate", description=TYPE + " Peak Message Delivery Rate")
- double getPeakMessageDeliveryRate();
-
- /**
- * Peak rate of bytes delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakDataDeliveryRate", description=TYPE + " Peak Data Delivery Rate")
- double getPeakDataDeliveryRate();
-
- /**
- * Rate of messages delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="MessageDeliveryRate", description=TYPE + " Message Delivery Rate")
- double getMessageDeliveryRate();
-
- /**
- * Rate of bytes delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="DataDeliveryRate", description=TYPE + " Data Delivery Rate")
- double getDataDeliveryRate();
-
- /**
- * Total count of messages delivered for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalMessagesDelivered", description=TYPE + " Total Messages Delivered")
- long getTotalMessagesDelivered();
-
- /**
- * Total count of bytes for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalDataDelivered", description=TYPE + " Total Data Delivered")
- long getTotalDataDelivered();
-
- /**
- * Peak rate of messages received per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakMessageReceiptRate", description=TYPE + " Peak Message Receipt Rate")
- double getPeakMessageReceiptRate();
-
- /**
- * Peak rate of bytes received per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakDataReceiptRate", description=TYPE + " Peak Data Receipt Rate")
- double getPeakDataReceiptRate();
-
- /**
- * Rate of messages received per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="MessageReceiptRate", description=TYPE + " Message Receipt Rate")
- double getMessageReceiptRate();
-
- /**
- * Rate of bytes received per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="DataReceiptRate", description=TYPE + " Data Receipt Rate")
- double getDataReceiptRate();
-
- /**
- * Total count of messages received for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalMessagesReceived", description=TYPE + " Total Messages Received")
- long getTotalMessagesReceived();
-
- /**
- * Total count of bytes received for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalDataReceived", description=TYPE + " Total Data Received")
- long getTotalDataReceived();
-
- /**
- * Is statistics collection enabled for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="StatisticsEnabled", description=TYPE + " Statistics Enabled")
- boolean isStatisticsEnabled();
}
diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedConnection.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedConnection.java
index d16db65d5d..d6b79d1dde 100644
--- a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedConnection.java
+++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedConnection.java
@@ -37,9 +37,8 @@ import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParame
/**
* The management interface exposed to allow management of Connections.
- *
- * @version Qpid JMX API 2.2
- * @since Qpid JMX API 1.3
+ * @author Bhupendra Bhardwaj
+ * @version 0.1
*/
public interface ManagedConnection
{
@@ -146,126 +145,4 @@ public interface ManagedConnection
description="Closes this connection and all related channels",
impact= MBeanOperationInfo.ACTION)
void closeConnection() throws Exception;
-
- /**
- * Resets message and data statistics for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanOperation(name="resetStatistics",
- description="Resets message and data statistics for this connection",
- impact= MBeanOperationInfo.ACTION)
- void resetStatistics() throws Exception;
-
- /**
- * Peak rate of messages delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakMessageDeliveryRate", description=TYPE + " Peak Message Delivery Rate")
- double getPeakMessageDeliveryRate();
-
- /**
- * Peak rate of bytes delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakDataDeliveryRate", description=TYPE + " Peak Data Delivery Rate")
- double getPeakDataDeliveryRate();
-
- /**
- * Rate of messages delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="MessageDeliveryRate", description=TYPE + " Message Delivery Rate")
- double getMessageDeliveryRate();
-
- /**
- * Rate of bytes delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="DataDeliveryRate", description=TYPE + " Data Delivery Rate")
- double getDataDeliveryRate();
-
- /**
- * Total count of messages delivered for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalMessagesDelivered", description=TYPE + " Total Messages Delivered")
- long getTotalMessagesDelivered();
-
- /**
- * Total count of bytes for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalDataDelivered", description=TYPE + " Total Data Delivered")
- long getTotalDataDelivered();
-
- /**
- * Peak rate of messages received per second for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakMessageReceiptRate", description=TYPE + " Peak Message Receipt Rate")
- double getPeakMessageReceiptRate();
-
- /**
- * Peak rate of bytes received per second for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakDataReceiptRate", description=TYPE + " Peak Data Receipt Rate")
- double getPeakDataReceiptRate();
-
- /**
- * Rate of messages received per second for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="MessageReceiptRate", description=TYPE + " Message Receipt Rate")
- double getMessageReceiptRate();
-
- /**
- * Rate of bytes received per second for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="DataReceiptRate", description=TYPE + " Data Receipt Rate")
- double getDataReceiptRate();
-
- /**
- * Total count of messages received for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalMessagesReceived", description=TYPE + " Total Messages Received")
- long getTotalMessagesReceived();
-
- /**
- * Total count of bytes received for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalDataReceived", description=TYPE + " Total Data Received")
- long getTotalDataReceived();
-
- /**
- * Is statistics collection enabled for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="StatisticsEnabled", description=TYPE + " Statistics Enabled")
- boolean isStatisticsEnabled();
-
- /**
- * Sets statistics collection enabled/disabled for this connection.
- *
- * @param enabled
- * @since Qpid JMX API 2.2
- */
- void setStatisticsEnabled(boolean enabled);
}
diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ServerInformation.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ServerInformation.java
index 12ae69571e..618403fdca 100644
--- a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ServerInformation.java
+++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ServerInformation.java
@@ -22,15 +22,10 @@ package org.apache.qpid.management.common.mbeans;
import java.io.IOException;
-import javax.management.MBeanOperationInfo;
-
import org.apache.qpid.management.common.mbeans.annotations.MBeanAttribute;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation;
/**
* Interface for the ServerInformation MBean
- *
- * @version Qpid JMX API 2.3
* @since Qpid JMX API 1.3
*/
public interface ServerInformation
@@ -47,7 +42,7 @@ public interface ServerInformation
* Qpid JMX API 1.1 can be assumed.
*/
int QPID_JMX_API_MAJOR_VERSION = 2;
- int QPID_JMX_API_MINOR_VERSION = 3;
+ int QPID_JMX_API_MINOR_VERSION = 0;
/**
@@ -85,118 +80,4 @@ public interface ServerInformation
@MBeanAttribute(name="ProductVersion",
description = "The product version string")
String getProductVersion() throws IOException;
-
- /**
- * Resets all message and data statistics for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanOperation(name="resetStatistics",
- description="Resets all message and data statistics for the broker",
- impact= MBeanOperationInfo.ACTION)
- void resetStatistics() throws Exception;
-
- /**
- * Peak rate of messages delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakMessageDeliveryRate", description=TYPE + " Peak Message Delivery Rate")
- double getPeakMessageDeliveryRate();
-
- /**
- * Peak rate of bytes delivered per second for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakDataDeliveryRate", description=TYPE + " Peak Data Delivery Rate")
- double getPeakDataDeliveryRate();
-
- /**
- * Rate of messages delivered per second for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="MessageDeliveryRate", description=TYPE + " Message Delivery Rate")
- double getMessageDeliveryRate();
-
- /**
- * Rate of bytes delivered per second for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="DataDeliveryRate", description=TYPE + " Data Delivery Rate")
- double getDataDeliveryRate();
-
- /**
- * Total count of messages delivered for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalMessagesDelivered", description=TYPE + " Total Messages Delivered")
- long getTotalMessagesDelivered();
-
- /**
- * Total count of bytes for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalDataDelivered", description=TYPE + " Total Data Delivered")
- long getTotalDataDelivered();
-
- /**
- * Peak rate of messages received per second for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakMessageReceiptRate", description=TYPE + " Peak Message Receipt Rate")
- double getPeakMessageReceiptRate();
-
- /**
- * Peak rate of bytes received per second for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakDataReceiptRate", description=TYPE + " Peak Data Receipt Rate")
- double getPeakDataReceiptRate();
-
- /**
- * Rate of messages received per second for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="MessageReceiptRate", description=TYPE + " Message Receipt Rate")
- double getMessageReceiptRate();
-
- /**
- * Rate of bytes received per second for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="DataReceiptRate", description=TYPE + " Data Receipt Rate")
- double getDataReceiptRate();
-
- /**
- * Total count of messages received for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalMessagesReceived", description=TYPE + " Total Messages Received")
- long getTotalMessagesReceived();
-
- /**
- * Total count of bytes received for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalDataReceived", description=TYPE + " Total Data Received")
- long getTotalDataReceived();
-
- /**
- * Is statistics collection enabled for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="StatisticsEnabled", description=TYPE + " Statistics Enabled")
- boolean isStatisticsEnabled();
}
diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/UserManagement.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/UserManagement.java
index 1a82c58ee9..2bd00d5802 100644
--- a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/UserManagement.java
+++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/UserManagement.java
@@ -38,21 +38,38 @@ public interface UserManagement
//TabularType and contained CompositeType key/description information.
//For compatibility reasons, DONT MODIFY the existing key values if expanding the set.
String USERNAME = "Username";
- String RIGHTS_READ_ONLY = "read"; // item deprecated
- String RIGHTS_READ_WRITE = "write"; // item deprecated
- String RIGHTS_ADMIN = "admin"; // item deprecated
-
+ String RIGHTS_READ_ONLY = "read";
+ String RIGHTS_READ_WRITE = "write";
+ String RIGHTS_ADMIN = "admin";
List<String> COMPOSITE_ITEM_NAMES = Collections.unmodifiableList(Arrays.asList(USERNAME, RIGHTS_READ_ONLY, RIGHTS_READ_WRITE, RIGHTS_ADMIN));
List<String> COMPOSITE_ITEM_DESCRIPTIONS = Collections.unmodifiableList(
Arrays.asList("Broker Login username",
- "Item no longer used",
- "Item no longer used",
- "Item no longer used"));
-
+ "Management Console Read Permission",
+ "Management Console Write Permission",
+ "Management Console Admin Permission"));
List<String> TABULAR_UNIQUE_INDEX = Collections.unmodifiableList(Arrays.asList(USERNAME));
//********** Operations *****************//
/**
+ * set password for user.
+ *
+ * Since Qpid JMX API 1.2 this operation expects plain text passwords to be provided. Prior to this, MD5 hashed passwords were supplied.
+ *
+ * @deprecated since Qpid JMX API 1.7
+ *
+ * @param username The username to create
+ * @param password The password for the user
+ *
+ * @return The result of the operation
+ */
+ @Deprecated
+ @MBeanOperation(name = "setPassword", description = "Set password for user.",
+ impact = MBeanOperationInfo.ACTION)
+ boolean setPassword(@MBeanOperationParameter(name = "username", description = "Username")String username,
+ //NOTE: parameter name was changed to 'passwd' in Qpid JMX API 1.7 to protect against older, incompatible management clients
+ @MBeanOperationParameter(name = "passwd", description = "Password")char[] password);
+
+ /**
* Set password for a given user.
*
* @since Qpid JMX API 1.7
@@ -66,21 +83,69 @@ public interface UserManagement
impact = MBeanOperationInfo.ACTION)
boolean setPassword(@MBeanOperationParameter(name = "username", description = "Username")String username,
@MBeanOperationParameter(name = "password", description = "Password")String password);
+
+ /**
+ * set rights for users with given details
+ *
+ * @param username The username to create
+ * @param read The set of permission to give the new user
+ * @param write The set of permission to give the new user
+ * @param admin The set of permission to give the new user
+ *
+ * @return The result of the operation
+ */
+ @MBeanOperation(name = "setRights", description = "Set access rights for user.",
+ impact = MBeanOperationInfo.ACTION)
+ boolean setRights(@MBeanOperationParameter(name = "username", description = "Username")String username,
+ @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
+ @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write,
+ @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin);
+
+ /**
+ * Create users with given details
+ *
+ * Since Qpid JMX API 1.2 this operation expects plain text passwords to be provided. Prior to this, MD5 hashed passwords were supplied.
+ *
+ * @deprecated since Qpid JMX API 1.7
+ *
+ * @param username The username to create
+ * @param password The password for the user
+ * @param read The set of permission to give the new user
+ * @param write The set of permission to give the new user
+ * @param admin The set of permission to give the new user
+ *
+ * @return The result of the operation
+ */
+ @Deprecated
+ @MBeanOperation(name = "createUser", description = "Create new user from system.",
+ impact = MBeanOperationInfo.ACTION)
+ boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username,
+ //NOTE: parameter name was changed to 'passwd' in Qpid JMX API 1.7 to protect against older, incompatible management clients
+ @MBeanOperationParameter(name = "passwd", description = "Password")char[] password,
+ @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
+ @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write,
+ @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin);
/**
* Create users with given details.
*
- * @since Qpid JMX API 2.3 / 1.12
+ * @since Qpid JMX API 1.7
*
* @param username The username to create
* @param password The password for the user
+ * @param read The set of permission to give the new user
+ * @param write The set of permission to give the new user
+ * @param admin The set of permission to give the new user
*
- * @return true if the user was created successfully, or false otherwise
+ * @return The result of the operation
*/
@MBeanOperation(name = "createUser", description = "Create a new user.",
impact = MBeanOperationInfo.ACTION)
boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username,
- @MBeanOperationParameter(name = "password", description = "Password")String password);
+ @MBeanOperationParameter(name = "password", description = "Password")String password,
+ @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
+ @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write,
+ @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin);
/**
* View users returns all the users that are currently available to the system.
@@ -95,11 +160,9 @@ public interface UserManagement
/**
- * Reload the user data
+ * Reload the date from disk
*
- * Since Qpid JMX API 2.3 / 1.12 this operation reloads only the password data.
- * Since Qpid JMX API 1.2 but prior to 2.3 / 1.12 this operation reloads the password and authorisation files.
- * Prior to 1.2, only the authorisation file was reloaded.
+ * Since Qpid JMX API 1.2 this operation reloads the password and authorisation files. Prior to this, only the authorisation file was reloaded.
*
* @return The result of the operation
*/
@@ -109,13 +172,10 @@ public interface UserManagement
/**
* View users returns all the users that are currently available to the system.
- *
- * Since Qpid JMX API 2.3 / 1.12 the items that corresponded to read, write and admin flags
- * are deprecated and always return false.
*
* @return a table of users data (Username, read, write, admin)
*/
- @MBeanOperation(name = "viewUsers", description = "All users that are currently available to the system.",
+ @MBeanOperation(name = "viewUsers", description = "All users with access rights to the system.",
impact = MBeanOperationInfo.INFO)
TabularData viewUsers();
diff --git a/qpid/java/management/console/build.xml b/qpid/java/management/console/build.xml
new file mode 100644
index 0000000000..8f23030b44
--- /dev/null
+++ b/qpid/java/management/console/build.xml
@@ -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.
+ -
+ -->
+<project name="QMF Console" default="build">
+
+ <property name="module.depends" value="common client"/>
+
+ <import file="../../module.xml"/>
+
+</project>
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/AbstractConsole.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/AbstractConsole.java
new file mode 100644
index 0000000000..d95003b1cc
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/AbstractConsole.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.console;
+
+public class AbstractConsole implements Console
+{
+ public AbstractConsole()
+ {
+ }
+
+ public void agentRemoved(Agent agent)
+ {
+ }
+
+ public void brokerConnected(Broker broker)
+ {
+ }
+
+ public void brokerDisconnected(Broker broker)
+ {
+ }
+
+ public void brokerInformation(Broker broker)
+ {
+ }
+
+ public void eventRecieved(Broker broker, QMFEvent anEvent)
+ {
+ }
+
+ public void hearbeatRecieved(Agent agent, long timestamp)
+ {
+ }
+
+ public void methodResponse(Broker broker, long seq, MethodResult response)
+ {
+ }
+
+ public void newAgent(Agent agent)
+ {
+ }
+
+ public void newClass(short kind, ClassKey key)
+ {
+ }
+
+ public void newPackage(String packageName)
+ {
+ }
+
+ public void objectProperties(Broker broker, QMFObject obj)
+ {
+ }
+
+ public void objectStatistics(Broker broker, QMFObject obj)
+ {
+ }
+
+ public Class typeMapping(ClassKey key)
+ {
+ return QMFObject.class;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/Agent.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Agent.java
new file mode 100644
index 0000000000..e1887d82ea
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Agent.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.console;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Agent
+{
+ private static Logger log = LoggerFactory.getLogger(Agent.class);
+
+ public static String AgentKey(long AgentBank, long BrokerBank)
+ {
+ return String.format("%s:%s", AgentBank, BrokerBank);
+ }
+
+ public static long getAgentBank(String routingKey)
+ {
+ String delim = ".";
+ return Long.parseLong(routingKey.split(java.util.regex.Pattern
+ .quote(delim))[3]);
+ }
+
+ public static long getBrokerBank(String routingKey)
+ {
+ String delim = ".";
+ return Long.parseLong(routingKey.split(java.util.regex.Pattern
+ .quote(delim))[2]);
+ }
+
+ public static String routingCode(long AgentBank, long BrokerBank)
+ {
+ return String.format("agent.%s.%s", BrokerBank, AgentBank);
+ }
+
+ private long agentBank;
+ private Broker broker;
+ private long brokerBank;
+ private String label;
+
+ public Agent(Broker broker, long agentBank, String label)
+ {
+ this.setBroker(broker);
+ this.setBrokerBank(broker.brokerBank());
+ this.setAgentBank(agentBank);
+ this.setlabel(label);
+ }
+
+ public final String agentKey()
+ {
+ return Agent.AgentKey(getAgentBank(), getBrokerBank());
+ }
+
+ public final long getAgentBank()
+ {
+ return agentBank;
+ }
+
+ public final Broker getBroker()
+ {
+ return broker;
+ }
+
+ public final long getBrokerBank()
+ {
+ return brokerBank;
+ }
+
+ public final String getlabel()
+ {
+ return label;
+ }
+
+ public final String routingCode()
+ {
+ return Agent.routingCode(getAgentBank(), getBrokerBank());
+ }
+
+ public final void setAgentBank(long value)
+ {
+ agentBank = value;
+ }
+
+ public final void setBroker(Broker value)
+ {
+ broker = value;
+ }
+
+ public final void setBrokerBank(long value)
+ {
+ brokerBank = value;
+ }
+
+ public final void setlabel(String value)
+ {
+ label = value;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/Broker.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Broker.java
new file mode 100644
index 0000000000..16c77449f1
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Broker.java
@@ -0,0 +1,504 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.console;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.UUID;
+
+import javax.jms.BytesMessage;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Broker implements MessageListener
+{
+ class HeaderInfo
+ {
+ boolean valid;
+ long sequence;
+ char opcode;
+
+ public String toString()
+ {
+ return String.format("%s Header with opcode %s and sequence %s",
+ (valid ? "Valid" : "Invalid"), opcode, sequence);
+ }
+ }
+
+ private static Logger log = LoggerFactory.getLogger(Broker.class);
+ public static final int SYNC_TIME = 60000;
+ // JMS Stuff
+ private javax.jms.Session session;
+ boolean sessionTransacted = false;
+ private String replyName;
+ private String topicName;
+ private MessageProducer prod;
+ private ArrayList<MessageConsumer> consumers = new ArrayList<MessageConsumer>();
+ private Queue reply;
+ private Queue topic;
+ private int acknowledgeMode = javax.jms.Session.AUTO_ACKNOWLEDGE;
+ // QMF Stuff
+ AMQConnection connection;
+ public String url;
+ public java.util.HashMap<String, Agent> Agents = new java.util.HashMap<String, Agent>();
+ private Session consoleSession;
+ private boolean connected = false;
+ private boolean syncInFlight = false;
+ private boolean topicBound = false;
+ private int reqsOutstanding = 0;
+ private Object lockObject = new Object();
+ UUID brokerId = UUID.randomUUID();
+
+ public Broker(org.apache.qpid.console.Session session, String url)
+ {
+ log.debug("Creating a new Broker for url " + url);
+ this.url = url;
+ consoleSession = session;
+ this.tryToConnect();
+ }
+
+ public int brokerBank()
+ {
+ return 1;
+ }
+
+ protected HeaderInfo CheckHeader(Decoder decoder)
+ {
+ HeaderInfo returnValue = new HeaderInfo();
+ returnValue.opcode = 'x';
+ returnValue.sequence = -1;
+ returnValue.valid = false;
+ if (decoder.hasRemaining())
+ {
+ char character = (char) decoder.readUint8();
+ if (character != 'A')
+ {
+ return returnValue;
+ }
+ character = (char) decoder.readUint8();
+ if (character != 'M')
+ {
+ return returnValue;
+ }
+ character = (char) decoder.readUint8();
+ if (character != '2')
+ {
+ return returnValue;
+ }
+ returnValue.valid = true;
+ returnValue.opcode = (char) decoder.readUint8();
+ returnValue.sequence = decoder.readUint32();
+ }
+ return returnValue;
+ }
+
+ public Encoder createEncoder(char opcode, long sequence)
+ {
+ return setHeader(new BBEncoder(1024), opcode, sequence);
+ }
+
+ public Message createMessage(Encoder enc)
+ {
+ try
+ {
+ byte[] buf = new byte[1024];
+ BBEncoder bbenc = (BBEncoder) enc;
+ BytesMessage msg = session.createBytesMessage();
+ ByteBuffer slice = bbenc.buffer();
+ while (slice.hasRemaining())
+ {
+ int n = Math.min(buf.length, slice.remaining());
+ slice.get(buf, 0, n);
+ msg.writeBytes(buf, 0, n);
+ }
+ return msg;
+ } catch (JMSException e)
+ {
+ throw new ConsoleException(e);
+ }
+ }
+
+ public void decrementOutstanding()
+ {
+ synchronized (lockObject)
+ {
+ this.reqsOutstanding -= 1;
+ if ((reqsOutstanding == 0) & !topicBound)
+ {
+ for (String key : consoleSession.bindingKeys())
+ {
+ try
+ {
+ // this.clientSession.exchangeBind(topicName,
+ // "qpid.mannagement", key) ;
+ log.debug("Setting Topic Binding " + key);
+ // topicName = "management://qpid.management//" + key;
+ String rk = String.format("&routingkey='%s'", key);
+ Queue aQueue = session.createQueue(topicName + rk);
+ MessageConsumer cons = session.createConsumer(aQueue);
+ cons.setMessageListener(this);
+ consumers.add(cons);
+ } catch (JMSException e)
+ {
+ throw new ConsoleException(e);
+ }
+ }
+ topicBound = true;
+ }
+ if ((reqsOutstanding == 0) & syncInFlight)
+ {
+ syncInFlight = false;
+ lockObject.notifyAll();
+ }
+ }
+ }
+
+ private byte[] ensure(int capacity, byte[] body, int size)
+ {
+ if (capacity > body.length)
+ {
+ byte[] copy = new byte[capacity];
+ System.arraycopy(body, 0, copy, 0, size);
+ body = copy;
+ }
+ return body;
+ }
+
+ protected void finalize()
+ {
+ if (connected)
+ {
+ this.shutdown();
+ }
+ }
+
+ public boolean getSyncInFlight()
+ {
+ return syncInFlight;
+ }
+
+ public void incrementOutstanding()
+ {
+ synchronized (lockObject)
+ {
+ this.reqsOutstanding += 1;
+ }
+ }
+
+ public boolean isConnected()
+ {
+ return connected;
+ }
+
+ public void onMessage(Message msg)
+ {
+ Decoder decoder = readBody(msg);
+ HeaderInfo headerInfo = this.CheckHeader(decoder);
+ // log.debug(headerInfo.toString());
+ while (headerInfo.valid)
+ {
+ long seq = headerInfo.sequence;
+ switch (headerInfo.opcode)
+ {
+ case 'b':
+ consoleSession.handleBrokerResponse(this, decoder, seq);
+ break;
+ case 'p':
+ consoleSession.handlePackageIndicator(this, decoder, seq);
+ break;
+ case 'z':
+ consoleSession.handleCommandComplete(this, decoder, seq);
+ break;
+ case 'q':
+ consoleSession.handleClassIndicator(this, decoder, seq);
+ break;
+ case 'm':
+ consoleSession.handleMethodResponse(this, decoder, seq);
+ break;
+ case 'h':
+ consoleSession
+ .handleHeartbeatIndicator(this, decoder, seq, msg);
+ break;
+ case 'e':
+ consoleSession.handleEventIndicator(this, decoder, seq);
+ break;
+ case 's':
+ consoleSession.handleSchemaResponse(this, decoder, seq);
+ break;
+ case 'c':
+ consoleSession.handleContentIndicator(this, decoder, seq, true,
+ false);
+ break;
+ case 'i':
+ consoleSession.handleContentIndicator(this, decoder, seq,
+ false, true);
+ break;
+ case 'g':
+ consoleSession.handleContentIndicator(this, decoder, seq, true,
+ true);
+ break;
+ default:
+ log.error("Invalid message type recieved with opcode "
+ + headerInfo.opcode);
+ break;
+ }
+ headerInfo = this.CheckHeader(decoder);
+ }
+ }
+
+ private Decoder readBody(Message message)
+ {
+ BytesMessage msg = (BytesMessage) message;
+ BBDecoder dec = new BBDecoder();
+ byte[] buf = new byte[1024];
+ byte[] body = new byte[1024];
+ int size = 0;
+ int n;
+ try
+ {
+ while ((n = msg.readBytes(buf)) > 0)
+ {
+ body = ensure(size + n, body, size);
+ System.arraycopy(buf, 0, body, size, n);
+ size += n;
+ }
+ } catch (JMSException e)
+ {
+ throw new ConsoleException(e);
+ }
+ dec.init(ByteBuffer.wrap(body, 0, size));
+ return dec;
+ }
+
+ public void send(Encoder enc)
+ {
+ this.send(this.createMessage(enc), "broker");
+ }
+
+ public void send(Message msg)
+ {
+ this.send(msg, "broker", -1);
+ }
+
+ public void send(Message msg, String routingKey)
+ {
+ this.send(msg, routingKey, -1);
+ }
+
+ public void send(Message msg, String routingKey, int ttl)
+ {
+ synchronized (lockObject)
+ {
+ try
+ {
+ log.debug(String.format("Sending message to routing key '%s'",
+ routingKey));
+ String destName = String.format(
+ "management://qpid.management//?routingkey='%s'",
+ routingKey);
+ log.debug(destName);
+ Queue dest = session.createQueue(destName);
+ // Queue jmsReply = session
+ // createQueue("direct://amq.direct//?routingkey='reply-"
+ // + brokerId + "'");
+ if (ttl != -1)
+ {
+ msg.setJMSExpiration(ttl);
+ }
+ msg.setJMSReplyTo(reply);
+ prod.send(dest, msg);
+ } catch (Exception e)
+ {
+ throw new ConsoleException(e);
+ }
+ }
+ }
+
+ protected Encoder setHeader(Encoder enc, char opcode, long sequence)
+ {
+ enc.writeUint8((short) 'A');
+ enc.writeUint8((short) 'M');
+ enc.writeUint8((short) '2');
+ enc.writeUint8((short) opcode);
+ enc.writeUint32(sequence);
+ return enc;
+ }
+
+ public void setSyncInFlight(boolean inFlight)
+ {
+ synchronized (lockObject)
+ {
+ syncInFlight = inFlight;
+ lockObject.notifyAll();
+ }
+ }
+
+ public void shutdown()
+ {
+ if (connected)
+ {
+ this.waitForStable();
+ try
+ {
+ session.close();
+ for (MessageConsumer cons : consumers)
+ {
+ cons.close();
+ }
+ connection.close();
+ } catch (Exception e)
+ {
+ throw new ConsoleException(e);
+ } finally
+ {
+ this.connected = false;
+ }
+ }
+ }
+
+ protected void tryToConnect()
+ {
+ try
+ {
+ reqsOutstanding = 1;
+ Agent newAgent = new Agent(this, 0, "BrokerAgent");
+ Agents.put(newAgent.agentKey(), newAgent);
+ connection = new AMQConnection(url);
+ session = connection.createSession(sessionTransacted,
+ acknowledgeMode);
+ replyName = String
+ .format(
+ "direct://amq.direct//reply-%s?exclusive='True'&autodelete='True'",
+ brokerId);
+ topicName = String
+ .format(
+ "management://qpid.management//topic-%s?exclusive='True'&autodelete='True'",
+ brokerId);
+ reply = session.createQueue(replyName);
+ MessageConsumer cons = session.createConsumer(reply);
+ cons.setMessageListener(this);
+ consumers.add(cons);
+ prod = session.createProducer(null);
+ topic = session.createQueue(topicName);
+ cons = session.createConsumer(topic);
+ cons.setMessageListener(this);
+ consumers.add(cons);
+ connection.start();
+ // Rest of the topic is bound later. Start er up
+ } catch (Exception e)
+ {
+ throw new ConsoleException(e);
+ }
+ connected = true;
+ consoleSession.handleBrokerConnect(this);
+ Encoder Encoder = createEncoder('B', 0);
+ this.send(Encoder);
+ }
+
+ public void updateAgent(QMFObject obj)
+ {
+ long agentBank = (Long) obj.getProperty("agentBank");
+ long brokerBank = (Long) obj.getProperty("brokerBank");
+ String key = Agent.AgentKey(agentBank, brokerBank);
+ if (obj.isDeleted())
+ {
+ if (Agents.containsKey(key))
+ {
+ Agent agent = Agents.get(key);
+ Agents.remove(key);
+ consoleSession.handleAgentRemoved(agent);
+ }
+ } else
+ {
+ if (!Agents.containsKey(key))
+ {
+ Agent newAgent = new Agent(this, agentBank, (String) obj
+ .getProperty("label"));
+ Agents.put(key, newAgent);
+ consoleSession.handleNewAgent(newAgent);
+ }
+ }
+ }
+
+ public void waitForStable()
+ {
+ synchronized (lockObject)
+ {
+ if (connected)
+ {
+ long start = System.currentTimeMillis();
+ syncInFlight = true;
+ while (reqsOutstanding != 0)
+ {
+ log.debug("Waiting to recieve messages");
+ try
+ {
+ lockObject.wait(SYNC_TIME);
+ } catch (Exception e)
+ {
+ throw new ConsoleException(e);
+ }
+ long duration = System.currentTimeMillis() - start;
+ if (duration > SYNC_TIME)
+ {
+ throw new ConsoleException(
+ "Timeout waiting for Broker to Sync");
+ }
+ }
+ }
+ }
+ }
+
+ public void waitForSync(int timeout)
+ {
+ synchronized (lockObject)
+ {
+ long start = System.currentTimeMillis();
+ while (syncInFlight)
+ {
+ try
+ {
+ lockObject.wait(SYNC_TIME);
+ } catch (Exception e)
+ {
+ throw new ConsoleException(e);
+ }
+ }
+ long duration = System.currentTimeMillis() - start;
+ if (duration > timeout)
+ {
+ throw new ConsoleException("Timeout waiting for Broker to Sync");
+ }
+ }
+ }
+}
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/ClassKey.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/ClassKey.java
new file mode 100644
index 0000000000..1fbf4c7f3d
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/ClassKey.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.console;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ClassKey
+{
+ private static final Logger log = LoggerFactory.getLogger(ClassKey.class);
+ private String packageName;
+ private String className;
+ private long[] hash = new long[4];
+
+ public ClassKey(Decoder dec)
+ {
+ setPackageName(dec.readStr8());
+ setClassName(dec.readStr8());
+ hash[0] = dec.readUint32();
+ hash[1] = dec.readUint32();
+ hash[2] = dec.readUint32();
+ hash[3] = dec.readUint32();
+ }
+
+ public ClassKey(String keyString)
+ {
+ String delims = "[*:*(*)]";
+ String[] parts = keyString.split(delims);
+ if (parts.length < 3)
+ {
+ throw new ConsoleException(
+ "Invalid class key format. Format should be package:class(bytes)");
+ }
+ setPackageName(parts[0]);
+ setClassName(parts[1]);
+ delims = "-";
+ String[] bytes = parts[2].split(delims);
+ if (bytes.length != 4)
+ {
+ throw new ConsoleException(
+ "Invalid class key format. Bytes should be in the format HEX-HEX-HEX-HEX");
+ }
+ hash[0] = Long.parseLong(bytes[0], 16);
+ hash[1] = Long.parseLong(bytes[1], 16);
+ hash[2] = Long.parseLong(bytes[2], 16);
+ hash[3] = Long.parseLong(bytes[3], 16);
+ }
+
+ public void encode(Encoder enc)
+ {
+ enc.writeStr8(getPackageName());
+ enc.writeStr8(getClassName());
+ enc.writeUint32(hash[0]);
+ enc.writeUint32(hash[1]);
+ enc.writeUint32(hash[2]);
+ enc.writeUint32(hash[3]);
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if(obj instanceof ClassKey && obj.getClass().equals(this.getClass()))
+ {
+ ClassKey other = (ClassKey) obj;
+ return (other.getKeyString().equals(this.getKeyString()));
+ } else
+ {
+ return false;
+ }
+ }
+
+ public final String getClassName()
+ {
+ return className;
+ }
+
+ public long[] getHash()
+ {
+ return hash;
+ }
+
+ public String getHashString()
+ {
+ return String.format("%08x-%08x-%08x-%08x", hash[0], hash[1], hash[2],
+ hash[3]);
+ }
+
+ public String getKeyString()
+ {
+ String hashString = this.getHashString();
+ return String.format("%s:%s(%s)", getPackageName(), getClassName(),
+ hashString);
+ }
+
+ public String getPackageName()
+ {
+ return packageName;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return getKeyString().hashCode();
+ }
+
+ public void setClassName(String value)
+ {
+ className = value;
+ }
+
+ public void setHash(long[] hash)
+ {
+ this.hash = hash;
+ }
+
+ public void setPackageName(String value)
+ {
+ packageName = value;
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("ClassKey: %s", getKeyString());
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/Console.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Console.java
new file mode 100644
index 0000000000..11b381032a
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Console.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.console;
+
+public interface Console
+{
+ void agentRemoved(Agent agent);
+
+ void brokerConnected(Broker broker);
+
+ void brokerDisconnected(Broker broker);
+
+ void brokerInformation(Broker broker);
+
+ void eventRecieved(Broker broker, QMFEvent anEvent);
+
+ void hearbeatRecieved(Agent agent, long timestamp);
+
+ void methodResponse(Broker broker, long seq, MethodResult response);
+
+ void newAgent(Agent agent);
+
+ void newClass(short kind, ClassKey key);
+
+ void newPackage(String packageName);
+
+ void objectProperties(Broker broker, QMFObject obj);
+
+ void objectStatistics(Broker broker, QMFObject obj);
+
+ @SuppressWarnings("unchecked")
+ Class typeMapping(ClassKey key);
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/ConsoleException.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/ConsoleException.java
new file mode 100644
index 0000000000..3176da70a6
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/ConsoleException.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.console;
+
+import java.lang.RuntimeException;
+
+public class ConsoleException extends RuntimeException
+{
+ private static final long serialVersionUID = 1L;
+
+ public ConsoleException()
+ {
+ super();
+ }
+
+ public ConsoleException(String message)
+ {
+ super(message);
+ }
+
+ public ConsoleException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ public ConsoleException(Throwable cause)
+ {
+ super(cause);
+ }
+}
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/EventSeverity.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/EventSeverity.java
new file mode 100644
index 0000000000..d40d41b196
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/EventSeverity.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.console;
+
+public enum EventSeverity
+{
+ EMER(0), ALERT(1), CRIT(2), ERROR(3), WARN(4), NOTIC(5), INFO(6), DEBUG(7);
+ private int intValue;
+
+ private EventSeverity(int value)
+ {
+ intValue = value;
+ }
+
+ public int getValue()
+ {
+ return intValue;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/MethodResult.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/MethodResult.java
new file mode 100644
index 0000000000..34980b50e1
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/MethodResult.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.console;
+
+import java.util.HashMap;
+
+public class MethodResult
+{
+ private long returnCode;
+ private String text;
+ protected java.util.HashMap<String, Object> returnValues;
+
+ public MethodResult(long aCode, String aMsg,
+ java.util.HashMap<String, Object> args)
+ {
+ setReturnCode(aCode);
+ setText(aMsg);
+ returnValues = args;
+ }
+
+ public long getReturnCode()
+ {
+ return returnCode;
+ }
+
+ public Object getReturnValue(String name)
+ {
+ Object returnValue = null;
+ if (returnValues.containsKey(name))
+ {
+ returnValue = returnValues.get(name);
+ }
+ return returnValue;
+ }
+
+ public HashMap<String, Object> getReturnValues()
+ {
+ return returnValues;
+ }
+
+ public String getText()
+ {
+ return text;
+ }
+
+ public void setReturnCode(long value)
+ {
+ returnCode = value;
+ }
+
+ public void setText(String value)
+ {
+ text = value;
+ }
+
+ @Override
+ public String toString()
+ {
+ String returnString = "";
+ for (java.util.Map.Entry<String, Object> pair : returnValues.entrySet())
+ {
+ returnString = returnString
+ + String.format("(Key: '%s' Value: '%s')", pair.getKey(),
+ pair.getValue());
+ }
+ return String.format(
+ "MethodResult: ReturnCode=%s, Text=%s Values=[%s]",
+ getReturnCode(), getText(), returnString);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/ObjectID.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/ObjectID.java
new file mode 100644
index 0000000000..6cf5301de5
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/ObjectID.java
@@ -0,0 +1,93 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.console;
+
+import org.apache.qpid.transport.codec.*;
+
+public class ObjectID
+{
+ protected long first;
+ protected long second;
+
+ public ObjectID()
+ {
+ }
+
+ public ObjectID(Decoder dec)
+ {
+ first = dec.readUint64();
+ second = dec.readUint64();
+ }
+
+ public ObjectID(long first, long second)
+ {
+ this.first = first;
+ this.second = second;
+ }
+
+ public long agentBank()
+ {
+ return (this.first & 0x000000000FFFFFFF);
+ }
+
+ public long brokerBank()
+ {
+ return (this.first & 0x0000FFFFF0000000L) >> 28;
+ }
+
+ public void encode(Encoder enc)
+ {
+ enc.writeUint64(first);
+ enc.writeUint64(second);
+ }
+
+ public long flags()
+ {
+ return (this.first & 0xF000000000000000L) >> 60;
+ }
+
+ public boolean isDurable()
+ {
+ return sequence() == 0;
+ }
+
+ public long objectNum()
+ {
+ return second;
+ }
+
+ public String routingCode()
+ {
+ return Agent.routingCode(agentBank(), brokerBank());
+ }
+
+ public long sequence()
+ {
+ return (this.first & 0x0FFF000000000000L) >> 48;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "" + flags() + "-" + sequence() + "-" + brokerBank() + "-"
+ + agentBank() + "-" + objectNum();
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFEvent.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFEvent.java
new file mode 100644
index 0000000000..116387acfc
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFEvent.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.console;
+
+import java.util.HashMap;
+
+import org.apache.qpid.transport.codec.*;
+
+public class QMFEvent
+{
+ private java.util.HashMap<String, Object> arguments;
+ private ClassKey classKey;
+ private Session session;
+ private EventSeverity severity;
+ // FIXME time?
+ private long timestamp;
+
+ public QMFEvent(Session session, Decoder dec)
+ {
+ setSession(session);
+ setClassKey(new ClassKey(dec));
+ setTimestamp(dec.readInt64());
+ setSeverity(EventSeverity.values()[dec.readUint8()]);
+ SchemaClass sClass = getSession().getSchema(getClassKey());
+ setArguments(new java.util.HashMap<String, Object>());
+ if (sClass != null)
+ {
+ for (SchemaArgument arg : sClass.arguments)
+ {
+ getArguments().put(arg.getName(),
+ getSession().decodeValue(dec, arg.getType()));
+ }
+ }
+ }
+
+ public final Object GetArgument(String argName)
+ {
+ return getArguments().get(argName);
+ }
+
+ public final HashMap<String, Object> getArguments()
+ {
+ return arguments;
+ }
+
+ public final ClassKey getClassKey()
+ {
+ return classKey;
+ }
+
+ public final Session getSession()
+ {
+ return session;
+ }
+
+ public final EventSeverity getSeverity()
+ {
+ return severity;
+ }
+
+ public final long getTimestamp()
+ {
+ return timestamp;
+ }
+
+ public final void setArguments(java.util.HashMap<String, Object> value)
+ {
+ arguments = value;
+ }
+
+ public final void setClassKey(ClassKey value)
+ {
+ classKey = value;
+ }
+
+ public final void setSession(Session value)
+ {
+ session = value;
+ }
+
+ public final void setSeverity(EventSeverity value)
+ {
+ severity = value;
+ }
+
+ public final void setTimestamp(long value)
+ {
+ timestamp = value;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFObject.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFObject.java
new file mode 100644
index 0000000000..1919bac411
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFObject.java
@@ -0,0 +1,423 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.console;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import edu.emory.mathcs.backport.java.util.Arrays;
+
+public class QMFObject
+{
+ private static Logger log = LoggerFactory.getLogger(QMFObject.class);
+ protected SchemaClass schema;
+ private java.util.Date createTime;
+ private java.util.Date currentTime;
+ private java.util.Date deleteTime;
+ private ObjectID objectID;
+ private Session session;
+ private boolean managed;
+ public java.util.HashMap<String, Object> properties = new java.util.HashMap<String, Object>();
+ public java.util.HashMap<String, Object> statistics = new java.util.HashMap<String, Object>();
+
+ // This constructor is the "naked" constructor which creates
+ // an object without a session or a schema. It is used by
+ // subclasses which are auto generated
+ public QMFObject()
+ {
+ }
+
+ public QMFObject(QMFObject source)
+ {
+ this.setSession(source.getSession());
+ this.setSchema(source.getSchema());
+ this.managed = source.managed;
+ this.setCurrentTime(source.getCurrentTime());
+ this.setCreateTime(source.getCreateTime());
+ this.setDeleteTime(source.getDeleteTime());
+ this.setObjectID(source.getObjectID());
+ this.properties = source.properties;
+ this.statistics = source.statistics;
+ }
+
+ // This constructor is used by a session make object call to
+ // create a blank object from a schema.
+ public QMFObject(Session session, SchemaClass schema,
+ boolean hasProperties, boolean hasStats, boolean isManaged)
+ {
+ setSession(session);
+ setSchema(schema);
+ managed = isManaged;
+ if (hasProperties)
+ {
+ for (SchemaProperty prop : getSchema().getAllProperties())
+ {
+ Object propValue = null;
+ if (!prop.getOptional())
+ {
+ propValue = Util.defaultValue(prop.getType());
+ }
+ this.setProperty(prop.getName(), propValue);
+ }
+ }
+ if (hasStats)
+ {
+ for (SchemaStatistic stat : getSchema().statistics)
+ {
+ setStatistic(stat.getName(), Util.defaultValue(stat.getType()));
+ }
+ }
+ }
+
+ // This constructor is used by the session to create an object based on a
+ // data
+ // stream by the agent.
+ public QMFObject(Session session, SchemaClass schema, Decoder dec,
+ boolean hasProperties, boolean hasStats, boolean isManaged)
+ {
+ setSession(session);
+ setSchema(schema);
+ managed = isManaged;
+ if (managed)
+ {
+ // FIXME DateTime or Uint64??
+ setCurrentTime(new java.util.Date(dec.readDatetime()));
+ setCreateTime(new java.util.Date(dec.readDatetime()));
+ setDeleteTime(new java.util.Date(dec.readDatetime()));
+ setObjectID(new ObjectID(dec));
+ }
+ if (hasProperties)
+ {
+ java.util.ArrayList<String> excluded = processPresenceMasks(dec,
+ getSchema());
+ for (SchemaProperty prop : getSchema().getAllProperties())
+ {
+ if (excluded.contains(prop.getName()))
+ {
+ // log.Debug(String.Format("Setting Property Default {0}",
+ // prop.Name)) ;
+ safeAddProperty(prop.getName(), null);
+ } else
+ {
+ // log.Debug(String.Format("Setting Property {0}",
+ // prop.Name)) ;
+ safeAddProperty(prop.getName(), session.decodeValue(dec,
+ prop.getType()));
+ }
+ }
+ }
+ if (hasStats)
+ {
+ for (SchemaStatistic stat : getSchema().getAllStatistics())
+ {
+ // log.Debug(String.Format("Setting Statistic {0}", stat.Name))
+ // ;
+ statistics.put(stat.getName(), session.decodeValue(dec, stat
+ .getType()));
+ }
+ }
+ }
+
+ public final long agentBank()
+ {
+ return getObjectID().agentBank();
+ }
+
+ public final long brokerBank()
+ {
+ return getObjectID().brokerBank();
+ }
+
+ public final void encode(Encoder enc)
+ {
+ int mask = 0;
+ int bit = 0;
+ java.util.ArrayList<SchemaProperty> propsToEncode = new java.util.ArrayList<SchemaProperty>();
+ log.debug(String.format("Encoding class %s:%s", getSchema()
+ .getPackageName(), getSchema().getClassName()));
+ enc.writeUint8((short) 20);
+ getSchema().getKey().encode(enc);
+ for (SchemaProperty prop : getSchema().getAllProperties())
+ {
+ if (prop.getOptional())
+ {
+ if (bit == 0)
+ {
+ bit = 1;
+ }
+ if ((properties.containsKey(prop.getName()))
+ && (properties.get(prop.getName()) != null))
+ {
+ mask |= bit;
+ propsToEncode.add(prop);
+ } else
+ {
+ }
+ bit = bit << 1;
+ if (bit == 256)
+ {
+ bit = 0;
+ enc.writeUint8((short) mask);
+ mask = 0;
+ }
+ } else
+ {
+ propsToEncode.add(prop);
+ }
+ }
+ if (bit != 0)
+ {
+ enc.writeUint8((short) mask);
+ }
+ for (SchemaProperty prop : propsToEncode)
+ {
+ Object obj = properties.get(prop.getName());
+ // log.Debug(String.Format("Encoding property {0}", prop.Name)) ;
+ getSession().encodeValue(enc, prop.getType(), obj);
+ }
+ for (SchemaStatistic stat : getSchema().statistics)
+ {
+ Object obj = statistics.get(stat.getName());
+ getSession().encodeValue(enc, stat.getType(), obj);
+ }
+ log.debug("Done");
+ }
+
+ public final Date getCreateTime()
+ {
+ return createTime;
+ }
+
+ public final Date getCurrentTime()
+ {
+ return currentTime;
+ }
+
+ public final Date getDeleteTime()
+ {
+ return deleteTime;
+ }
+
+ protected final ArrayList<SchemaMethod> getMethods()
+ {
+ return getSchema().getAllMethods();
+ }
+
+ public final ObjectID getObjectID()
+ {
+ return objectID;
+ }
+
+ public final Object getProperty(String attributeName)
+ {
+ return properties.get(attributeName);
+ }
+
+ public SchemaClass getSchema()
+ {
+ return schema;
+ }
+
+ public final Session getSession()
+ {
+ return session;
+ }
+
+ protected final MethodResult internalInvokeMethod(String name,
+ List<Object> args, boolean synchronous, int timeToLive)
+ {
+ if (!managed)
+ {
+ throw new ConsoleException("Object is not Managed");
+ }
+ if (getSchema().getMethod(name) == null)
+ {
+ throw new ConsoleException(String.format(
+ "Method named '%s' does not exist", name));
+ }
+ return getSession().invokeMethod(this, name, args, synchronous,
+ timeToLive);
+ }
+
+ public final MethodResult invokeMethod(String name, boolean synchronous,
+ int timeToLive, Object... args)
+ {
+ return this.internalInvokeMethod(name, Arrays.asList(args),
+ synchronous, timeToLive);
+ }
+
+ public final MethodResult invokeMethod(String name, boolean synchronous,
+ Object... args)
+ {
+ return this.internalInvokeMethod(name, Arrays.asList(args),
+ synchronous, Broker.SYNC_TIME);
+ }
+
+ public final MethodResult invokeMethod(String name, int timeToLive,
+ Object... args)
+ {
+ return this.internalInvokeMethod(name, Arrays.asList(args), true,
+ timeToLive);
+ }
+
+ public final MethodResult invokeMethod(String name, Object... args)
+ {
+ return this.internalInvokeMethod(name, Arrays.asList(args), true,
+ Broker.SYNC_TIME);
+ }
+
+ public final boolean isDeleted()
+ {
+ return !getDeleteTime().equals(new java.util.Date(0));
+ }
+
+ protected final ArrayList<String> processPresenceMasks(Decoder dec,
+ SchemaClass schema)
+ {
+ java.util.ArrayList<String> excludes = new java.util.ArrayList<String>();
+ short bit = 0;
+ short mask = 0;
+ for (SchemaProperty prop : getSchema().getAllProperties())
+ {
+ if (prop.getOptional())
+ {
+ // log.Debug(String.Format("Property named {0} is optional",
+ // prop.Name)) ;
+ if (bit == 0)
+ {
+ mask = dec.readUint8();
+ bit = 1;
+ }
+ if ((mask & bit) == 0)
+ {
+ // log.Debug(String.Format("Property named {0} is not present",
+ // prop.Name)) ;
+ excludes.add(prop.getName());
+ }
+ bit *= 2;
+ if (bit == 256)
+ {
+ bit = 0;
+ }
+ }
+ }
+ return excludes;
+ }
+
+ public final String routingKey()
+ {
+ return getObjectID().routingCode();
+ }
+
+ protected final void safeAddProperty(String propName, Object value)
+ {
+ if (properties.containsKey(propName))
+ {
+ properties.put(propName, value);
+ } else
+ {
+ properties.put(propName, value);
+ }
+ }
+
+ public final void setCreateTime(java.util.Date value)
+ {
+ createTime = value;
+ }
+
+ public final void setCurrentTime(java.util.Date value)
+ {
+ currentTime = value;
+ }
+
+ public final void setDeleteTime(java.util.Date value)
+ {
+ deleteTime = value;
+ }
+
+ public final void setObjectID(ObjectID value)
+ {
+ objectID = value;
+ }
+
+ public final void setProperty(String attributeName, Object newValue)
+ {
+ properties.put(attributeName, newValue);
+ }
+
+ public void setSchema(SchemaClass value)
+ {
+ schema = value;
+ }
+
+ public final void setSession(Session value)
+ {
+ session = value;
+ }
+
+ protected final void setStatistic(String attributeName, Object newValue)
+ {
+ statistics.put(attributeName, newValue);
+ }
+
+ @Override
+ public String toString()
+ {
+ String propertyString = "";
+ for (Entry<String, Object> pair : properties.entrySet())
+ {
+ propertyString = propertyString
+ + String.format("(Name: '%0$s' Value: '%1$s')", pair
+ .getKey(), pair.getValue());
+ }
+ String statsString = "";
+ for (Entry<String, Object> sPair : statistics.entrySet())
+ {
+ statsString = statsString
+ + String.format("(Name: '%0$s' Value: '%1$s')", sPair
+ .getKey(), sPair.getValue());
+ }
+ if (managed)
+ {
+ return String
+ .format(
+ "Managed QMFObject %0$s:%1$s(%2$s) Properties: [%3$s] Statistics: [%4$s])",
+ getSchema().getPackageName(), getSchema()
+ .getClassName(), getObjectID(),
+ propertyString, statsString);
+ } else
+ {
+ return String
+ .format(
+ "QMFObject %0$s:%1$s Properties: [%2$s] Statistics: [%3$s]",
+ getSchema().getPackageName(), getSchema()
+ .getClassName(), propertyString,
+ statsString);
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaArgument.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaArgument.java
new file mode 100644
index 0000000000..7e83b1b447
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaArgument.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.console;
+
+import java.util.Map;
+
+import org.apache.qpid.transport.codec.Decoder;
+
+public class SchemaArgument extends SchemaVariable
+{
+ private String direction;
+
+ public SchemaArgument(Decoder dec, boolean methodArg)
+ {
+ Map<String, Object> map = dec.readMap();
+ super.populateData(map);
+ if (map.containsKey("dir"))
+ {
+ setDirection((String) map.get("dir"));
+ }
+ }
+
+ public String getDirection()
+ {
+ return direction;
+ }
+
+ public boolean isBidirectional()
+ {
+ return getDirection().equals("IO");
+ }
+
+ public boolean isInput()
+ {
+ return getDirection().equals("I") | getDirection().equals("IO");
+ }
+
+ public boolean isOutput()
+ {
+ return getDirection().equals("O") | getDirection().equals("IO");
+ }
+
+ public void setDirection(String value)
+ {
+ direction = value;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaClass.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaClass.java
new file mode 100644
index 0000000000..311d81cc8e
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaClass.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.console;//
+
+import java.util.ArrayList;
+
+import org.apache.qpid.transport.codec.*;
+
+public class SchemaClass
+{
+ public static final int CLASS_KIND_EVENT = 2;
+ public static final int CLASS_KIND_TABLE = 1;
+ public ArrayList<SchemaArgument> arguments = new ArrayList<SchemaArgument>();
+ private ClassKey classKey;
+ private int kind;
+ private Session session;
+ private ClassKey superType;
+ public ArrayList<SchemaMethod> methods = new ArrayList<SchemaMethod>();
+ public ArrayList<SchemaProperty> properties = new ArrayList<SchemaProperty>();
+ public ArrayList<SchemaStatistic> statistics = new ArrayList<SchemaStatistic>();
+
+ public SchemaClass(int kind, ClassKey key, Decoder dec, Session session)
+ {
+ // System.Console.WriteLine(key.ClassName) ;
+ setKind(kind);
+ setSession(session);
+ this.setKey(key);
+ boolean hasSupertype = false; //dec.readUint8() != 0;
+ if (kind == CLASS_KIND_TABLE)
+ {
+ int propCount = dec.readUint16();
+ int statCount = dec.readUint16();
+ int methodCount = dec.readUint16();
+ if (hasSupertype)
+ {
+ setSuperType(new ClassKey(dec));
+ }
+ for (int x = 0; x < propCount; x++)
+ {
+ properties.add(new SchemaProperty(dec));
+ }
+ for (int x = 0; x < statCount; x++)
+ {
+ statistics.add(new SchemaStatistic(dec));
+ }
+ for (int x = 0; x < methodCount; x++)
+ {
+ methods.add(new SchemaMethod(dec));
+ }
+ }
+ if (kind == CLASS_KIND_EVENT)
+ {
+ int argCount = dec.readUint16();
+ if (hasSupertype)
+ {
+ setSuperType(new ClassKey(dec));
+ }
+ for (int x = 0; x < argCount; x++)
+ {
+ arguments.add(new SchemaArgument(dec, false));
+ }
+ }
+ }
+
+ public ArrayList<SchemaMethod> getAllMethods()
+ {
+ if (getSuperType() == null)
+ {
+ return methods;
+ } else
+ {
+ ArrayList<SchemaMethod> allMethods = new ArrayList<SchemaMethod>(
+ methods);
+ allMethods.addAll(getSession().getSchema(getSuperType())
+ .getAllMethods());
+ return allMethods;
+ }
+ }
+
+ public ArrayList<SchemaProperty> getAllProperties()
+ {
+ if (getSuperType() == null)
+ {
+ return properties;
+ } else
+ {
+ ArrayList<SchemaProperty> allProperties = new ArrayList<SchemaProperty>(
+ properties);
+ allProperties.addAll(getSession().getSchema(getSuperType())
+ .getAllProperties());
+ return allProperties;
+ }
+ }
+
+ public ArrayList<SchemaStatistic> getAllStatistics()
+ {
+ if (getSuperType() == null)
+ {
+ return statistics;
+ } else
+ {
+ ArrayList<SchemaStatistic> allStats = new ArrayList<SchemaStatistic>(
+ statistics);
+ allStats.addAll(getSession().getSchema(getSuperType())
+ .getAllStatistics());
+ return allStats;
+ }
+ }
+
+ public String getClassKeyString()
+ {
+ return getKey().getKeyString();
+ }
+
+ public String getClassName()
+ {
+ return getKey().getClassName();
+ }
+
+ public ClassKey getKey()
+ {
+ return classKey;
+ }
+
+ public int getKind()
+ {
+ return kind;
+ }
+
+ public SchemaMethod getMethod(String name)
+ {
+ SchemaMethod returnValue = null;
+ for (SchemaMethod method : methods)
+ {
+ if (method.getName().equals(name))
+ {
+ returnValue = method;
+ break;
+ }
+ }
+ return returnValue;
+ }
+
+ public String getPackageName()
+ {
+ return getKey().getPackageName();
+ }
+
+ protected Session getSession()
+ {
+ return session;
+ }
+
+ public ClassKey getSuperType()
+ {
+ return superType;
+ }
+
+ public boolean hasSuperType()
+ {
+ return getSuperType() != null;
+ }
+
+ public void setKey(ClassKey value)
+ {
+ classKey = value;
+ }
+
+ public void setKind(int value)
+ {
+ kind = value;
+ }
+
+ protected void setSession(Session value)
+ {
+ session = value;
+ }
+
+ public void setSuperType(ClassKey value)
+ {
+ superType = value;
+ }
+
+ public ArrayList<SchemaProperty> getProperties()
+ {
+ return properties;
+ }
+
+ public void setProperties(ArrayList<SchemaProperty> properties)
+ {
+ this.properties = properties;
+ }
+
+ public ArrayList<SchemaMethod> getMethods()
+ {
+ return methods;
+ }
+
+ public void setMethods(ArrayList<SchemaMethod> methods)
+ {
+ this.methods = methods;
+ }
+
+ public ArrayList<SchemaStatistic> getStatistics()
+ {
+ return statistics;
+ }
+
+ public void setStatistics(ArrayList<SchemaStatistic> statistics)
+ {
+ this.statistics = statistics;
+ }
+
+ public ArrayList<SchemaArgument> getArguments()
+ {
+ return arguments;
+ }
+
+ public void setArguments(ArrayList<SchemaArgument> arguments)
+ {
+ this.arguments = arguments;
+ }
+
+ public ClassKey getClassKey()
+ {
+ return classKey;
+ }
+
+ public void setClassKey(ClassKey classKey)
+ {
+ this.classKey = classKey;
+ }
+}
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaMethod.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaMethod.java
new file mode 100644
index 0000000000..1c20ae55bb
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaMethod.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.console;//
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.apache.qpid.transport.codec.*;
+
+public class SchemaMethod
+{
+ public ArrayList<SchemaArgument> Arguments = new ArrayList<SchemaArgument>();
+ private int m_ArgCount;
+ private int m_BidirectionalArgCount;
+ private String m_Description;
+ private int m_InputArgCount;
+ private String m_Name;
+ private int m_OutputArgCount;
+
+ public SchemaMethod(Decoder dec)
+ {
+ Map<String, Object> map = dec.readMap();
+ setName((String) map.get("name"));
+ setArgCount((Integer) map.get("argCount"));
+ if (map.containsKey("desc"))
+ {
+ setDescription((String) map.get("desc"));
+ }
+ for (int x = 0; x < getArgCount(); x++)
+ {
+ SchemaArgument arg = new SchemaArgument(dec, true);
+ Arguments.add(arg);
+ if (arg.isInput())
+ {
+ setInputArgCount(getInputArgCount() + 1);
+ }
+ if (arg.isOutput())
+ {
+ setOutputArgCount(getOutputArgCount() + 1);
+ }
+ if (arg.isBidirectional())
+ {
+ setBidirectionalArgCount(getBidirectionalArgCount() + 1);
+ }
+ }
+ }
+
+ public final int getArgCount()
+ {
+ return m_ArgCount;
+ }
+
+ public final int getBidirectionalArgCount()
+ {
+ return m_BidirectionalArgCount;
+ }
+
+ public final String getDescription()
+ {
+ return m_Description;
+ }
+
+ public final int getInputArgCount()
+ {
+ return m_InputArgCount;
+ }
+
+ public final String getName()
+ {
+ return m_Name;
+ }
+
+ public final int getOutputArgCount()
+ {
+ return m_OutputArgCount;
+ }
+
+ public final void setArgCount(int value)
+ {
+ m_ArgCount = value;
+ }
+
+ public final void setBidirectionalArgCount(int value)
+ {
+ m_BidirectionalArgCount = value;
+ }
+
+ public final void setDescription(String value)
+ {
+ m_Description = value;
+ }
+
+ public final void setInputArgCount(int value)
+ {
+ m_InputArgCount = value;
+ }
+
+ public final void setName(String value)
+ {
+ m_Name = value;
+ }
+
+ public final void setOutputArgCount(int value)
+ {
+ m_OutputArgCount = value;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaProperty.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaProperty.java
new file mode 100644
index 0000000000..8e278ff70d
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaProperty.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.console;
+
+import java.util.Map;
+
+import org.apache.qpid.transport.codec.*;
+
+public class SchemaProperty extends SchemaVariable
+{
+ private int access;
+ private boolean index;
+ private boolean optional;
+
+ public SchemaProperty(Decoder dec)
+ {
+ Map<String, Object> map = dec.readMap();
+ super.populateData(map);
+ setName((String) map.get("name"));
+ if (map.containsKey("optional"))
+ {
+ setOptional((Integer) map.get("optional") != 0);
+ }
+ if (map.containsKey("index"))
+ {
+ setIndex((Integer) map.get("index") != 0);
+ }
+ if (map.containsKey("access"))
+ {
+ setAccess((Integer) map.get("access"));
+ }
+ }
+
+ public int getAccess()
+ {
+ return access;
+ }
+
+ public boolean getIndex()
+ {
+ return index;
+ }
+
+ public boolean getOptional()
+ {
+ return optional;
+ }
+
+ public void setAccess(int value)
+ {
+ access = value;
+ }
+
+ public void setIndex(boolean value)
+ {
+ index = value;
+ }
+
+ public void setOptional(boolean value)
+ {
+ optional = value;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaStatistic.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaStatistic.java
new file mode 100644
index 0000000000..18bce86423
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaStatistic.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.console;//
+
+import java.util.Map;
+
+import org.apache.qpid.transport.codec.*;
+
+public class SchemaStatistic
+{
+ private String description;
+ private String name;
+ private short type;
+ private String unit;
+
+ public SchemaStatistic(Decoder dec)
+ {
+ Map<String, Object> map = dec.readMap();
+ setName((String) map.get("name"));
+ setType(Short.parseShort("" + map.get("type")));
+ if (map.containsKey("unit"))
+ {
+ setUnit((String) map.get("unit"));
+ }
+ if (map.containsKey("description"))
+ {
+ setDescription((String) map.get("description"));
+ }
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public short getType()
+ {
+ return type;
+ }
+
+ public String getUnit()
+ {
+ return unit;
+ }
+
+ public void setDescription(String value)
+ {
+ description = value;
+ }
+
+ public void setName(String value)
+ {
+ name = value;
+ }
+
+ public void setType(short value)
+ {
+ type = value;
+ }
+
+ public void setUnit(String value)
+ {
+ unit = value;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaVariable.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaVariable.java
new file mode 100644
index 0000000000..483a17d0de
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaVariable.java
@@ -0,0 +1,185 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.console;
+
+import java.util.Map;
+
+public abstract class SchemaVariable
+{
+ private String defaultVariable;
+ private String description;
+ private Integer max;
+ private Integer maxLength;
+ private Integer min;
+ private String name;
+ private String refClass;
+ private String refPackage;
+ private short type;
+ private String unit;
+
+ public SchemaVariable()
+ {
+ }
+
+ public String getDefault()
+ {
+ return defaultVariable;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public Integer getMax()
+ {
+ return max;
+ }
+
+ public Integer getMaxLength()
+ {
+ return maxLength;
+ }
+
+ public Integer getMin()
+ {
+ return min;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getRefClass()
+ {
+ return refClass;
+ }
+
+ public String getRefPackage()
+ {
+ return refPackage;
+ }
+
+ public short getType()
+ {
+ return type;
+ }
+
+ public String getUnit()
+ {
+ return unit;
+ }
+
+ protected void populateData(Map<String, Object> map)
+ {
+ if (map.containsKey("name"))
+ {
+ setName((String) map.get("name"));
+ }
+ if (map.containsKey("type"))
+ {
+ setType(Short.parseShort(("" + map.get("type"))));
+ }
+ if (map.containsKey("unit"))
+ {
+ setUnit((String) map.get("unit"));
+ }
+ if (map.containsKey("min"))
+ {
+ setMin((Integer) map.get("min"));
+ }
+ if (map.containsKey("max"))
+ {
+ setMax((Integer) map.get("max"));
+ }
+ if (map.containsKey("maxlen"))
+ {
+ setMaxLength((Integer) map.get("maxlen"));
+ }
+ if (map.containsKey("description"))
+ {
+ setDescription((String) map.get("description"));
+ }
+ if (map.containsKey("refClass"))
+ {
+ setRefClass((String) map.get("refClass"));
+ }
+ if (map.containsKey("refPackage"))
+ {
+ setRefPackage((String) map.get("refPackage"));
+ }
+ if (map.containsKey("Default"))
+ {
+ setDefault((String) map.get("default"));
+ }
+ }
+
+ public void setDefault(String value)
+ {
+ defaultVariable = value;
+ }
+
+ public void setDescription(String value)
+ {
+ description = value;
+ }
+
+ public void setMax(Integer value)
+ {
+ max = value;
+ }
+
+ public void setMaxLength(Integer value)
+ {
+ maxLength = value;
+ }
+
+ public void setMin(Integer value)
+ {
+ min = value;
+ }
+
+ public void setName(String value)
+ {
+ name = value;
+ }
+
+ public void setRefClass(String value)
+ {
+ refClass = value;
+ }
+
+ public void setRefPackage(String value)
+ {
+ refPackage = value;
+ }
+
+ public void setType(short value)
+ {
+ type = value;
+ }
+
+ public void setUnit(String value)
+ {
+ unit = value;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SequenceManager.java
index 8b9b2df5a3..4c5fcc7355 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SequenceManager.java
@@ -1,49 +1,57 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.server.security.auth.sasl;
-
-import java.security.Principal;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.security.auth.Subject;
-
-public class TestPrincipalUtils
-{
-
- /**
- * Creates a test subject, with exactly one UsernamePrincipal 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));
- for (String group : groups)
- {
- principals.add(new GroupPrincipal(group));
- }
-
- final Subject subject = new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET);
- return subject;
- }
-
-}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.console;
+
+import java.util.HashMap;
+
+public class SequenceManager
+{
+ private long sequence = 0;
+ private HashMap<Long, Object> pending = new HashMap<Long, Object>();
+ private Object lockObject = new Object();
+
+ public SequenceManager()
+ {
+ }
+
+ public Object release(long seq)
+ {
+ Object returnValue = null;
+ synchronized (lockObject)
+ {
+ returnValue = pending.get(seq);
+ pending.remove(seq);
+ }
+ return returnValue;
+ }
+
+ public long reserve(Object data)
+ {
+ long returnValue = 0;
+ synchronized (lockObject)
+ {
+ returnValue = sequence;
+ sequence += 1;
+ pending.put(returnValue, data);
+ }
+ return returnValue;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/Session.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Session.java
new file mode 100644
index 0000000000..a590a95546
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Session.java
@@ -0,0 +1,980 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.console;//
+
+import java.lang.reflect.Constructor;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.jms.Message;
+
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Session
+{
+ private static Logger log = LoggerFactory.getLogger(Session.class);
+ public static final int CONTEXT_SYNC = 1;
+ public static final int CONTEXT_STARTUP = 2;
+ public static final int CONTEXT_MULTIGET = 3;
+ public static final int DEFAULT_GET_WAIT_TIME = 60000;
+ public boolean recieveObjects = true;
+ public boolean recieveEvents = true;
+ public boolean recieveHeartbeat = true;
+ public boolean userBindings = false;
+ public Console console;
+ protected HashMap<String, HashMap<String, SchemaClass>> packages = new HashMap<String, HashMap<String, SchemaClass>>();
+ protected ArrayList<Broker> brokers = new ArrayList<Broker>();
+ protected SequenceManager sequenceManager = new SequenceManager();
+ protected Object lockObject = new Object();
+ protected ArrayList<Long> syncSequenceList = new ArrayList<Long>();
+ protected ArrayList<QMFObject> getResult;
+ protected Object syncResult;
+
+ public Session()
+ {
+ }
+
+ public Session(Console console)
+ {
+ this.console = console;
+ }
+
+ public void addBroker(String url)
+ {
+ Broker broker = new Broker(this, url);
+ brokers.add(broker);
+ java.util.HashMap<String, Object> args = new java.util.HashMap<String, Object>();
+ args.put("_class", "agent");
+ args.put("_broker", broker);
+ this.getObjects(args);
+ }
+
+ public ArrayList<String> bindingKeys()
+ {
+ ArrayList<String> bindings = new ArrayList<String>();
+ bindings.add("schema.#");
+ if (recieveObjects && recieveEvents && recieveHeartbeat && !userBindings)
+ {
+ bindings.add("console.#");
+ } else
+ {
+ if (recieveObjects && !userBindings)
+ {
+ bindings.add("console.obj.#");
+ } else
+ {
+ bindings.add("console.obj.*.*.org.apache.qpid.broker.agent");
+ }
+ if (recieveEvents)
+ {
+ bindings.add("console.event.#");
+ }
+ if (recieveHeartbeat)
+ {
+ bindings.add("console.heartbeat.#");
+ }
+ }
+ return bindings;
+ }
+
+ public void close()
+ {
+ for (Broker broker : brokers.toArray(new Broker[0]))
+ {
+ this.removeBroker(broker);
+ }
+ }
+
+ protected QMFObject createQMFObject(SchemaClass schema,
+ boolean hasProperties, boolean hasStats, boolean isManaged)
+ {
+ Class realClass = QMFObject.class;
+ if (console != null)
+ {
+ realClass = console.typeMapping(schema.getKey());
+ }
+ Class[] types = new Class[]
+ { Session.class, SchemaClass.class, boolean.class, boolean.class,
+ boolean.class };
+ Object[] args = new Object[]
+ { this, schema, hasProperties, hasStats, isManaged };
+ try
+ {
+ Constructor ci = realClass.getConstructor(types);
+ return (QMFObject) ci.newInstance(args);
+ } catch (Exception e)
+ {
+ throw new ConsoleException(e);
+ }
+ }
+
+ protected QMFObject createQMFObject(SchemaClass schema, Decoder dec,
+ boolean hasProperties, boolean hasStats, boolean isManaged)
+ {
+ Class realClass = QMFObject.class;
+ if (console != null)
+ {
+ realClass = console.typeMapping(schema.getKey());
+ }
+ Class[] types = new Class[]
+ { Session.class, SchemaClass.class, Decoder.class, boolean.class,
+ boolean.class, boolean.class };
+ Object[] args = new Object[]
+ { this, schema, dec, hasProperties, hasStats, isManaged };
+ try
+ {
+ log.debug("" + realClass);
+ Constructor ci = realClass.getConstructor(types);
+ return (QMFObject) ci.newInstance(args);
+ } catch (Exception e)
+ {
+ throw new ConsoleException(e);
+ }
+ }
+
+ public Object decodeValue(Decoder dec, short type)
+ {
+ switch (type)
+ {
+ case 1: // U8
+ return dec.readUint8();
+ case 2: // U16
+ return dec.readUint16();
+ case 3: // U32
+ return dec.readUint32();
+ case 4: // U64
+ return dec.readUint64();
+ case 6: // SSTR
+ return dec.readStr8();
+ case 7: // LSTR
+ return dec.readStr16();
+ case 8: // ABSTIME
+ return dec.readDatetime();
+ case 9: // DELTATIME
+ return dec.readUint32();
+ case 10: // ref
+ return new ObjectID(dec);
+ case 11: // bool
+ return dec.readUint8() != 0;
+ case 12: // float
+ return dec.readFloat();
+ case 13: // double
+ return dec.readDouble();
+ case 14: // UUID
+ return dec.readUuid();
+ case 15: // Ftable
+ return dec.readMap();
+ case 16: // int8
+ return dec.readInt8();
+ case 17: // int16
+ return dec.readInt16();
+ case 18: // int32
+ return dec.readInt32();
+ case 19: // int64
+ return dec.readInt64();
+ case 20: // Object
+ // Peek into the inner type code, make sure
+ // it is actually an object
+ Object returnValue = null;
+ short innerTypeCode = dec.readUint8();
+ if (innerTypeCode != 20)
+ {
+ returnValue = this.decodeValue(dec, innerTypeCode);
+ } else
+ {
+ ClassKey classKey = new ClassKey(dec);
+ synchronized (lockObject)
+ {
+ SchemaClass sClass = getSchema(classKey);
+ if (sClass != null)
+ {
+ returnValue = this.createQMFObject(sClass, dec, true,
+ true, false);
+ }
+ }
+ }
+ return returnValue;
+ case 21: // List
+ BBDecoder lDec = new BBDecoder();
+ lDec.init(ByteBuffer.wrap(dec.readVbin32()));
+ long count = lDec.readUint32();
+ ArrayList<Object> newList = new ArrayList<Object>();
+ while (count > 0)
+ {
+ short innerType = lDec.readUint8();
+ newList.add(this.decodeValue(lDec, innerType));
+ count -= 1;
+ }
+ return newList;
+ case 22: // Array
+ BBDecoder aDec = new BBDecoder();
+ aDec.init(ByteBuffer.wrap(dec.readVbin32()));
+ long cnt = aDec.readUint32();
+ short innerType = aDec.readUint8();
+ ArrayList<Object> aList = new ArrayList<Object>();
+ while (cnt > 0)
+ {
+ aList.add(this.decodeValue(aDec, innerType));
+ cnt -= 1;
+ }
+ return aList;
+ default:
+ throw new ConsoleException(String.format("Invalid Type Code: %s",
+ type));
+ }
+ }
+
+ public void encodeValue(Encoder enc, short type, Object val)
+ {
+ try
+ {
+ switch (type)
+ {
+ case 1: // U8
+ enc.writeUint8(((Short) val).shortValue());
+ break;
+ case 2: // U16
+ enc.writeUint16(((Integer) val).intValue());
+ break;
+ case 3: // U32
+ enc.writeUint32(((Integer) val).longValue());
+ break;
+ case 4: // U64
+ enc.writeUint64(((Long) val).longValue());
+ break;
+ case 6: // SSTR
+ enc.writeStr8((String) val);
+ break;
+ case 7: // LSTR
+ enc.writeStr16((String) val);
+ break;
+ case 8: // ABSTIME
+ enc.writeDatetime(((Long) val).longValue());
+ break;
+ case 9: // DELTATIME
+ enc.writeUint32(((Long) val).longValue());
+ break;
+ case 10: // ref
+ ((ObjectID) val).encode(enc);
+ break;
+ case 11:
+ if (((Boolean) val).booleanValue())
+ {
+ enc.writeUint8((short) 1);
+ } else
+ {
+ enc.writeUint8((short) 0);
+ }
+ break;
+ case 12: // FLOAT
+ enc.writeFloat(((Float) val).floatValue());
+ break;
+ case 13: // DOUBLE
+ enc.writeDouble(((Double) val).doubleValue());
+ break;
+ case 14: // UUID
+ enc.writeUuid((UUID) val);
+ break;
+ case 15: // Ftable
+ enc.writeMap((HashMap) val);
+ break;
+ case 16: // int8
+ enc.writeInt8((Byte) val);
+ break;
+ case 17: // int16
+ enc.writeInt16((Short) val);
+ break;
+ case 18: // int32
+ enc.writeInt32((Integer) val);
+ break;
+ case 19: // int64
+ enc.writeInt64((Long) val);
+ break;
+ case 20: // Object
+ // Check that the object has a session, if not
+ // take ownership of it
+ QMFObject qObj = (QMFObject) val;
+ if (qObj.getSession() == null)
+ {
+ qObj.setSession(this);
+ }
+ qObj.encode(enc);
+ break;
+ case 21: // List
+ ArrayList<Object> items = (ArrayList<Object>) val;
+ BBEncoder lEnc = new BBEncoder(1);
+ lEnc.init();
+ lEnc.writeUint32(items.size());
+ for (Object obj : items)
+ {
+ short innerType = Util.qmfType(obj);
+ lEnc.writeUint8(innerType);
+ this.encodeValue(lEnc, innerType, obj);
+ }
+ enc.writeVbin32(lEnc.segment().array());
+ break;
+ case 22: // Array
+ ArrayList<Object> aItems = (ArrayList<Object>) val;
+ BBEncoder aEnc = new BBEncoder(1);
+ aEnc.init();
+ long aCount = aItems.size();
+ aEnc.writeUint32(aCount);
+ if (aCount > 0)
+ {
+ Object anObj = aItems.get(0);
+ short innerType = Util.qmfType(anObj);
+ aEnc.writeUint8(innerType);
+ for (Object obj : aItems)
+ {
+ this.encodeValue(aEnc, innerType, obj);
+ }
+ }
+ enc.writeVbin32(aEnc.segment().array());
+ break;
+ default:
+ throw new ConsoleException(String.format(
+ "Invalid Type Code: %s", type));
+ }
+ } catch (ClassCastException e)
+ {
+ String msg = String.format(
+ "Class cast exception for typecode %s, type %s ", type, val
+ .getClass());
+ log.error(msg);
+ throw new ConsoleException(msg + type, e);
+ }
+ }
+
+ public Broker getBroker(long BrokerBank)
+ {
+ Broker returnValue = null;
+ for (Broker broker : brokers)
+ {
+ if (broker.brokerBank() == BrokerBank)
+ {
+ returnValue = broker;
+ break;
+ }
+ }
+ return returnValue;
+ }
+
+ public ArrayList<ClassKey> getClasses(String packageName)
+ {
+ ArrayList<ClassKey> returnValue = new ArrayList<ClassKey>();
+ this.waitForStable();
+ if (packages.containsKey(packageName))
+ {
+ for (SchemaClass sClass : packages.get(packageName).values())
+ {
+ returnValue.add(sClass.getKey());
+ }
+ }
+ return returnValue;
+ }
+
+ public ArrayList<QMFObject> getObjects(
+ java.util.HashMap<String, Object> args)
+ {
+ ArrayList<Broker> brokerList = null;
+ ArrayList<Agent> agentList = new ArrayList<Agent>();
+ if (args.containsKey("_broker"))
+ {
+ brokerList = new ArrayList<Broker>();
+ brokerList.add((Broker) args.get("_broker"));
+ } else
+ {
+ brokerList = this.brokers;
+ }
+ for (Broker broker : brokerList)
+ {
+ broker.waitForStable();
+ }
+ if (args.containsKey("_agent"))
+ {
+ Agent agent = (Agent) args.get("_agent");
+ if (brokerList.contains(agent.getBroker()))
+ {
+ agentList.add(agent);
+ } else
+ {
+ throw new ConsoleException(
+ "Agent is not managed by this console or the supplied broker");
+ }
+ } else
+ {
+ if (args.containsKey("_objectId"))
+ {
+ ObjectID oid = (ObjectID) args.get("_objectId");
+ for (Broker broker : brokers)
+ {
+ for (Agent agent : broker.Agents.values())
+ {
+ if ((agent.getAgentBank() == oid.agentBank())
+ && (agent.getBrokerBank() == oid.brokerBank()))
+ {
+ agentList.add(agent);
+ }
+ }
+ }
+ } else
+ {
+ for (Broker broker : brokerList)
+ {
+ for (Agent agent : broker.Agents.values())
+ {
+ if (agent.getBroker().isConnected())
+ {
+ agentList.add(agent);
+ }
+ }
+ }
+ }
+ }
+ getResult = new ArrayList<QMFObject>();
+ if (agentList.size() > 0)
+ {
+ // FIXME Add a bunch of other suff too
+ for (Agent agent : agentList)
+ {
+ HashMap<String, Object> getParameters = new HashMap<String, Object>();
+ Broker broker = agent.getBroker();
+ long seq = -1;
+ synchronized (lockObject)
+ {
+ seq = sequenceManager.reserve(Session.CONTEXT_MULTIGET);
+ syncSequenceList.add(seq);
+ }
+ String packageName = (String) args.get("_package");
+ String className = (String) args.get("_class");
+ ClassKey key = (ClassKey) args.get("_key");
+ Object sClass = args.get("_schema");
+ Object oid = args.get("_objectID");
+ long[] hash = (long[]) args.get("_hash");
+ if ((className == null) && (oid == null))
+ {
+ throw new ConsoleException(
+ "No class supplied, use '_schema', '_key', '_class', or '_objectId' argument");
+ }
+ if (oid != null)
+ {
+ getParameters.put("_objectID", oid);
+ } else
+ {
+ if (sClass != null)
+ {
+ key = (key != null) ? key : ((SchemaClass) sClass)
+ .getKey();
+ }
+ if (key != null)
+ {
+ className = (className != null) ? className : key
+ .getClassName();
+ packageName = (packageName != null) ? packageName : key
+ .getPackageName();
+ hash = (hash != null) ? hash : key.getHash();
+ }
+ if (packageName != null)
+ {
+ getParameters.put("_package", packageName);
+ }
+ if (className != null)
+ {
+ getParameters.put("_class", className);
+ }
+ if (hash != null)
+ {
+ getParameters.put("_hash", hash);
+ }
+ for (java.util.Map.Entry<String, Object> pair : args
+ .entrySet())
+ {
+ if (!pair.getKey().startsWith("_"))
+ {
+ getParameters.put(pair.getKey(), pair.getValue());
+ }
+ }
+ }
+ Encoder enc = broker.createEncoder('G', seq);
+ enc.writeMap(getParameters);
+ String routingKey = agent.routingCode();
+ Message msg = broker.createMessage(enc);
+ log.debug("Get Object Keys: ");
+ for (String pKey : getParameters.keySet())
+ {
+ log.debug(String.format("\tKey: '%s' Value: '%s'", pKey,
+ getParameters.get(pKey)));
+ }
+ broker.send(msg, routingKey);
+ }
+ int waittime = DEFAULT_GET_WAIT_TIME;
+ boolean timeout = false;
+ if (args.containsKey("_timeout"))
+ {
+ waittime = (Integer) args.get("_timeout");
+ }
+ long start = System.currentTimeMillis();
+ synchronized (lockObject)
+ {
+ // FIXME ERROR
+ while (syncSequenceList.size() > 0)
+ {
+ try
+ {
+ lockObject.wait(waittime);
+ } catch (InterruptedException e)
+ {
+ throw new ConsoleException(e);
+ }
+ long duration = System.currentTimeMillis() - start;
+ if (duration > waittime)
+ {
+ for (long pendingSeq : syncSequenceList)
+ {
+ sequenceManager.release(pendingSeq);
+ }
+ syncSequenceList.clear();
+ timeout = true;
+ }
+ }
+ }
+ // FIXME Add the error logic
+ if ((getResult.isEmpty()) && timeout)
+ {
+ throw new ConsoleException("Get Request timed out");
+ }
+ }
+ return getResult;
+ }
+
+ public ArrayList<String> getPackages()
+ {
+ this.waitForStable();
+ ArrayList<String> returnValue = new ArrayList<String>();
+ for (String name : packages.keySet())
+ {
+ returnValue.add(name);
+ }
+ return returnValue;
+ }
+
+ public SchemaClass getSchema(ClassKey key)
+ {
+ return getSchema(key, true);
+ }
+
+ protected SchemaClass getSchema(ClassKey key, boolean waitForStable)
+ {
+ if (waitForStable)
+ {
+ this.waitForStable();
+ }
+ SchemaClass returnValue = null;
+ returnValue = packages.get(key.getPackageName())
+ .get(key.getKeyString());
+ return returnValue;
+ }
+
+ public void handleAgentRemoved(Agent agent)
+ {
+ if (console != null)
+ {
+ console.agentRemoved(agent);
+ }
+ }
+
+ public void handleBrokerConnect(Broker broker)
+ {
+ if (console != null)
+ {
+ console.brokerConnected(broker);
+ }
+ }
+
+ public void handleBrokerDisconnect(Broker broker)
+ {
+ if (console != null)
+ {
+ console.brokerDisconnected(broker);
+ }
+ }
+
+ public void handleBrokerResponse(Broker broker, Decoder decoder,
+ long sequence)
+ {
+ if (console != null)
+ {
+ console.brokerInformation(broker);
+ }
+ long seq = sequenceManager.reserve(CONTEXT_STARTUP);
+ Encoder encoder = broker.createEncoder('P', seq);
+ broker.send(encoder);
+ }
+
+ public void handleClassIndicator(Broker broker, Decoder decoder,
+ long sequence)
+ {
+ short kind = decoder.readUint8();
+ ClassKey classKey = new ClassKey(decoder);
+ boolean unknown = false;
+ synchronized (lockObject)
+ {
+ if (packages.containsKey(classKey.getPackageName()))
+ {
+ if (!packages.get(classKey.getPackageName()).containsKey(
+ classKey.getKeyString()))
+ {
+ unknown = true;
+ }
+ }
+ }
+ if (unknown)
+ {
+ broker.incrementOutstanding();
+ long seq = sequenceManager.reserve(Session.CONTEXT_STARTUP);
+ Encoder enc = broker.createEncoder('S', seq);
+ classKey.encode(enc);
+ broker.send(enc);
+ }
+ }
+
+ public void handleCommandComplete(Broker broker, Decoder decoder,
+ long sequence)
+ {
+ long code = decoder.readUint32();
+ String text = decoder.readStr8();
+ Object context = this.sequenceManager.release(sequence);
+ if (context.equals(CONTEXT_STARTUP))
+ {
+ broker.decrementOutstanding();
+ } else
+ {
+ if ((context.equals(CONTEXT_SYNC)) && broker.getSyncInFlight())
+ {
+ broker.setSyncInFlight(false);
+ } else
+ {
+ if (context.equals(CONTEXT_MULTIGET)
+ && syncSequenceList.contains(sequence))
+ {
+ synchronized (lockObject)
+ {
+ syncSequenceList.remove(sequence);
+ if (syncSequenceList.isEmpty())
+ {
+ lockObject.notifyAll();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void handleContentIndicator(Broker broker, Decoder decoder,
+ long sequence, boolean hasProperties, boolean hasStatistics)
+ {
+ ClassKey key = new ClassKey(decoder);
+ SchemaClass sClass = null;
+ ;
+ synchronized (lockObject)
+ {
+ sClass = getSchema(key, false);
+ }
+ if (sClass != null)
+ {
+ QMFObject obj = this.createQMFObject(sClass, decoder,
+ hasProperties, hasStatistics, true);
+ if (key.getPackageName().equals("org.apache.qpid.broker")
+ && key.getClassName().equals("agent") && hasProperties)
+ {
+ broker.updateAgent(obj);
+ }
+ synchronized (lockObject)
+ {
+ if (syncSequenceList.contains(sequence))
+ {
+ if (!obj.isDeleted() && this.selectMatch(obj))
+ {
+ getResult.add(obj);
+ }
+ }
+ }
+ if (console != null)
+ {
+ if (hasProperties)
+ {
+ console.objectProperties(broker, obj);
+ }
+ if (hasStatistics)
+ {
+ console.objectStatistics(broker, obj);
+ }
+ }
+ }
+ }
+
+ public void handleEventIndicator(Broker broker, Decoder decoder,
+ long sequence)
+ {
+ if (console != null)
+ {
+ QMFEvent newEvent = new QMFEvent(this, decoder);
+ console.eventRecieved(broker, newEvent);
+ }
+ }
+
+ public void handleHeartbeatIndicator(Broker broker, Decoder decoder,
+ long sequence, Message msg)
+ {
+ if (console != null)
+ {
+ long brokerBank = 1;
+ long agentBank = 0;
+ try
+ {
+ // FIXME HOW DO WE GET THE ROUTING KEY
+ // String routingKey = msg.DeliveryProperties.getRoutingKey();
+ String routingKey = null;
+ if (routingKey != null)
+ {
+ agentBank = Agent.getBrokerBank(routingKey);
+ brokerBank = Agent.getBrokerBank(routingKey);
+ }
+ } catch (Throwable e)
+ {
+ log.warn("Internal QPID error", e);
+ }
+ String agentKey = Agent.AgentKey(agentBank, brokerBank);
+ long timestamp = decoder.readUint64();
+ if (broker.Agents.containsKey(agentKey))
+ {
+ Agent agent = broker.Agents.get(agentKey);
+ console.hearbeatRecieved(agent, timestamp);
+ }
+ }
+ }
+
+ public void handleMethodResponse(Broker broker, Decoder decoder,
+ long sequence)
+ {
+ long code = decoder.readUint32();
+ String text = decoder.readStr16();
+ java.util.HashMap<String, Object> outArgs = new java.util.HashMap<String, Object>();
+ Object obj = sequenceManager.release(sequence);
+ if (obj == null)
+ {
+ return;
+ }
+ Object[] pair = (Object[]) obj;
+ if (code == 0)
+ {
+ for (SchemaArgument arg : ((SchemaMethod) pair[0]).Arguments)
+ {
+ if (arg.isOutput())
+ {
+ outArgs.put(arg.getName(), this.decodeValue(decoder, arg
+ .getType()));
+ }
+ }
+ }
+ MethodResult result = new MethodResult(code, text, outArgs);
+ if ((Boolean) pair[1])
+ {
+ this.syncResult = result;
+ broker.setSyncInFlight(false);
+ }
+ if (console != null)
+ {
+ console.methodResponse(broker, sequence, result);
+ }
+ }
+
+ // Callback Methods
+ public void handleNewAgent(Agent agent)
+ {
+ if (console != null)
+ {
+ console.newAgent(agent);
+ }
+ }
+
+ public void handlePackageIndicator(Broker broker, Decoder decoder,
+ long sequence)
+ {
+ String packageName = decoder.readStr8();
+ boolean notify = false;
+ if (!packages.containsKey(packageName))
+ {
+ synchronized (lockObject)
+ {
+ packages.put(packageName,
+ new java.util.HashMap<String, SchemaClass>());
+ notify = true;
+ }
+ }
+ if (notify && console != null)
+ {
+ console.newPackage(packageName);
+ }
+ broker.incrementOutstanding();
+ long seq = sequenceManager.reserve(Session.CONTEXT_STARTUP);
+ Encoder enc = broker.createEncoder('Q', seq);
+ enc.writeStr8(packageName);
+ broker.send(enc);
+ }
+
+ public void handleSchemaResponse(Broker broker, Decoder decoder,
+ long sequence)
+ {
+ short kind = decoder.readUint8();
+ ClassKey classKey = new ClassKey(decoder);
+ SchemaClass sClass = new SchemaClass(kind, classKey, decoder, this);
+ synchronized (lockObject)
+ {
+ java.util.HashMap<String, SchemaClass> classMappings = packages
+ .get(sClass.getPackageName());
+ classMappings.remove(sClass.getClassKeyString());
+ classMappings.put(sClass.getClassKeyString(), sClass);
+ log.debug(classKey.toString());
+ }
+ sequenceManager.release(sequence);
+ broker.decrementOutstanding();
+ if (console != null)
+ {
+ this.console.newClass(kind, classKey);
+ }
+ }
+
+ public MethodResult invokeMethod(QMFObject obj, String name,
+ List<Object> args, boolean synchronous, int timeToLive)
+ {
+ Broker aBroker = this.getBroker(obj.brokerBank());
+ long seq = this.sendMethodRequest(obj, aBroker, name, args,
+ synchronous, timeToLive);
+ if (seq != 0)
+ {
+ if (!synchronous)
+ {
+ return null;
+ }
+ try
+ {
+ aBroker.waitForSync(timeToLive);
+ } catch (Throwable e)
+ {
+ sequenceManager.release(seq);
+ throw new ConsoleException(e);
+ }
+ // FIXME missing error logic in the broker
+ return (MethodResult) syncResult;
+ }
+ return null;
+ }
+
+ public QMFObject makeObject(ClassKey key)
+ {
+ SchemaClass sClass = this.getSchema(key);
+ if (sClass == null)
+ {
+ throw new ConsoleException("No schema found for class "
+ + key.toString());
+ }
+ return this.createQMFObject(sClass, true, true, false);
+ }
+
+ public QMFObject makeObject(String keyString)
+ {
+ return this.makeObject(new ClassKey(keyString));
+ }
+
+ public void removeBroker(Broker broker)
+ {
+ if (brokers.contains(broker))
+ {
+ brokers.remove(broker);
+ }
+ broker.shutdown();
+ }
+
+ public boolean selectMatch(QMFObject obj)
+ {
+ return true;
+ }
+
+ protected long sendMethodRequest(QMFObject obj, Broker aBroker,
+ String name, List<Object> args, boolean synchronous, int timeToLive)
+ {
+ SchemaMethod method = obj.getSchema().getMethod(name);
+ if (args == null)
+ {
+ args = new ArrayList<Object>();
+ }
+ long seq = 0;
+ if (method != null)
+ {
+ Object[] pair =
+ { method, synchronous };
+ seq = sequenceManager.reserve(pair);
+ Encoder enc = aBroker.createEncoder('M', seq);
+ obj.getObjectID().encode(enc);
+ obj.getSchema().getKey().encode(enc);
+ enc.writeStr8(name);
+ if (args.size() < method.getInputArgCount())
+ {
+ throw new ConsoleException(String.format(
+ "Incorrect number of arguments: expected %s, got %s",
+ method.getInputArgCount(), args.size()));
+ }
+ int argIndex = 0;
+ for (SchemaArgument arg : method.Arguments)
+ {
+ if (arg.isInput())
+ {
+ this.encodeValue(enc, arg.getType(), args.get(argIndex));
+ argIndex += 1;
+ }
+ }
+ Message msg = aBroker.createMessage(enc);
+ if (synchronous)
+ {
+ aBroker.setSyncInFlight(true);
+ }
+ aBroker.send(msg, obj.routingKey(), timeToLive);
+ }
+ return seq;
+ }
+
+ protected void waitForStable()
+ {
+ for (Broker broker : brokers)
+ {
+ broker.waitForStable();
+ }
+ }
+}
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/Util.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Util.java
new file mode 100644
index 0000000000..a9e4d68601
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Util.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.console;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.UUID;
+
+public class Util
+{
+ private static HashMap<Class, Short> ENCODINGS = new HashMap<Class, Short>();
+ static
+ {
+ ENCODINGS.put(String.class, (short) 7);
+ ENCODINGS.put(Short.class, (short) 1);
+ ENCODINGS.put(Float.class, (short) 13);
+ ENCODINGS.put(QMFObject.class, (short) 20);
+ ENCODINGS.put(Integer.class, (short) 17);
+ ENCODINGS.put(Long.class, (short) 18);
+ ENCODINGS.put(ArrayList.class, (short) 21);
+ }
+
+ public static String accessName(int type)
+ {
+ switch (type)
+ {
+ // case 0: return "UNKNOWN" ;
+ case 1:
+ return "RC";
+ case 2:
+ return "RW";
+ case 3:
+ return "RO";
+ }
+ throw new ConsoleException(String.format("Invalid Access Code: %s",
+ type));
+ }
+
+ public static String byteString(byte[] bytes)
+ {
+ return new String(bytes, Charset.forName("UTF-8"));
+ }
+
+ public static Object defaultValue(short type)
+ {
+ switch (type)
+ {
+ // case 0: return "UNKNOWN" ;
+ case 1:
+ return 0;
+ case 2:
+ return 0;
+ case 3:
+ return 0l;
+ case 4:
+ return 0l;
+ case 5:
+ return false;
+ case 6:
+ return "";
+ case 7:
+ return "";
+ case 8:
+ return 0l;
+ case 9:
+ return 0l;
+ case 10:
+ return new ObjectID();
+ case 11:
+ return false;
+ case 12:
+ return 0f;
+ case 13:
+ return 0d;
+ case 14:
+ return new UUID(0, 0);
+ case 15:
+ return new HashMap<String, Object>();
+ case 16:
+ return 0;
+ case 17:
+ return 0;
+ case 18:
+ return 0l;
+ case 19:
+ return 0l;
+ case 20:
+ return null;
+ case 21:
+ return new java.util.ArrayList<Object>();
+ case 22:
+ return new java.util.ArrayList<Object>();
+ }
+ throw new ConsoleException(String.format("Invalid Type Code: %s", type));
+ }
+
+ public static short qmfType(Object obj)
+ {
+ if (ENCODINGS.containsKey(obj.getClass()))
+ {
+ return ENCODINGS.get(obj.getClass());
+ } else
+ {
+ throw new ConsoleException(String.format("Unkown Type of %s", obj
+ .getClass()));
+ }
+ }
+
+ public static String typeName(short type)
+ {
+ switch (type)
+ {
+ // case 0: return "UNKNOWN" ;
+ case 1:
+ return "uint8";
+ case 2:
+ return "uint16";
+ case 3:
+ return "uint32";
+ case 4:
+ return "uint64";
+ case 5:
+ return "bool";
+ case 6:
+ return "short-string";
+ case 7:
+ return "long-string";
+ case 8:
+ return "abs-time";
+ case 9:
+ return "delta-time";
+ case 10:
+ return "reference";
+ case 11:
+ return "boolean";
+ case 12:
+ return "float";
+ case 13:
+ return "double";
+ case 14:
+ return "uuid";
+ case 15:
+ return "field-table";
+ case 16:
+ return "int8";
+ case 17:
+ return "int16";
+ case 18:
+ return "int32";
+ case 19:
+ return "int64";
+ case 20:
+ return "object";
+ case 21:
+ return "list";
+ case 22:
+ return "array";
+ }
+ throw new ConsoleException(String.format("Invalid Type Code: %s", type));
+ }
+
+ protected Util()
+ {
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/XMLUtil.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/XMLUtil.java
new file mode 100644
index 0000000000..dcbcb5b6b6
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/XMLUtil.java
@@ -0,0 +1,155 @@
+package org.apache.qpid.console;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+
+public class XMLUtil
+{
+ public static String commonAttributes(SchemaVariable var)
+ {
+ String returnString = "";
+ if (var.getDescription() != null)
+ {
+ returnString = returnString
+ + String.format(" desc='%s'", var.getDescription());
+ }
+ if (var.getRefPackage() != null)
+ {
+ returnString = returnString
+ + String.format(" refPackage='%s'", var.getRefPackage());
+ }
+ if (var.getRefClass() != null)
+ {
+ returnString = returnString
+ + String.format(" refClass='%s'", var.getRefClass());
+ }
+ if (var.getUnit() != null)
+ {
+ returnString = returnString
+ + String.format(" unit='%s'", var.getUnit());
+ }
+ if (var.getMin() != null)
+ {
+ returnString = returnString
+ + String.format(" min='%s'", var.getMin());
+ }
+ if (var.getMax() != null)
+ {
+ returnString = returnString
+ + String.format(" max='%s'", var.getMax());
+ }
+ if (var.getMaxLength() != null)
+ {
+ returnString = returnString
+ + String.format(" maxLength='%s'", var.getMaxLength());
+ }
+ return returnString;
+ }
+
+ public static String schemaXML(Session sess, String packageName)
+ {
+ String returnValue = String.format("<schema package='%s'>\n",
+ packageName);
+ for (ClassKey key : sess.getClasses(packageName))
+ {
+ SchemaClass schema = sess.getSchema(key);
+ if (schema.getKind() == 1)
+ {
+ if (schema.getSuperType() == null)
+ {
+ returnValue += String.format(
+ "\t<class name='%s' hash='%s'>\n", key
+ .getClassName(), key.getHashString());
+ } else
+ {
+ returnValue += String.format(
+ "\t<class name='%s' hash='%s' extends='%s'>\n", key
+ .getClassName(), key.getHashString(),
+ schema.getSuperType().getKeyString());
+ }
+ for (SchemaProperty prop : schema.getProperties())
+ {
+ Object[] attributes = new Object[5];
+ attributes[0] = prop.getName();
+ attributes[1] = Util.typeName(prop.getType());
+ attributes[2] = Util.accessName(prop.getAccess());
+ attributes[3] = prop.getOptional() ? "True" : "False ";
+ attributes[4] = XMLUtil.commonAttributes(prop);
+ returnValue += String
+ .format(
+ "\t\t<property name='%s' type='%s' access='%s' optional='%s'%s/>\n",
+ attributes);
+ }
+ for (SchemaMethod meth : schema.getMethods())
+ {
+ returnValue += String.format("\t\t<method name='%s'/>\n",
+ meth.getName());
+ for (SchemaArgument arg : meth.Arguments)
+ {
+ Object[] attributes = new Object[4];
+ attributes[0] = arg.getName();
+ attributes[1] = arg.getDirection();
+ attributes[2] = Util.typeName(arg.getType());
+ attributes[3] = XMLUtil.commonAttributes(arg);
+ returnValue += String
+ .format(
+ "\t\t\t<arg name='%s' dir='%s' type='%s'%s/>\n",
+ attributes);
+ }
+ returnValue += String.format("\t\t</method>\n");
+ }
+ returnValue += String.format("\t</class>\n");
+ } else
+ {
+ returnValue += String.format("\t<event name='%s' hash='%s'>\n",
+ key.getClassName(), key.getHashString());
+ for (SchemaArgument arg : schema.getArguments())
+ {
+ Object[] attributes = new Object[4];
+ attributes[0] = arg.getName();
+ attributes[1] = Util.typeName(arg.getType());
+ attributes[2] = XMLUtil.commonAttributes(arg);
+ returnValue += String.format(
+ "\t\t\t<arg name='%s' type='%s'%s/>\n", attributes);
+ }
+ returnValue += String.format("\t</event>\n");
+ }
+ }
+ returnValue += String.format("</schema>\n");
+ return returnValue;
+ }
+
+ public static String schemaXML(Session sess, String[] packageNames)
+ {
+ String returnValue = "<schemas>\n";
+ for (String pack : packageNames)
+ {
+ returnValue += XMLUtil.schemaXML(sess, pack);
+ returnValue += "\n";
+ }
+ returnValue += "</schemas>\n";
+ return returnValue;
+ }
+
+ protected XMLUtil()
+ {
+ }
+}
diff --git a/qpid/java/management/console/src/test/java/org/apache/qpid/console/ClassKeyTest.java b/qpid/java/management/console/src/test/java/org/apache/qpid/console/ClassKeyTest.java
new file mode 100644
index 0000000000..dc16aaac5b
--- /dev/null
+++ b/qpid/java/management/console/src/test/java/org/apache/qpid/console/ClassKeyTest.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.console;
+
+import junit.framework.TestCase;
+
+public class ClassKeyTest extends TestCase
+{
+ public void testCreation()
+ {
+ ClassKey key = new ClassKey(
+ "some.package:Class(00000001-00000002-00000003-00000004)");
+ assertEquals("some.package", key.getPackageName());
+ assertEquals("Class", key.getClassName());
+ assertEquals("00000001-00000002-00000003-00000004", key.getHashString());
+ assertEquals(1, key.getHash()[0]);
+ assertEquals(2, key.getHash()[1]);
+ assertEquals(3, key.getHash()[2]);
+ assertEquals(4, key.getHash()[3]);
+ }
+}
diff --git a/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF b/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF
index 0df308dff1..124fe1e767 100644
--- a/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF
+++ b/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@ Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
Bundle-ManifestVersion: 2
Bundle-Name: Qpid JMX Management Console Plug-in
Bundle-SymbolicName: org.apache.qpid.management.ui; singleton:=true
-Bundle-Version: 0.13.0
+Bundle-Version: 0.9.0
Bundle-Activator: org.apache.qpid.management.ui.Activator
Bundle-Vendor: Apache Software Foundation
Bundle-Localization: plugin
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
index 4a59176374..20cfec3758 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
@@ -47,7 +47,7 @@ public abstract class ApplicationRegistry
//max supported broker management interface supported by this release of the management console
public static final int SUPPORTED_QPID_JMX_API_MAJOR_VERSION = 2;
- public static final int SUPPORTED_QPID_JMX_API_MINOR_VERSION = 3;
+ public static final int SUPPORTED_QPID_JMX_API_MINOR_VERSION = 0;
public static final String DATA_DIR = System.getProperty("user.home") + File.separator + ".qpidmc";
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java
index a8fb864cf6..3561e16098 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java
@@ -21,7 +21,6 @@
package org.apache.qpid.management.ui.jmx;
import java.util.HashMap;
-import java.util.Map;
import javax.management.ObjectName;
@@ -32,36 +31,14 @@ public class JMXManagedObject extends ManagedBean
{
private ObjectName _objName;
+ @SuppressWarnings("unchecked")
public JMXManagedObject(ObjectName objName)
{
super();
this._objName = objName;
setUniqueName(_objName.toString());
- setDomain(_objName.getDomain());
-
- HashMap<String,String> props = new HashMap<String,String>(_objName.getKeyPropertyList());
-
- for(Map.Entry<String,String> entry : props.entrySet())
- {
- String value = entry.getValue();
-
- if(value != null)
- {
- try
- {
- //if the name is quoted in the ObjectName, unquote it
- value = ObjectName.unquote(value);
- entry.setValue(value);
- }
- catch(IllegalArgumentException e)
- {
- //ignore, this just means the name is not quoted
- //and can be left unchanged
- }
- }
- }
-
- super.setProperties(props);
+ setDomain(_objName.getDomain());
+ super.setProperties(new HashMap(_objName.getKeyPropertyList()));
}
public ObjectName getObjectName()
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java
index 35cc9f6e27..e42b3c53b6 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java
@@ -61,7 +61,7 @@ public class NotificationObject
{
if (_source instanceof ObjectName)
{
- return unquote(((ObjectName)_source).getKeyProperty("name"));
+ return ((ObjectName)_source).getKeyProperty("name");
}
return null;
@@ -71,31 +71,12 @@ public class NotificationObject
{
if (_source instanceof ObjectName)
{
- return unquote(((ObjectName)_source).getKeyProperty(VIRTUAL_HOST));
+ return ((ObjectName)_source).getKeyProperty(VIRTUAL_HOST);
}
return null;
}
-
- private String unquote(String value)
- {
- if(value != null)
- {
- try
- {
- //if the value is quoted in the ObjectName, unquote it
- value = ObjectName.unquote(value);
- }
- catch(IllegalArgumentException e)
- {
- //ignore, this just means the value is not quoted
- //and can be left unchanged
- }
- }
-
- return value;
- }
-
+
public String getMessage()
{
return _message;
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java
index 527fc67be3..1fef89d6b5 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java
@@ -131,8 +131,6 @@ public class MBeanTabFolderFactory
}
break;
case VHOST_MANAGER:
- createAttributesTab(tabFolder, mbean);
-
tab = new TabItem(tabFolder, SWT.NONE);
tab.setText("Operations");
controller = new VHostTabControl(tabFolder, mbean, mbsc);
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/LegacySupportingUserManagement.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/LegacySupportingUserManagement.java
deleted file mode 100644
index 0fc94a5972..0000000000
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/LegacySupportingUserManagement.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.management.ui.views.users;
-
-import javax.management.MBeanOperationInfo;
-
-import org.apache.qpid.management.common.mbeans.UserManagement;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParameter;
-
-/**
- * UserManagement interface extension to provide the method signatures
- * for old UserManagement methods no longer supported by the broker.
- *
- * This interface is used only for the creation of MBean proxy objects
- * within the management console, for backwards compatibility with
- * functionality in older broker versions.
- */
-public interface LegacySupportingUserManagement extends UserManagement
-{
- /**
- * set password for user.
- *
- * Since Qpid JMX API 1.2 this operation expects plain text passwords to be provided. Prior to this, MD5 hashed passwords were supplied.
- *
- * @deprecated since Qpid JMX API 1.7
- *
- * @param username The username for which the password is to be set
- * @param password The password for the user
- *
- * @return The result of the operation
- */
- @Deprecated
- @MBeanOperation(name = "setPassword", description = "Set password for user.",
- impact = MBeanOperationInfo.ACTION)
- boolean setPassword(@MBeanOperationParameter(name = "username", description = "Username")String username,
- //NOTE: parameter name was changed to 'passwd' in Qpid JMX API 1.7 to protect against older, incompatible management clients
- @MBeanOperationParameter(name = "passwd", description = "Password")char[] password);
-
- /**
- * Set rights for users with given details.
- * Since Qpid JMX API 2.3 all invocations will cause an exception to be thrown
- * as access rights can no longer be maintain via this interface.
- *
- * @deprecated since Qpid JMX API 2.3 / 1.12
- *
- * @param username The username to create
- * @param read The set of permission to give the new user
- * @param write The set of permission to give the new user
- * @param admin The set of permission to give the new user
- *
- * @return The result of the operation
- */
- @Deprecated
- @MBeanOperation(name = "setRights", description = "Set access rights for user.",
- impact = MBeanOperationInfo.ACTION)
- boolean setRights(@MBeanOperationParameter(name = "username", description = "Username")String username,
- @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
- @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write,
- @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin);
-
- /**
- * Create users with given details.
- * Since Qpid JMX API 2.3 if the user passes true for parameters read, write, or admin, a
- * exception will be thrown as access rights can no longer be maintain via this interface.
- *
- * Since Qpid JMX API 1.2 this operation expects plain text passwords to be provided. Prior to this, MD5 hashed passwords were supplied.
- *
- * @deprecated since Qpid JMX API 1.7
- *
- * @param username The username to create
- * @param password The password for the user
- * @param read The set of permission to give the new user
- * @param write The set of permission to give the new user
- * @param admin The set of permission to give the new user
- *
- * @return true if the user was created successfully, or false otherwise
- */
- @Deprecated
- @MBeanOperation(name = "createUser", description = "Create new user from system.",
- impact = MBeanOperationInfo.ACTION)
- boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username,
- //NOTE: parameter name was changed to 'passwd' in Qpid JMX API 1.7 to protect against older, incompatible management clients
- @MBeanOperationParameter(name = "passwd", description = "Password")char[] password,
- @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
- @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write,
- @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin);
-
- /**
- * Create users with given details.
- * Since Qpid JMX API 2.3 if the user passes true for parameters read, write, or admin, a
- * exception will be thrown as access rights can no longer be maintain via this interface.
- *
- * @deprecated since Qpid JMX API 2.3 / 1.12
- * @since Qpid JMX API 1.7
- *
- * @param username The username to create
- * @param password The password for the user
- * @param read The set of permission to give the new user
- * @param write The set of permission to give the new user
- * @param admin The set of permission to give the new user
- *
- * @return true if the user was created successfully, or false otherwise
- */
- @Deprecated
- @MBeanOperation(name = "createUser", description = "Create a new user.",
- impact = MBeanOperationInfo.ACTION)
- boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username,
- @MBeanOperationParameter(name = "password", description = "Password")String password,
- @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
- @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write,
- @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin);
-
-}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/UserManagementTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/UserManagementTabControl.java
index 2c540bf982..fdcc25d337 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/UserManagementTabControl.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/UserManagementTabControl.java
@@ -37,6 +37,7 @@ import javax.management.openmbean.TabularDataSupport;
import org.apache.qpid.management.ui.ApiVersion;
import org.apache.qpid.management.ui.ApplicationRegistry;
import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.common.mbeans.UserManagement;
import org.apache.qpid.management.ui.jmx.JMXManagedObject;
import org.apache.qpid.management.ui.jmx.MBeanUtility;
import org.apache.qpid.management.ui.views.TabControl;
@@ -82,7 +83,7 @@ public class UserManagementTabControl extends TabControl
private TableViewer _tableViewer = null;
private TabularDataSupport _userDetails = null;
- private LegacySupportingUserManagement _ummb;
+ private UserManagement _ummb;
private ApiVersion _ApiVersion;
public UserManagementTabControl(TabFolder tabFolder, JMXManagedObject mbean, MBeanServerConnection mbsc)
@@ -90,9 +91,9 @@ public class UserManagementTabControl extends TabControl
super(tabFolder);
_mbean = mbean;
_ApiVersion = ApplicationRegistry.getServerRegistry(mbean).getManagementApiVersion();
- _ummb = (LegacySupportingUserManagement)
+ _ummb = (UserManagement)
MBeanServerInvocationHandler.newProxyInstance(mbsc, mbean.getObjectName(),
- LegacySupportingUserManagement.class, false);
+ UserManagement.class, false);
_toolkit = new FormToolkit(_tabFolder.getDisplay());
_form = _toolkit.createScrolledForm(_tabFolder);
_form.getBody().setLayout(new GridLayout());
@@ -170,13 +171,6 @@ public class UserManagementTabControl extends TabControl
String[] titles = { "Username", "JMX Management Rights" };
int[] bounds = { 310, 200 };
- if(!settingManagementRightsSupported())
- {
- //Since Qpid JMX API 2.3 / 1.12 only Username is used
- titles = new String[]{ "Username"};
- bounds = new int[]{ 310 };
- }
-
for (int i = 0; i < titles.length; i++)
{
final int index = i;
@@ -220,16 +214,7 @@ public class UserManagementTabControl extends TabControl
Composite buttonsComposite = _toolkit.createComposite(tableComposite);
gridData = new GridData(SWT.FILL, SWT.TOP, false, false);
- if(!settingManagementRightsSupported())
- {
- //The 'Set Rights' button is not shown from Qpid JMX API 2.3 / 1.12
- //onward, provide less space
- gridData.heightHint = 135;
- }
- else
- {
- gridData.heightHint = 165;
- }
+ gridData.heightHint = 165;
buttonsComposite.setLayoutData(gridData);
buttonsComposite.setLayout(new GridLayout());
@@ -307,14 +292,14 @@ public class UserManagementTabControl extends TabControl
if (returnValue == InputDialog.OK)
{
- char[] passwordArray = id.getValue().toCharArray();
+ char[] password = id.getValue().toCharArray();
// Qpid JMX API 1.1 and below expects the password to be sent as a hashed value.
if (_ApiVersion.lessThanOrEqualTo(1,1))
{
try
{
- passwordArray = ViewUtility.getHash(id.getValue());
+ password = ViewUtility.getHash(id.getValue());
}
catch (Exception hashException)
{
@@ -327,18 +312,7 @@ public class UserManagementTabControl extends TabControl
try
{
- boolean result;
-
- //For Qpid JMX API >=1.7 use String based method instead of older char[] based method.
- if(_ApiVersion.greaterThanOrEqualTo(1, 7))
- {
- result = _ummb.setPassword(user, id.getValue());
- }
- else
- {
- result = _ummb.setPassword(user, passwordArray);
- }
-
+ boolean result = _ummb.setPassword(user, password);
ViewUtility.operationResultFeedback(result, "Updated user password", "Failed to update user password");
}
catch(Exception e2)
@@ -350,34 +324,25 @@ public class UserManagementTabControl extends TabControl
}
}
});
-
- final Button setRightsButton;
- if(!settingManagementRightsSupported())
- {
- //The 'Set Rights' button is not used from Qpid JMX API 2.3 / 1.12 onward
- setRightsButton = null;
- }
- else
+
+ final Button setRightsButton = _toolkit.createButton(buttonsComposite, "Set Rights ...", SWT.PUSH);
+ gridData = new GridData(SWT.CENTER, SWT.BOTTOM, false, false);
+ gridData.widthHint = 125;
+ setRightsButton.setLayoutData(gridData);
+ setRightsButton.setEnabled(false);
+ setRightsButton.addSelectionListener(new SelectionAdapter()
{
- setRightsButton = _toolkit.createButton(buttonsComposite, "Set Rights ...", SWT.PUSH);
- gridData = new GridData(SWT.CENTER, SWT.BOTTOM, false, false);
- gridData.widthHint = 125;
- setRightsButton.setLayoutData(gridData);
- setRightsButton.setEnabled(false);
- setRightsButton.addSelectionListener(new SelectionAdapter()
+ public void widgetSelected(SelectionEvent e)
{
- public void widgetSelected(SelectionEvent e)
- {
- int selectionIndex = _table.getSelectionIndex();
+ int selectionIndex = _table.getSelectionIndex();
- if (selectionIndex != -1)
- {
- setRights(setRightsButton.getShell());
- }
+ if (selectionIndex != -1)
+ {
+ setRights(setRightsButton.getShell());
}
- });
- }
-
+ }
+ });
+
_tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
public void selectionChanged(SelectionChangedEvent evt)
{
@@ -386,20 +351,14 @@ public class UserManagementTabControl extends TabControl
if (selectionIndex == -1)
{
deleteUsersButton.setEnabled(false);
+ setRightsButton.setEnabled(false);
setPasswordButton.setEnabled(false);
- if(setRightsButton != null)
- {
- setRightsButton.setEnabled(false);
- }
return;
}
else
{
deleteUsersButton.setEnabled(true);
- if(setRightsButton != null)
- {
- setRightsButton.setEnabled(true);
- }
+ setRightsButton.setEnabled(true);
}
if (_table.getSelectionCount() > 1)
@@ -427,17 +386,11 @@ public class UserManagementTabControl extends TabControl
//this only reloaded the JMX rights file before Qpid JMX API 1.2
_toolkit.createLabel(miscGroup, " Loads the current management rights file from disk");
}
- else if(settingManagementRightsSupported())
- {
- //from Qpid JMX API 1.2 to 2.3 / 1.12 it also reloads the password file
- _toolkit.createLabel(miscGroup, " Loads the current password and management rights files from disk");
- }
else
{
- //since Qpid JMX API 2.3 / 1.12 it only reloads the password file
- _toolkit.createLabel(miscGroup, " Loads the current password data");
+ //since Qpid JMX API 1.2 it also reloads the password file
+ _toolkit.createLabel(miscGroup, " Loads the current password and management rights files from disk");
}
-
reloadUserDetails.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
@@ -500,7 +453,7 @@ public class UserManagementTabControl extends TabControl
{
case 0 : // username column
return (String) ((CompositeData) element).get(USERNAME);
- case 1 : // rights column (used for API < 2.3 / 1.12)
+ case 1 : // rights column
return classifyUserRights((CompositeData) element);
default :
return "-";
@@ -557,11 +510,11 @@ public class UserManagementTabControl extends TabControl
int comparison = 0;
switch(column)
{
- case 0: //username column
+ case 0:
comparison = String.valueOf(user1.get(USERNAME)).compareTo(
String.valueOf(user2.get(USERNAME)));
break;
- case 1: // rights column (used for API < 2.3 / 1.12)
+ case 1:
comparison = classifyUserRights(user1).compareTo(classifyUserRights(user2));
break;
default:
@@ -602,12 +555,7 @@ public class UserManagementTabControl extends TabControl
private void setRights(final Shell parent)
{
- if(!settingManagementRightsSupported())
- {
- throw new UnsupportedOperationException("Setting management rights" +
- " is not supported using this version of the broker management API: " + (_ApiVersion));
- }
-
+
int selectionIndex = _table.getSelectionIndex();
if (selectionIndex == -1)
@@ -751,13 +699,6 @@ public class UserManagementTabControl extends TabControl
shell.open();
}
-
- protected boolean settingManagementRightsSupported()
- {
- //setting management access rights was supported until Qpid JMX API 1.12 / 2.3
- return _ApiVersion.lessThan(1,12) ||
- (_ApiVersion.greaterThanOrEqualTo(2, 0) && _ApiVersion.lessThan(2,3));
- }
private void addUser(final Shell parent)
{
@@ -765,8 +706,7 @@ public class UserManagementTabControl extends TabControl
Composite usernameComposite = _toolkit.createComposite(shell, SWT.NONE);
usernameComposite.setBackground(shell.getBackground());
- GridData usernameCompGridData = new GridData(SWT.FILL, SWT.TOP, true, false);
- usernameComposite.setLayoutData(usernameCompGridData);
+ usernameComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
usernameComposite.setLayout(new GridLayout(2,false));
_toolkit.createLabel(usernameComposite,"Username:").setBackground(shell.getBackground());
@@ -775,45 +715,28 @@ public class UserManagementTabControl extends TabControl
Composite passwordComposite = _toolkit.createComposite(shell, SWT.NONE);
passwordComposite.setBackground(shell.getBackground());
- GridData passwordCompGridData = new GridData(SWT.FILL, SWT.TOP, true, false);
- passwordComposite.setLayoutData(passwordCompGridData);
+ passwordComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
passwordComposite.setLayout(new GridLayout(2,false));
_toolkit.createLabel(passwordComposite,"Password:").setBackground(shell.getBackground());
final Text passwordText = new Text(passwordComposite, SWT.BORDER | SWT.PASSWORD);
passwordText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ Group buttonGroup = new Group(shell, SWT.NONE);
+ buttonGroup.setText("JMX Management Rights");
+ buttonGroup.setBackground(shell.getBackground());
+ buttonGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ buttonGroup.setLayout(new GridLayout(4,false));
- final Button readButton;
- final Button writeButton;
- final Button adminButton;
- if(settingManagementRightsSupported())
- {
- Group buttonGroup = new Group(shell, SWT.NONE);
- buttonGroup.setText("JMX Management Rights");
- buttonGroup.setBackground(shell.getBackground());
- buttonGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
- buttonGroup.setLayout(new GridLayout(4,false));
-
- final Button noneButton = new Button(buttonGroup, SWT.RADIO);
- noneButton.setText("No Access");
- noneButton.setSelection(true);
- readButton = new Button(buttonGroup, SWT.RADIO);
- readButton.setText("Read Only");
- writeButton = new Button(buttonGroup, SWT.RADIO);
- writeButton.setText("Read + Write");
- adminButton = new Button(buttonGroup, SWT.RADIO);
- adminButton.setText("Admin");
- }
- else
- {
- readButton = null;
- writeButton = null;
- adminButton = null;
- //The lack of rights settings will cause the dialog to,
- //shrink so add width hints to the other components
- passwordCompGridData.widthHint = 350;
- usernameCompGridData.widthHint = 350;
- }
+ final Button noneButton = new Button(buttonGroup, SWT.RADIO);
+ noneButton.setText("No Access");
+ noneButton.setSelection(true);
+ final Button readButton = new Button(buttonGroup, SWT.RADIO);
+ readButton.setText("Read Only");
+ final Button writeButton = new Button(buttonGroup, SWT.RADIO);
+ writeButton.setText("Read + Write");
+ final Button adminButton = new Button(buttonGroup, SWT.RADIO);
+ adminButton.setText("Admin");
Composite okCancelButtonsComp = _toolkit.createComposite(shell);
okCancelButtonsComp.setBackground(shell.getBackground());
@@ -861,36 +784,22 @@ public class UserManagementTabControl extends TabControl
return;
}
}
-
- //read the access rights selections if required
- boolean read = false;
- boolean write = false;
- boolean admin = false;
- if(settingManagementRightsSupported())
- {
- read = readButton.getSelection();
- write = writeButton.getSelection();
- admin = adminButton.getSelection();
- }
+
+ boolean read = readButton.getSelection();
+ boolean write = writeButton.getSelection();
+ boolean admin = adminButton.getSelection();
shell.dispose();
try
{
boolean result = false;
-
- if (!settingManagementRightsSupported())
- {
- // If we have Qpid JMX API 2.3 / 1.12 or above, use newer createUser method without rights parameters.
- result = _ummb.createUser(username, password);
- }
- else if (_ApiVersion.greaterThanOrEqualTo(1,7))
+ // If we have Qpid JMX API 1.7 or above, use newer createUser method with String based password.
+ if (_ApiVersion.greaterThanOrEqualTo(1,7))
{
- // If we have Qpid JMX API 1.7 or above, use newer createUser method with String based password.
result = _ummb.createUser(username, password, read, write, admin);
}
else
{
- // Else we have Qpid JMX API 1.6 or below, use older createUser method with char[] based password.
result = _ummb.createUser(username, passwordChars, read, write, admin);
}
diff --git a/qpid/java/management/tools/qpid-cli/Guide.txt b/qpid/java/management/tools/qpid-cli/Guide.txt
new file mode 100644
index 0000000000..db841ebaa1
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/Guide.txt
@@ -0,0 +1,143 @@
+
+ * How to connect with the Broker *
+ ---------------------------------
+
+Before you come in to this state you have to build the source or you
+can get the binary and extract then set the QPID_CLI environment
+variable to the main directory of the source or binary,then only you
+are in a position to start working with management console. First
+check whether the broker is up and running. In order to simply connect
+with the broker you can run the qpid-cli script which required
+arguments.
+
+${QPID_CLI}/bin/qpid-cli -h [HostName of IP of the broker ] -p [Port
+of the broker]
+
+Default values for arguments -h [localhost] -p [8999]
+
+ * One Shot mode *
+ -----------------
+
+With one shot mode you can run interactive mode commands for one time
+and disconnect with the broker.This feature is useful when you want to
+run particular command in the management console using a script which
+is running in the normal console.What you have to do is you have to
+give the command you want to run with the qpid-cli script running
+command.
+
+Ex 1: $QPID_CLI/bin/qpid-cli queue list -- This will list the queue
+objects and disconnect.
+
+Ex 2: $QPID_CLI/bin/qpid-cli queue view -n ping - This will display
+information about all the message in the queue with the name of ping
+
+Likewise you can run any command in one shot mode and get the output
+for one time.
+
+ * Report Generation Mode *
+ -------------------------
+
+If you want to generate reports you can do it by defining your
+required information using a property file. There's a sample property
+file in the parent directory and you can have a look and get an idea
+about that.You can generate reports by giving a time interval in the
+property file. In order to start the daemon mode you have to run the
+qpid-cli script with the option : -r by giving the path for your
+property file.
+
+Ex: $QPID_CLI/bin/qpid-cli -r ../report.property
+
+You should specify a property file in order to run the daemon mode and
+get information repeatedly.
+
+ * Interactive mode with number of command *
+ -------------------------------------------
+
+This is the mode you get when you run the qpid-cli script without the
+one shot mode and without the daemon mode with [-r] option.Once you
+connect with the broker it display you a prompt [qpid-admin-$], then
+you can run several commands to can perform following tasks.
+
+For all the commands object type is command and most important command
+so you can use this option value without giving the option letter by
+giving that option value at the beginning of the command.
+
+Ex: [list -o queue ] can use this command like this dropping -o option
+[queue list]
+Ex: [list -o queue -n ping] = [queue list -n ping]
+
+ * Data displaying commands *
+ ----------------------------
+
+This is the set of commands which display the information about
+broker.
+
+list :
+------
+list information about the given object type with limited
+number of attributes and you can use number of command options to get
+different useful behaviors with the list command.You can get the
+complete description about the command by running the command like
+this.[list -h].
+
+info :
+------
+list all the attributes of a given object type. This command
+works very similar way to list command. You can use -h option for help
+and get complete description of the info command.
+
+view :
+------
+view information about the content of the message in the queue
+object. In order to run this command you have to specify the object
+type at the beginning.You can give how many message informations you
+want to view from the top of the queue by using -t option.
+
+Ex : queue view -n message_queue -t 5
+[list the message info for top 5 messages in queue message_queue]
+
+viewcontent :
+-------------
+view the content of the a given message in the
+queue. You have to give the messageId as a parameter with -id option
+letters.
+
+Ex: queue viewcontent -n message_queue -id 12
+[list the content encoding and Mimetype of the message with the
+messageId for the give message which is in the queue message_queue]
+
+ * Data modification commands *
+ ------------------------------
+
+This is a set of commands which allow users to deal with messages in
+queues.Users can delete messages from a give queue and user's can move
+one message from one queue to another queue.
+
+delete :
+--------
+Using this command user can delete a give message from a given
+queue you can specify how many messages you want to delete from the
+queue from the top of the queue by using -t option.If user does not
+give how many messages to delete from the top of the queue program is
+going to delete all the messages from the queue after giving a prompt
+to confirm the deletion.
+
+Ex: queue delete -n message_queue -t 3
+[Delete top three messages in the queue message_queue ]
+
+move :
+------
+This command allow user to move number of messages from one
+queue to another queue. First you have to specify from which queue you
+want to move messages by using -n1 and -v1 option letters(-n1 queue
+name/ -v1 virtual host).Then you have to use -n2 option to give the
+target queue name and then you have to give From messageId and To
+messageId using -fmid and -tmid option letters to specify the messages
+range you want to do the move operation.
+
+Ex: queue move -n1 message_queue -n2 ping -fmid 13 -tmid 15
+[This will move messages with the messageId range of 13-15 from queue
+message_queue to queue ping.
+
+
+
diff --git a/qpid/java/management/tools/qpid-cli/LICENSE b/qpid/java/management/tools/qpid-cli/LICENSE
new file mode 100644
index 0000000000..c6432e459f
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/LICENSE
@@ -0,0 +1,225 @@
+=========================================================================
+== Apache License ==
+=========================================================================
+
+ 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.
+
+
+=============================================================================
+== JLine (BSD) License
+=============================================================================
+Copyright (c) 2008, Apache Software Foundation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
diff --git a/qpid/java/management/tools/qpid-cli/NOTICE b/qpid/java/management/tools/qpid-cli/NOTICE
new file mode 100644
index 0000000000..f1d9e54095
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/NOTICE
@@ -0,0 +1,12 @@
+Apache Qpid
+Copyright 2006-2008 Apache Software Foundation
+This product includes software developed at
+Apache Software Foundation (http://www.apache.org/)
+
+Handling console input is provided bye the Jline library package,
+JLine is a Java library for handling console input. It is similar
+in functionality to BSD editline and GNU readline.Original software is
+available from
+
+http://jline.sourceforge.net/index.html
+
diff --git a/qpid/java/management/tools/qpid-cli/README.txt b/qpid/java/management/tools/qpid-cli/README.txt
new file mode 100644
index 0000000000..6db439aad0
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/README.txt
@@ -0,0 +1,64 @@
+README
+n======
+
+INSTALL
+=======
+ source
+ ======
+ 1.Set the environment variable QPID_HOME to the root directory of the repository or the release.
+
+ 2.Run these command to build the source
+
+ ant compile OR run the ant build in the parent directory(main ant script)
+
+ 3.To launch the CLI run the script in bin folder with appropriate parameters.
+
+ ex:
+
+ Linux $QPID_HOME/bin/qpid-cli -h 10.8.100.122 -p 8334
+ Windows %QPID_HOME%/bin/qpid-cli.bat -h 10.8.100.122 -p 8334
+
+ -h hostname (default localhost)
+ -p broker port (default 8999)
+
+ binary
+ ======
+ 1.Set the environment variable QPID_HOME to the root directory of the repository or the release.
+
+ 2.To launch the CLI run the script in bin folder with appropriate parameters.
+
+ ex:
+
+ Linux $QPID_HOME/bin/qpid-cli -h 10.8.100.122 -p 8334
+ Windows %QPID_HOME%/bin/qpid-cli.bat -h 10.8.100.122 -p 8334
+
+ -h hostname (default localhost)
+ -p broker port (default 8999)
+
+ 3. No test cases are included in the binary version.
+
+TESTING
+=======
+
+1.Test source is located in the test directory.If you want to run the tests please start the
+Qpid java broker and run following ant targets.
+
+ ant compile-tests This compile all the test sources
+ ant test This runs all the test cases
+2.If you want to test with a remote broker please use the source release and change the constants in ConnectionConstants.java
+class.(Default values are BROKER_HOSTNAME="localhost" BROKER_PORT="8999")
+
+For more informations please visit the project home page.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qpid/java/tools/bin/check-qpid-java-env b/qpid/java/management/tools/qpid-cli/bin/qpid-cli
index dedd6e06ea..0efb49dddd 100755
--- a/qpid/java/tools/bin/check-qpid-java-env
+++ b/qpid/java/management/tools/qpid-cli/bin/qpid-cli
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Licensed to the Apache Software Foundation (ASF) under one
+# License to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
@@ -18,21 +18,18 @@
# under the License.
#
-if [ -z "$LOG_CONFIG" ]; then
- echo "Please set the appropriate parameters for logging as it may affect performance. Ex log4j defaults to DEBUG if not configured properly"
- exit -1
+if [ -z "$QPID_HOME" ]; then
+ export QPID_HOME=$(dirname $(dirname $(readlink -f $0)))
+ export PATH=${PATH}:${QPID_HOME}/bin
fi
-if [ -z "$JAVA_MEM" ]; then
- JAVA_MEM=-Xmx1024m
-fi
+# Set classpath to include Qpid jar with all required jars in manifest
+QPID_LIBS=$QPID_HOME/lib/qpid-all.jar
-if [ -z "$JAVA" ]; then
- echo "Please set the path to the correct java executable to JAVA"
- exit -1
-fi
+# Set other variables used by the qpid-run script before calling
+export JAVA=java \
+ JAVA_VM=-server \
+ JAVA_MEM=-Xmx1024m \
+ QPID_CLASSPATH=$QPID_LIBS
-if [ -z "$CLASSPATH" ]; then
- echo "Please set the $CLASSPATH variable to point to the jar/class files"
- exit -1
-fi
+. qpid-run org.apache.qpid.CommandLineInterpreter "$@"
diff --git a/qpid/java/management/tools/qpid-cli/bin/qpid-cli.bat b/qpid/java/management/tools/qpid-cli/bin/qpid-cli.bat
new file mode 100755
index 0000000000..452ddb65ee
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/bin/qpid-cli.bat
@@ -0,0 +1,28 @@
+@REM
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM
+set CLASSPATH=%CLASSPATH%;%QPID_HOME%/lib/jline-0.9.94.jar
+set CLASSPATH=%CLASSPATH%;%QPID_HOME%/lib/junit-4.4.jar
+set CLASSPATH=%CLASSPATH%;%QPID_HOME%/lib/qpid-cli-1.0.jar
+set CLASSPATH=%CLASSPATH%;%QPID_HOME%/lib/qpid-management-common-M4.jar
+set CLASSPATH=%CLASSPATH%;%QPID_HOME%/management/tools/qpid-cli/main/classes/
+java -classpath %CLASSPATH% org.apache.qpid.CommandLineInterpreter %1
+
+
+
+
diff --git a/qpid/java/management/tools/qpid-cli/build.xml b/qpid/java/management/tools/qpid-cli/build.xml
new file mode 100644
index 0000000000..7026cd2fd2
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/build.xml
@@ -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.
+ -
+ -->
+<project name="qpid-cli">
+
+ <property name="module.depends" value="common management/common" />
+ <property name="module.test.depends" value="common client" />
+ <property name="module.src" value="src" />
+ <!-- Disable tests as per QPID-1342 -->
+ <!--property name="module.test.src" value="test" /-->
+
+ <import file="../../../module.xml"/>
+
+</project>
diff --git a/qpid/java/management/tools/qpid-cli/report.property b/qpid/java/management/tools/qpid-cli/report.property
new file mode 100644
index 0000000000..46734d52a8
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/report.property
@@ -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.
+#
+
+object=queue
+column=Name,MessageCount,ActiveConsumerCount,Durable
+filter.name=ping
+filter.virtualhost=test
+output=csv
+seperator=|
+interval=1
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Command.java
index a51f195761..eadc87186f 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Command.java
@@ -18,15 +18,16 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.auth.manager;
+package org.apache.qpid;
-import org.apache.qpid.server.plugins.PluginFactory;
-
-/**
- * Factory producing authentication producing configured, initialised authentication
- * managers.
- */
-public interface AuthenticationManagerPluginFactory<S extends AuthenticationManager> extends PluginFactory<S>
+public interface Command
{
+ public void execute();
+
+ public void printusage();
+
+ public String optionchecker(String string);
+
+ public boolean checkoptionsetting(String string);
}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandExecutionEngine.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandExecutionEngine.java
new file mode 100644
index 0000000000..69f261b4ba
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandExecutionEngine.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;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.qpid.utils.JMXinfo;
+
+public class CommandExecutionEngine
+{
+ private static Map<String, Class<? extends Command>> _commands = new HashMap<String, Class<? extends Command>>();
+ private Command currentcommand = null;
+ private String commandname = null;
+ private JMXinfo info = null;
+
+ public CommandExecutionEngine(JMXinfo info)
+ {
+ this.info = info;
+ this.commandname = info.getCommandLineOptionParser().getcommandname();
+ }
+
+ public boolean CommandSelector() throws Exception
+ {
+ Class<? extends Command> commandClass = _commands.get(this.commandname);
+ if (commandClass != null)
+ {
+ Class<?> parameterTypes = JMXinfo.class;
+ currentcommand = (Command) commandClass.getConstructor(parameterTypes).newInstance(info);
+ }
+ else
+ {
+ usage();
+ return false;
+ }
+ return true;
+ }
+
+ public static void addCommand(String name, Class<? extends Command> newCommand)
+ {
+ _commands.put(name, newCommand);
+ }
+
+ public static Map<String, Class<? extends Command>> getCommands()
+ {
+ return _commands;
+ }
+
+ public void runcommand()
+ {
+ currentcommand.execute();
+ }
+
+ public void usage()
+ {
+ System.out.println(commandname + ":Command not found");
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandLineInterpreter.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandLineInterpreter.java
new file mode 100644
index 0000000000..d8e76172bc
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandLineInterpreter.java
@@ -0,0 +1,263 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid;
+
+import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+
+import jline.ArgumentCompletor;
+import jline.ConsoleReader;
+import jline.SimpleCompletor;
+
+import org.apache.qpid.commands.Commanddelete;
+import org.apache.qpid.commands.Commandget;
+import org.apache.qpid.commands.Commandhelp;
+import org.apache.qpid.commands.Commandinfo;
+import org.apache.qpid.commands.Commandlist;
+import org.apache.qpid.commands.Commandmove;
+import org.apache.qpid.commands.Commandset;
+import org.apache.qpid.commands.Commandview;
+import org.apache.qpid.commands.Commandviewcontent;
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.utils.JMXConfiguration;
+import org.apache.qpid.utils.JMXinfo;
+
+public class CommandLineInterpreter
+{
+ private static final String OBJECT_VIRTUALHOST = "virtualhost";
+ private static final String OBJECT_USERMANAGEMENT = "usermanagement";
+ private static final String OBJECT_CONNECTION = "connection";
+ private static final String OBJECT_EXCHANGE = "exchange";
+ private static final String OBJECT_QUEUE = "queue";
+ private static final String COMMAND_QUIT = "quit";
+ private static final String COMMAND_EXIT = "exit";
+
+ public static void main(String[] args)
+ {
+ Connector conn = null;
+ try
+ {
+ // Create an RMI connector client and
+ // connect it to the RMI connector server
+
+ /*
+ * checking the commandline options and parse them in to config
+ * method
+ */
+ JMXConnector jmxc = null;
+ MBeanServerConnection mbsc = null;
+ ConsoleReader reader = new ConsoleReader();
+ reader.setBellEnabled(false);
+ CommandLineOptionParser commandlineoptionparser = null;
+
+ if ((args == null) || (args.length) == 0)
+ {
+ Usage();
+ }
+ /*
+ * here special constructor is calling, when parsing options,in here
+ * first option value is starting from minus sign so this is handle
+ * by a special constructor
+ */
+ else
+ {
+ if (args[0].startsWith("-"))
+ {
+ commandlineoptionparser = new CommandLineOptionParser(args, args[0]); // if
+ // user
+ // specify
+ // any
+ // argument
+ // with
+ // the
+ // qpid-cli
+ // script
+ }
+ }
+
+ registerCommands();
+
+ /* Connecting with the broker */
+ try
+ {
+ if (commandlineoptionparser == null)
+ commandlineoptionparser = new CommandLineOptionParser(args);
+
+ JMXConfiguration config = new JMXConfiguration(commandlineoptionparser.getAlloptions());
+ conn = ConnectorFactory.getConnector(config.gethostname(), config.getport(), config.getUsername(),
+ config.getPassword());
+ jmxc = conn.getConnector();
+ mbsc = conn.getMBeanServerConnection();
+ if (config.checkoptionsetting("r", commandlineoptionparser.getAlloptions()))
+ {
+ JMXinfo info = new JMXinfo(jmxc, commandlineoptionparser, mbsc);
+ ReportGenerator reportgen = new ReportGenerator(config.optionchecker("r", commandlineoptionparser
+ .getAlloptions()), info);
+ reportgen.loadproperties();
+ reportgen.run();
+ }
+ /*
+ * This implementation is for the people who are using the
+ * interactive mode for one shot this run the user given command
+ * and exit
+ */
+ for (int i = 0; i < args.length; i++)
+ {
+ if (CommandExecutionEngine.getCommands().keySet().contains(args[i]))
+ {
+ oneshotmode(args, commandlineoptionparser, jmxc, mbsc);
+ return;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ connectionrefuse(ex);
+ return;
+ }
+ /* In this point connection has been established */
+ String line;
+ String[] command;
+
+ /* prividing GNU readline features using Jline library */
+ PrintWriter out = new PrintWriter(System.out);
+ SimpleCompletor completer = new SimpleCompletor(new String[] {
+ COMMAND_EXIT, COMMAND_QUIT, OBJECT_QUEUE, OBJECT_EXCHANGE, OBJECT_CONNECTION,
+ OBJECT_USERMANAGEMENT, OBJECT_VIRTUALHOST});
+ for (String commandName : CommandExecutionEngine.getCommands().keySet())
+ {
+ completer.addCandidateString(commandName);
+ }
+ reader.addCompletor(new ArgumentCompletor(completer));
+ while ((line = reader.readLine("qpid-admin-$ ")) != null)
+ {
+ out.flush();
+ if (removeSpaces(line).equalsIgnoreCase(COMMAND_QUIT) || removeSpaces(line).equalsIgnoreCase(COMMAND_EXIT))
+ break;
+ else if (line.length() == 0)
+ continue;
+ else
+ {
+ command = line.split("\\s+");
+ commandlineoptionparser = new CommandLineOptionParser(command);
+ JMXinfo info = new JMXinfo(jmxc, commandlineoptionparser, mbsc);
+ CommandExecutionEngine engine = new CommandExecutionEngine(info);
+ if (engine.CommandSelector())
+ engine.runcommand();
+ }
+ }
+
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ private static void registerCommands()
+ {
+ CommandExecutionEngine.addCommand(Commanddelete.COMMAND_NAME, Commanddelete.class);
+ CommandExecutionEngine.addCommand(Commandget.COMMAND_NAME, Commandget.class);
+ CommandExecutionEngine.addCommand(Commandhelp.COMMAND_NAME, Commandhelp.class);
+ CommandExecutionEngine.addCommand(Commandinfo.COMMAND_NAME, Commandinfo.class);
+ CommandExecutionEngine.addCommand(Commandlist.COMMAND_NAME, Commandlist.class);
+ CommandExecutionEngine.addCommand(Commandmove.COMMAND_NAME, Commandmove.class);
+ CommandExecutionEngine.addCommand(Commandset.COMMAND_NAME, Commandset.class);
+ CommandExecutionEngine.addCommand(Commandview.COMMAND_NAME, Commandview.class);
+ CommandExecutionEngine.addCommand(Commandviewcontent.COMMAND_NAME, Commandviewcontent.class);
+ }
+
+ private static void Usage()
+ {
+ System.out.println("Connecting to localhost Qpid java broker...");
+ }
+
+ private static String removeSpaces(String s)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ", false);
+ String t = "";
+ while (st.hasMoreElements())
+ t += st.nextElement();
+ return t;
+ }
+
+ private static void connectionrefuse(Exception e)
+ {
+ String message = e.getLocalizedMessage();
+ if (e instanceof SecurityException)
+ {
+ message = " authentication failed, please check username and password";
+ }
+ else
+ {
+ Throwable cause = e.getCause();
+ while (cause != null)
+ {
+ message = cause.getMessage();
+ cause = cause.getCause();
+ }
+ }
+
+ System.out.println("Cannot connect with the broker: " + message);
+ }
+
+ public static String[] oneshotmode(String[] args, CommandLineOptionParser commandlineoptionparser,
+ JMXConnector jmxc, MBeanServerConnection mbsc) throws Exception
+ {
+ int check = 0;
+ String[] temp;
+ for (int i = 0; i < args.length; i++)
+ {
+
+ if (args[i].compareTo("-h") == 0)
+ check++;
+ else if (args[i].compareTo("-p") == 0)
+ check++;
+ }
+ for (int i = 0; i < (args.length - 2 * check); i++)
+ { // mulitply by 2 because have to remove the option letter with the
+ // option value//
+ args[i] = args[i + check * 2];
+ }
+
+ commandlineoptionparser = new CommandLineOptionParser(args); // change
+ // the args
+ // string
+ // array
+ // which
+ // works as
+ // interactive
+ // mode//
+ JMXinfo info = new JMXinfo(jmxc, commandlineoptionparser, mbsc);
+ CommandExecutionEngine engine = new CommandExecutionEngine(info);
+ if (engine.CommandSelector())
+ engine.runcommand();
+ return args;
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Connector.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Connector.java
new file mode 100644
index 0000000000..2b887077c3
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Connector.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;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+
+public class Connector
+{
+ private JMXConnector jmxc = null;
+ private MBeanServerConnection mbsc = null;
+
+ public Connector(JMXConnector jmxc, MBeanServerConnection mbsc)
+ {
+
+ this.jmxc = jmxc;
+ this.mbsc = mbsc;
+
+ }
+
+ public JMXConnector getConnector()
+ {
+ return jmxc;
+ }
+
+ public MBeanServerConnection getMBeanServerConnection()
+ {
+ return mbsc;
+ }
+
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/SpawnedBrokerHolder.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ConnectorFactory.java
index 65239bbe02..84ba94c5c4 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/SpawnedBrokerHolder.java
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ConnectorFactory.java
@@ -18,41 +18,33 @@
* under the License.
*
*/
-package org.apache.qpid.test.utils;
+package org.apache.qpid;
-import org.apache.log4j.Logger;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
-public class SpawnedBrokerHolder implements BrokerHolder
-{
- private static final Logger LOGGER = Logger.getLogger(SpawnedBrokerHolder.class);
-
- private final Process _process;
+import org.apache.qpid.management.common.JMXConnnectionFactory;
- public SpawnedBrokerHolder(final Process process)
- {
- if(process == null)
- {
- throw new IllegalArgumentException("Process must not be null");
- }
+public class ConnectorFactory
+{
- _process = process;
- }
+ private static final long TIMEOUT = 30 * 1000;
- public void shutdown()
+ public static Connector getConnector(String host, String port, String username, String password) throws Exception
{
- LOGGER.info("Destroying broker process");
-
- _process.destroy();
+ JMXConnector jmxc = null;
+ MBeanServerConnection mbsc = null;
try
{
- _process.waitFor();
- LOGGER.info("broker exited: " + _process.exitValue());
+ jmxc = JMXConnnectionFactory.getJMXConnection(TIMEOUT, host, Integer.parseInt(port), username, password);
+ mbsc = jmxc.getMBeanServerConnection();
}
- catch (InterruptedException e)
+ catch (NumberFormatException e)
{
- LOGGER.error("Interrupted whilst waiting for process destruction");
- Thread.currentThread().interrupt();
+ System.out.println("Illegal port entered:" + port);
+ System.exit(1);
}
+ return new Connector(jmxc, mbsc);
}
}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ReportGenerator.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ReportGenerator.java
new file mode 100644
index 0000000000..9d14f78b42
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ReportGenerator.java
@@ -0,0 +1,195 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid;
+
+import org.apache.qpid.commands.objects.*;
+import org.apache.qpid.utils.JMXinfo;
+
+import javax.management.MBeanServerConnection;
+import java.util.*;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class ReportGenerator implements Runnable
+{
+
+ String[] propertyname = { "object", "column", "filter.name", "filter.virtualhost", "output", "seperator",
+ "interval" };
+ String[] propertyvalue = null;
+ String propertyfilepath = null;
+ String[] columnvalue = null;
+ List<String> columns = null;
+ Properties props = null;
+ JMXinfo info = null;
+ int interval = 10;
+
+ public void run()
+ {
+ for (;;) // creating infinite loop
+ {
+ generatereport();
+ try
+ {
+ Thread.sleep((long)this.interval * 60000L);
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ public ReportGenerator(String propfile, JMXinfo info)
+ {
+ this.propertyfilepath = propfile;
+ props = new Properties();
+ propertyvalue = new String[propertyname.length];
+ this.info = info;
+ columns = new ArrayList<String>();
+ }
+
+ public void loadproperties() // get all the property file values and set the
+ // columen values//
+ {
+ try
+ {
+
+ props.load(new FileInputStream(this.propertyfilepath));
+ for (int i = 0; i < propertyname.length; i++)
+ {
+ propertyvalue[i] = props.getProperty(propertyname[i]);
+ }
+ this.setcolumnvalues();
+ this.setinterval();
+ }
+
+ // catch exception in case properties file does not exist
+
+ catch (IOException e)
+ {
+ System.out.println("Oooops Give property file is not exist");
+ }
+ }
+
+ public void generatereport()
+ {
+ this.listobjects(propertyvalue[0]);
+ }
+
+ private void setcolumnvalues()
+ {
+ columnvalue = propertyvalue[1].split(",");
+ for (int i = 0; i < columnvalue.length; i++)
+ {
+ columns.add(columnvalue[i]);
+ }
+ }
+
+ private void setinterval()
+ {
+ this.interval = (new Integer(propertyvalue[6])).intValue();
+ }
+
+ private void listobjects(String option_value)
+ {
+ /*
+ * pring usage if use is not give the correct option letter or no
+ * options
+ */
+ if (option_value == null)
+ {
+ // System.out.println("testing");
+ return;
+ }
+ MBeanServerConnection mbsc = info.getmbserverconnector();
+ Set set = null;
+ ObjectNames objname = null;
+
+ try
+ {
+ if (option_value.compareToIgnoreCase("queue") == 0 || option_value.compareToIgnoreCase("queues") == 0)
+ {
+ objname = new QueueObject(mbsc);
+
+ }
+ else if (option_value.compareToIgnoreCase("Virtualhosts") == 0
+ || option_value.compareToIgnoreCase("Virtualhost") == 0)
+ {
+ objname = new VirtualHostObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Exchange") == 0
+ || option_value.compareToIgnoreCase("Exchanges") == 0)
+ {
+ objname = new ExchangeObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Connection") == 0
+ || option_value.compareToIgnoreCase("Connections") == 0)
+ {
+ objname = new ConnectionObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("all") == 0)
+ {
+ objname = new AllObjects(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Usermanagement") == 0
+ || option_value.compareToIgnoreCase("Usermanagmenets") == 0)
+ {
+ objname = new UserManagementObject(mbsc);
+ // this.name = option_value;
+ }
+ else
+ {
+ printusage();
+ echo("Wrong objectName");
+ return;
+ }
+ objname.setQueryString(this.propertyvalue[0], this.propertyvalue[2], this.propertyvalue[3]);
+ objname.returnObjects();
+ if (objname.getSet().size() != 0)
+ {
+ objname.reportgenerator(this.propertyvalue[4], this.propertyvalue[5], columns);
+ }
+ else
+ {
+ printusage();
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void echo(String str)
+ {
+ System.out.println(str);
+ }
+
+ public void printusage()
+ {
+ System.out.println("Wrong option or wrong option value");
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/CommandImpl.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/CommandImpl.java
new file mode 100644
index 0000000000..6fdae4c0a6
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/CommandImpl.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.commands;
+
+import java.util.Map;
+
+import org.apache.qpid.Command;
+import org.apache.qpid.utils.CommandLineOption;
+import org.apache.qpid.utils.JMXinfo;
+
+public abstract class CommandImpl implements Command
+{
+ protected JMXinfo info = null;
+
+ private String name;
+ private String virtualhost = null;
+ private String object = null;
+
+ private String outputformat = null;
+ private String seperator = ",";
+
+ public CommandImpl(JMXinfo info)
+ {
+ this.info = info;
+ }
+
+ public CommandImpl()
+ {
+
+ }
+
+ protected void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public String getName()
+ {
+ return this.name;
+ }
+
+ protected boolean hasName()
+ {
+ if (this.name == null)
+ return false;
+
+ else
+ return true;
+ }
+
+ protected void setObject(String object)
+ {
+ this.object = object;
+ }
+
+ public String getObject()
+ {
+ return this.object;
+ }
+
+ protected void setOutputFormat(String outputformat)
+ {
+ this.outputformat = outputformat;
+ }
+
+ protected String getOutputFormat()
+ {
+ return outputformat;
+ }
+
+ protected void setSeperator(String seperator)
+ {
+ this.seperator = seperator;
+ }
+
+ protected String getSeperator()
+ {
+ return seperator;
+ }
+
+ protected void setVirtualhost(String virtualhost)
+ {
+ this.virtualhost = virtualhost;
+ }
+
+ public String getVirtualhost()
+ {
+ return this.virtualhost;
+ }
+
+ public String optionchecker(String option_letter)
+ {
+ Map map = info.getCommandLineOptionParser().getAlloptions();
+ if (map == null)
+ return null;
+ CommandLineOption option = (CommandLineOption) map.get(option_letter);
+ if (option == null)
+ return null;
+ String value = option.getOptionValue();
+ return value;
+ }
+
+ public boolean checkoptionsetting(String option_letter)
+ {
+ Map map = info.getCommandLineOptionParser().getAlloptions();
+ if (map == null)
+ return false;
+ CommandLineOption option = (CommandLineOption) map.get(option_letter);
+ if (option == null)
+ return false;
+ String value = option.getOptionType();
+
+ if (value != null)
+ return true;
+ else
+ return false;
+ }
+
+ public void echo(String str)
+ {
+ System.out.println(str);
+ }
+
+ public void unrecognizeoption()
+ {
+ echo("list: Unrecognized option");
+ echo("Try --help for more information");
+ }
+
+ public abstract void execute();
+
+ public abstract void printusage();
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commanddelete.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commanddelete.java
new file mode 100644
index 0000000000..cdbb8f1d4f
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commanddelete.java
@@ -0,0 +1,199 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.utils.JMXinfo;
+
+public class Commanddelete extends CommandImpl
+{
+ private int number = 0;
+ private QueueObject objname;
+ private MBeanServerConnection mbsc;
+ private String method1, method2;
+ private ObjectName queue;
+ public static final String COMMAND_NAME = "delete";
+
+ public Commanddelete(JMXinfo info)
+ {
+ super(info);
+ this.mbsc = info.getmbserverconnector();
+ this.objname = new QueueObject(mbsc);
+ this.method1 = "deleteMessageFromTop";
+ this.method2 = "clearQueue";
+
+ }
+
+ public void deletemessages()
+ {
+ Set set = null;
+ objname.setQueryString(this.getObject(), this.getName(), this.getVirtualhost());
+ set = objname.returnObjects();
+
+ if (objname.getSet().size() != 0)
+ {
+ Iterator it = set.iterator();
+ this.queue = (ObjectName) it.next();
+ try
+ {
+ if (this.number == 0)
+ {
+ echo("");
+ System.out.print("Do you want to delete all the messages from the Queue [Y/N] :");
+ InputStreamReader isr = new InputStreamReader(System.in);
+ BufferedReader br = new BufferedReader(isr);
+ String s = br.readLine();
+ echo(s);
+ if (s.compareToIgnoreCase("y") == 0)
+ this.mbsc.invoke(queue, this.method2, null, null);
+ else
+ return;
+ }
+ else if (objname.getmessagecount(this.queue) < this.number)
+ {
+ echo("Given number is Greater than the Queue Depth");
+ return;
+ }
+ else
+ {
+ for (int i = 0; i < this.number; i++)
+ {
+ this.mbsc.invoke(queue, this.method1, null, null);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+ else
+ {
+ if (hasName())
+ {
+
+ echo("The Queue you have specified is not in the current broker");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ if (object.compareToIgnoreCase("queue") == 0)
+ setObject(object);
+ else
+ {
+ unrecognizeoption();
+ echo("This command is only applicable for delete command so please start with queue");
+ }
+ if (checkoptionsetting("name") || checkoptionsetting("n"))
+ {
+ String name = optionchecker("name");
+ if (name == null)
+ name = optionchecker("n");
+
+ setName(name);
+ }
+ if (checkoptionsetting("virtualhost") || checkoptionsetting("v"))
+ {
+ String vhost = optionchecker("virtualhost");
+ if (vhost == null)
+ vhost = optionchecker("v");
+ setVirtualhost(vhost);
+ }
+ if (checkoptionsetting("top") || checkoptionsetting("t"))
+ {
+ String number = optionchecker("top");
+ if (number == null)
+ number = optionchecker("t");
+
+ setnumber(removeSpaces(number));
+ }
+ this.deletemessages();
+ }
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ printusage();
+ else
+ unrecognizeoption();
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:delete [OPTION] ... [OBJECT TYPE]...\n");
+ echo("Delete the top most messages from the given queue object\n");
+ echo("To specify the desired queue you have to give the virtualhost name and the queue name with following commands\n");
+ echo("Where possible options include:\n");
+ echo(" -v --virtualhost Give the virtuallhost name of the desired queue");
+ echo(" -n --name Give the queue name of the desired queue you want to do the delete operation");
+ echo(" -t --top Give how many number of messages you want to delete from the top (Default = all the messages will be deleted");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+
+ }
+
+ private void setnumber(String number)
+ {
+ Integer i = new Integer(number);
+ this.number = i.intValue();
+ }
+
+ public int getnumber()
+ {
+ return this.number;
+ }
+
+ private static String removeSpaces(String s)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ", false);
+ String t = "";
+ while (st.hasMoreElements())
+ t += st.nextElement();
+ return t;
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandget.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandget.java
new file mode 100644
index 0000000000..cb67edeb34
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandget.java
@@ -0,0 +1,211 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands;
+
+import org.apache.qpid.commands.objects.ObjectNames;
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.utils.JMXinfo;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import java.util.Set;
+
+public class Commandget extends CommandImpl
+{
+
+ private String _attributeName;
+ private String _value;
+ public static final String COMMAND_NAME = "get";
+
+ public Commandget(JMXinfo info)
+ {
+ super(info);
+ }
+
+ private void getAttribute(String option_value)
+ {
+ if (option_value == null)
+ {
+ printusage();
+ return;
+ }
+ MBeanServerConnection mbsc = info.getmbserverconnector();
+ Set set = null;
+ ObjectNames objname = null;
+
+ try
+ {
+ if (option_value.compareToIgnoreCase("queue") == 0 || option_value.compareToIgnoreCase("queues") == 0)
+ {
+ objname = new QueueObject(mbsc);
+ }
+ else
+ {
+ printusage();
+ echo("Wrong objectName");
+ return;
+ }
+
+ if (_attributeName == null)
+ {
+ echo("attribute name not specified. See --help for details");
+ return;
+ }
+
+ objname.setQueryString(this.getObject(), this.getName(), this.getVirtualhost());
+ objname.returnObjects();
+
+ if (objname.getSet().size() != 1)
+ {
+ echo("Your query returned more than one object to set was this intended?\n" + objname.getQueryString());
+ }
+ else if (objname.getSet().size() == 1)
+ {
+ ObjectName object = (ObjectName) objname.getSet().iterator().next();
+
+ Object value = objname.getAttribute(object, _attributeName);
+
+ echo(value.toString());
+ }
+ else
+ {
+ if (hasName())
+ {
+
+ echo("You might be querying wrong " + this.getObject() + " name with --name or -n option ");
+ echo("");
+ echo("No " + this.getObject() + "Type Objects might not in the broker currently");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+ if (checkoptionsetting("output"))
+ {
+ setOutputFormat(optionchecker("output"));
+ if (checkoptionsetting("separator"))
+ {
+ setSeperator(optionchecker("separator"));
+ }
+ }
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ setObject(object);
+
+ if (checkoptionsetting("name") || checkoptionsetting("n"))
+ {
+ String name = optionchecker("name");
+ if (name == null)
+ {
+ name = optionchecker("n");
+ }
+
+ setName(name);
+ }
+
+ if (checkoptionsetting("attribute") || checkoptionsetting("a"))
+ {
+ String name = optionchecker("attribute");
+ if (name == null)
+ {
+ name = optionchecker("a");
+ }
+
+ setAttributeName(name);
+ }
+ if (checkoptionsetting("virtualhost") || checkoptionsetting("v"))
+ {
+ String vhost = optionchecker("virtualhost");
+ if (vhost == null)
+ {
+ vhost = optionchecker("v");
+ }
+ setVirtualhost(vhost);
+ }
+ getAttribute(this.getObject());
+ }
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ {
+ printusage();
+ }
+ else
+ {
+ unrecognizeoption();
+ }
+ }
+
+ private void setAttributeName(String name)
+ {
+ this._attributeName = name;
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:set [OPTION] ... [OBJECT TYPE]...\n");
+ echo("List the information about the given object\n");
+ echo("Where possible options include:\n");
+ echo(" -o --object type of objects which you want to list\n");
+ echo(" ex: < list -o queue > : lists all the queues created in the java broker\n");
+ echo(" For now list command is supporting following object typse \n");
+ echo(" Queue Connection VirtualHost UserMangement Exchange");
+ echo(" Or You can specify object type by giving it at the beginning");
+ echo(" rather giving it as a argument");
+ echo(" Ex:< queue list > this command is equal to list -o queue \n");
+ echo(" -v --virtualhost After specifying the object type you can filter output with this option");
+ echo(" list objects with the given virtualhost which will help to find ");
+ echo(" identical queue objects with -n option");
+ echo(" ex: queue list -v develop ment");
+ echo(" -n --name After specifying what type of objects you want to monitor you can filter");
+ echo(" the output using -n option by specifying the name of the object you want ");
+ echo(" to monitor exactly");
+ echo(" ex: <list -o queue -n ping> : list all the queue objects having queue name");
+ echo(" of ping");
+ echo(" ex: <queue list -n ping -v development> list all the queue objects with name ");
+ echo(" of ping and virtualhost of developement \n");
+ echo(" -a --attribute ");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandhelp.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandhelp.java
new file mode 100644
index 0000000000..502ac89f74
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandhelp.java
@@ -0,0 +1,56 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands;
+
+import org.apache.qpid.utils.JMXinfo;
+
+public class Commandhelp extends CommandImpl
+{
+
+ public static final String COMMAND_NAME = "help";
+
+ public Commandhelp(JMXinfo info)
+ {
+ }
+
+ public void execute()
+ {
+ printusage();
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Current version of qpid CLI is supporting following commands");
+ echo("");
+ echo("[list] This command is listing limited information about a given type of object");
+ echo(" For more information about list command run `list --help`");
+ echo("[info] This command is listing All the information about a given type of object");
+ echo(" For more information about list command run `info --help`");
+
+ echo("");
+ echo("[exit] This command is disconnect the connection with the Qpid Java broker and go back to normal propmt");
+ echo("[quit] This command is disconnect the connection with the Qpid Java broker and go back to normal propmt");
+ echo("");
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandinfo.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandinfo.java
new file mode 100644
index 0000000000..7094a8fc7f
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandinfo.java
@@ -0,0 +1,206 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands;
+
+import java.util.Set;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.commands.objects.AllObjects;
+import org.apache.qpid.commands.objects.ConnectionObject;
+import org.apache.qpid.commands.objects.ExchangeObject;
+import org.apache.qpid.commands.objects.ObjectNames;
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.commands.objects.UserManagementObject;
+import org.apache.qpid.commands.objects.VirtualHostObject;
+import org.apache.qpid.utils.JMXinfo;
+
+public class Commandinfo extends CommandImpl
+{
+
+ public static final String COMMAND_NAME = "info";
+
+ public Commandinfo(JMXinfo info)
+ {
+ super(info);
+ }
+
+ private void listobjects(String option_value)
+ {
+ /*
+ * pring usage if use is not give the correct option letter or no
+ * options
+ */
+ if (option_value == null)
+ {
+ // System.out.println("testing");
+ printusage();
+ return;
+ }
+ MBeanServerConnection mbsc = info.getmbserverconnector();
+ Set set = null;
+ ObjectNames objname = null;
+
+ try
+ {
+ if (option_value.compareToIgnoreCase("queue") == 0 || option_value.compareToIgnoreCase("queues") == 0)
+ {
+ objname = new QueueObject(mbsc);
+
+ }
+ else if (option_value.compareToIgnoreCase("Virtualhosts") == 0
+ || option_value.compareToIgnoreCase("Virtualhost") == 0)
+ {
+ objname = new VirtualHostObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Exchange") == 0
+ || option_value.compareToIgnoreCase("Exchanges") == 0)
+ {
+ objname = new ExchangeObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Connection") == 0
+ || option_value.compareToIgnoreCase("Connections") == 0)
+ {
+ objname = new ConnectionObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("all") == 0)
+ {
+ objname = new AllObjects(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Usermanagement") == 0
+ || option_value.compareToIgnoreCase("Usermanagmenets") == 0)
+ {
+ objname = new UserManagementObject(mbsc);
+ // this.name = option_value;
+ }
+ else
+ {
+ printusage();
+ echo("Wrong objectName");
+ return;
+ }
+ objname.setQueryString(this.getObject(), this.getName(), this.getVirtualhost());
+ objname.returnObjects();
+ if (objname.getSet().size() != 0)
+ {
+ objname.displayinfo(this.getOutputFormat(), this.getSeperator());
+
+ }
+ else
+ {
+ if (hasName())
+ {
+
+ echo("You might querying wrong " + this.getObject() + " name with --name or -n option ");
+ echo("");
+ echo("No "+this.getObject() + "Type Objects might not be in the broker currently");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+ if (checkoptionsetting("output"))
+ {
+ setOutputFormat(optionchecker("output"));
+ if (checkoptionsetting("separator"))
+ setSeperator(optionchecker("separator"));
+ }
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ setObject(object);
+ if (checkoptionsetting("name") || checkoptionsetting("n"))
+ {
+ String name = optionchecker("name");
+ if (name == null)
+ name = optionchecker("n");
+
+ setName(name);
+ }
+ if (checkoptionsetting("virtualhost") || checkoptionsetting("v"))
+ {
+ String vhost = optionchecker("virtualhost");
+ if (vhost == null)
+ vhost = optionchecker("v");
+ setVirtualhost(vhost);
+ }
+ listobjects(this.getObject());
+ }
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ printusage();
+ else
+ unrecognizeoption();
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:info [OPTION] ... [OBJECT TYPE]...\n");
+ echo("Give ALL the information about the given object\n");
+ echo("Where possible options include:\n");
+ echo(" -o --object type of objects which you want to list\n");
+ echo(" ex: < list -o queue > : lists all the queues created in the java broker\n");
+ echo(" For now list command is supporting following object typse \n");
+ echo(" Queue Connection VirtualHost UserMangement Exchange");
+ echo(" Or You can specify object type by giving it at the beginning rather giving ");
+ echo(" it as a argument");
+ echo(" Ex:< queue info > this command is equal to <info -o queue> command \n");
+ echo(" -v --virtualhost After specifying the object type you can filter output with this option");
+ echo(" list objects with the given virtualhost which will help to find identical");
+ echo(" queue objects with -n option");
+ echo(" ex: queue info -v developement");
+ echo(" -output Specify which output format you want to get the ouput");
+ echo(" Although the option is there current version supports only for CSV output format");
+ echo(" -separator This option use with output option to specify which separator you want to get the CSV output (default seperator is comma");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+ echo(" -n --name After specifying what type of objects you want to monitor you can filter");
+ echo(" the output using -n option by specifying the name of the object you want");
+ echo(" to monitor exactly");
+ echo(" ex: <queue info -n ping> : Give all the information about queue objects ");
+ echo(" having queue name of ping\n");
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandlist.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandlist.java
new file mode 100644
index 0000000000..68ee593ba0
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandlist.java
@@ -0,0 +1,232 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands;
+
+import java.util.Set;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.commands.objects.AllObjects;
+import org.apache.qpid.commands.objects.ConnectionObject;
+import org.apache.qpid.commands.objects.ExchangeObject;
+import org.apache.qpid.commands.objects.ObjectNames;
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.commands.objects.UserManagementObject;
+import org.apache.qpid.commands.objects.VirtualHostObject;
+import org.apache.qpid.utils.JMXinfo;
+
+public class Commandlist extends CommandImpl
+{
+
+ public static final String COMMAND_NAME = "list";
+
+ public Commandlist(JMXinfo info)
+ {
+ super(info);
+ }
+
+ private void listobjects(String option_value)
+ {
+ /*
+ * pring usage if use is not give the correct option letter or no
+ * options
+ */
+ if (option_value == null)
+ {
+ // System.out.println("testing");
+ printusage();
+ return;
+ }
+ MBeanServerConnection mbsc = info.getmbserverconnector();
+ Set set = null;
+ ObjectNames objname = null;
+
+ try
+ {
+ if (option_value.compareToIgnoreCase("queue") == 0 || option_value.compareToIgnoreCase("queues") == 0)
+ {
+ objname = new QueueObject(mbsc);
+
+ }
+ else if (option_value.compareToIgnoreCase("Virtualhosts") == 0
+ || option_value.compareToIgnoreCase("Virtualhost") == 0)
+ {
+ objname = new VirtualHostObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Exchange") == 0
+ || option_value.compareToIgnoreCase("Exchanges") == 0)
+ {
+ objname = new ExchangeObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Connection") == 0
+ || option_value.compareToIgnoreCase("Connections") == 0)
+ {
+ objname = new ConnectionObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("all") == 0)
+ {
+ objname = new AllObjects(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Usermanagement") == 0
+ || option_value.compareToIgnoreCase("Usermanagmenets") == 0)
+ {
+ objname = new UserManagementObject(mbsc);
+ // this.name = option_value;
+ }
+ else
+ {
+ printusage();
+ echo("Wrong objectName");
+ return;
+ }
+ objname.setQueryString(this.getObject(), this.getName(), this.getVirtualhost());
+ objname.returnObjects();
+ if (objname.getSet().size() != 0)
+ {
+ if (this.getObject().compareToIgnoreCase("queue") == 0
+ || this.getObject().compareToIgnoreCase("queues") == 0)
+ objname.displayqueues(this.getOutputFormat(), this.getSeperator());
+ else
+ objname.displayobjects(this.getOutputFormat(), this.getSeperator());
+ }
+ else
+ {
+ if (hasName())
+ {
+
+ echo("You might quering wrong " + this.getObject() + " name with --name or -n option ");
+ echo("");
+ echo(this.getObject() + "Type Objects might not in the broker currently");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void listdomains()
+ {
+ MBeanServerConnection mbsc = info.getmbserverconnector();
+ try
+ {
+ String[] domains = mbsc.getDomains();
+ echo("DOMAINS");
+ for (int i = 0; i < domains.length; i++)
+ echo("\tDomain[" + i + "] = " + domains[i]);
+
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+ if (checkoptionsetting("output"))
+ {
+ setOutputFormat(optionchecker("output"));
+ if (checkoptionsetting("separator"))
+ setSeperator(optionchecker("separator"));
+ }
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ setObject(object);
+ if (checkoptionsetting("name") || checkoptionsetting("n"))
+ {
+ String name = optionchecker("name");
+ if (name == null)
+ name = optionchecker("n");
+
+ setName(name);
+ }
+ if (checkoptionsetting("virtualhost") || checkoptionsetting("v"))
+ {
+ String vhost = optionchecker("virtualhost");
+ if (vhost == null)
+ vhost = optionchecker("v");
+ setVirtualhost(vhost);
+ }
+ listobjects(this.getObject());
+ }
+ else if (checkoptionsetting("domain") || checkoptionsetting("d"))
+ listdomains();
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ printusage();
+ else
+ unrecognizeoption();
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:list [OPTION] ... [OBJECT TYPE]...\n");
+ echo("List the information about the given object\n");
+ echo("Where possible options include:\n");
+ echo(" -o --object type of objects which you want to list\n");
+ echo(" ex: < list -o queue > : lists all the queues created in the java broker\n");
+ echo(" For now list command is supporting following object typse \n");
+ echo(" Queue Connection VirtualHost UserMangement Exchange");
+ echo(" Or You can specify object type by giving it at the beginning");
+ echo(" rather giving it as a argument");
+ echo(" Ex:< queue list > this command is equal to list -o queue \n");
+ echo(" -d --domain list all the domains of objects available for remote monitoring\n");
+ echo(" -v --virtualhost After specifying the object type you can filter output with this option");
+ echo(" list objects with the given virtualhost which will help to find ");
+ echo(" identical queue objects with -n option");
+ echo(" ex: queue list -v develop ment");
+ echo(" -output Specify which output format you want to get the ouput");
+ echo(" Although the option is there current version supports only for CSV output format");
+ echo(" -separator This option use with output option to specify which separator you want to get the CSV output (default seperator is comma");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+ echo(" -n --name After specifying what type of objects you want to monitor you can filter");
+ echo(" the output using -n option by specifying the name of the object you want ");
+ echo(" to monitor exactly");
+ echo(" ex: <list -o queue -n ping> : list all the queue objects having queue name");
+ echo(" of ping");
+ echo(" ex: <queue list -n ping -v development> list all the queue objects with name ");
+ echo(" of ping and virtualhost of developement \n");
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandmove.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandmove.java
new file mode 100644
index 0000000000..6d1803409b
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandmove.java
@@ -0,0 +1,259 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.utils.JMXinfo;
+
+public class Commandmove extends CommandImpl
+{
+
+ public static final String COMMAND_NAME = "move";
+
+ private String name1 = null, name2 = null, vhost1 = null, vhost2 = null, method1 = null, method2 = null; // target
+ // and
+ // starting
+ // queue
+ // specifications
+ // happen
+ // with
+ // these
+ // options
+ private QueueObject queue1;
+ private MBeanServerConnection mbsc;
+ private ObjectName queue;
+ private int fmid = 0, tmid = 0;
+
+ public Commandmove(JMXinfo info)
+ {
+ super(info);
+
+ this.mbsc = info.getmbserverconnector();
+ this.queue1 = new QueueObject(mbsc);
+ this.method1 = "moveMessages";
+ this.method2 = "getMessagesOnTheQueue";
+
+ }
+
+ public void movemessages()
+ {
+ Set set = null;
+ queue1.setQueryString(this.getObject(), this.name1, this.vhost1);
+ set = queue1.returnObjects();
+ if (queue1.getSet().size() != 0)
+ { // find the queue
+ Iterator it = set.iterator();
+ this.queue = (ObjectName) it.next();
+ }
+ else
+ {
+ if (isname1() || isname2())
+ { // if the specified queue is not there in the broker
+
+ echo("The Queue you have specified is not in the current broker");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+ try
+ {
+ Object[] params1 = { getfmid(), gettmid(), this.name2 };
+ String[] signature1 = { new String("long"), new String("long"), new String("java.lang.String") };
+ this.mbsc.invoke(this.queue, this.method1, params1, signature1);
+
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ echo("Given messageId's might be wrong please run the view command and check messageId's you have given\n");
+ echo("From MessageId should be greater than 0 and should less than To messageId");
+ }
+
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ if (object.compareToIgnoreCase("queue") == 0)
+ setObject(object);
+ else
+ {
+ unrecognizeoption();
+ echo("This command is only applicable for queue command so please start with queue");
+ }
+ if (checkoptionsetting("n2") && checkoptionsetting("n1"))
+ {
+ setname1(optionchecker("n1"));
+ setname2(optionchecker("n2"));
+ }
+ else
+ {
+ echo("You have to specify both n1 and n2 option value to move a message"); /*
+ * when
+ * user
+ * forget
+ * to
+ * specify
+ * target
+ * or
+ * starting
+ * queue
+ * name
+ */
+ return;
+ }
+
+ if (checkoptionsetting("v1"))
+ {
+
+ setvhost1(optionchecker("v1"));
+ }
+ if (checkoptionsetting("tmid") && checkoptionsetting("fmid"))
+ {
+ String tmid = optionchecker("tmid");
+ String fmid = optionchecker("fmid");
+
+ settomessageIdandfrommessageId(removeSpaces(tmid), removeSpaces(fmid));
+ }
+ else
+ {
+ echo("You have to set from MessageId and to MessageId in order to move messages between queues");
+ echo("To view MessageId's use <view> command with -n and -v options");
+ return;
+ }
+ this.movemessages();
+
+ }
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ printusage();
+ else
+ unrecognizeoption();
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:move [OPTION] ... [OBJECT TYPE]...\n");
+ echo("Move the top most messages from the given queue object to the given destination object\n");
+ echo("To specify the desired queues you have to give the virtualhost name and the queue name with following commands\n");
+ echo("Where possible options include:\n");
+ echo(" -v1 Give the virtuallhost name from which queue you want to move messages");
+ echo(" -n1 Give the queue name which you want to move messages from");
+ echo(" -n2 Give the queue name of the destination queue");
+ echo(" -tmid Give From MessageId you want to move from the Queue");
+ echo(" -fmid Give To MessageId you want to move from the Queue");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+
+ }
+
+ private void setname1(String name)
+ {
+ this.name1 = name;
+ }
+
+ private void setname2(String name)
+ {
+ this.name2 = name;
+ }
+
+ private boolean isname1()
+ {
+ if (this.name1 == null)
+ return false;
+
+ else
+ return true;
+ }
+
+ private boolean isname2()
+ {
+ if (this.name2 == null)
+ return false;
+
+ else
+ return true;
+ }
+
+ private void setvhost1(String vhost)
+ {
+ this.vhost1 = vhost;
+ }
+
+ private static String removeSpaces(String s)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ", false);
+ String t = "";
+ while (st.hasMoreElements())
+ t += st.nextElement();
+ return t;
+ }
+
+ private void settomessageIdandfrommessageId(String tmid, String fmid)
+ {
+ Integer i = new Integer(tmid);
+ Integer j = new Integer(fmid);
+ this.tmid = i.intValue();
+ this.fmid = j.intValue();
+ }
+
+ public int gettmid()
+ {
+ return this.tmid;
+ }
+
+ public int getfmid()
+ {
+ return this.fmid;
+ }
+
+ public String getname1()
+ {
+ return this.name1;
+ }
+
+ public String getname2()
+ {
+ return this.name2;
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandset.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandset.java
new file mode 100644
index 0000000000..e70b7b17ad
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandset.java
@@ -0,0 +1,260 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands;
+
+import org.apache.qpid.commands.objects.ObjectNames;
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.utils.JMXinfo;
+
+import javax.management.Attribute;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import java.util.Set;
+
+public class Commandset extends CommandImpl
+{
+ private String _attributeName;
+ private String _value;
+ public static final String COMMAND_NAME = "set";
+
+ public Commandset(JMXinfo info)
+ {
+ super(info);
+ }
+
+ private void setAttribute(String option_value)
+ {
+ /*
+ * print usage if use is not give the correct option letter or no
+ * options
+ */
+ if (option_value == null)
+ {
+ printusage();
+ return;
+ }
+ MBeanServerConnection mbsc = info.getmbserverconnector();
+ Set set = null;
+ ObjectNames objname = null;
+
+ try
+ {
+ if (option_value.compareToIgnoreCase("queue") == 0 || option_value.compareToIgnoreCase("queues") == 0)
+ {
+ objname = new QueueObject(mbsc);
+ }
+ else
+ {
+ printusage();
+ echo("Wrong objectName");
+ return;
+ }
+
+ if (_attributeName == null)
+ {
+ echo("attribute name not specified. See --help for details");
+ return;
+ }
+
+ if (_value == null)
+ {
+ echo("new value not specified. See --help for details");
+ return;
+ }
+
+ objname.setQueryString(this.getObject(), this.getName(), this.getVirtualhost());
+ objname.returnObjects();
+
+ if (objname.getSet().size() != 1)
+ {
+ echo("Your query returned more than one object to set was this intended?" + objname.getQueryString());
+ }
+ else if (objname.getSet().size() == 1)
+ {
+ ObjectName object = (ObjectName) objname.getSet().iterator().next();
+
+ Object value = objname.getAttribute(object, _attributeName);
+
+ Object attributeValue = _value;
+
+ try
+ {
+ if (value instanceof Integer)
+ {
+ attributeValue = Integer.valueOf(_value);
+ }
+ else if (value instanceof Long)
+ {
+ attributeValue = Long.valueOf(_value);
+ }
+ }
+ catch (NumberFormatException nfe)
+ {
+ echo("Value(" + _attributeName + ") should be of type " + value.getClass().getName());
+ return;
+ }
+
+ Attribute attribute = new Attribute(_attributeName, attributeValue);
+
+ objname.setAttribute(object, attribute);
+ }
+ else
+ {
+ if (hasName())
+ {
+
+ echo("You might be querying wrong " + this.getObject() + " name with --name or -n option ");
+ echo("");
+ echo("No " + this.getObject() + "Type Objects might not in the broker currently");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+ if (checkoptionsetting("output"))
+ {
+ setOutputFormat(optionchecker("output"));
+ if (checkoptionsetting("separator"))
+ {
+ setSeperator(optionchecker("separator"));
+ }
+ }
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ setObject(object);
+
+ if (checkoptionsetting("name") || checkoptionsetting("n"))
+ {
+ String name = optionchecker("name");
+ if (name == null)
+ {
+ name = optionchecker("n");
+ }
+
+ setName(name);
+ }
+
+ if (checkoptionsetting("attribute") || checkoptionsetting("a"))
+ {
+ String name = optionchecker("attribute");
+ if (name == null)
+ {
+ name = optionchecker("a");
+ }
+
+ setAttributeName(name);
+ }
+
+ if (checkoptionsetting("set") || checkoptionsetting("s"))
+ {
+ String value = optionchecker("set");
+ if (value == null)
+ {
+ value = optionchecker("s");
+ }
+
+ setAttributeValue(value);
+ }
+
+ if (checkoptionsetting("virtualhost") || checkoptionsetting("v"))
+ {
+ String vhost = optionchecker("virtualhost");
+ if (vhost == null)
+ {
+ vhost = optionchecker("v");
+ }
+ setVirtualhost(vhost);
+ }
+ setAttribute(this.getObject());
+ }
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ {
+ printusage();
+ }
+ else
+ {
+ unrecognizeoption();
+ }
+ }
+
+ private void setAttributeValue(String value)
+ {
+ _value = value;
+ }
+
+ private void setAttributeName(String name)
+ {
+ this._attributeName = name;
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:set [OPTION] ... [OBJECT TYPE]...\n");
+ echo("List the information about the given object\n");
+ echo("Where possible options include:\n");
+ echo(" -o --object type of objects which you want to list\n");
+ echo(" ex: < list -o queue > : lists all the queues created in the java broker\n");
+ echo(" For now list command is supporting following object typse \n");
+ echo(" Queue Connection VirtualHost UserMangement Exchange");
+ echo(" Or You can specify object type by giving it at the beginning");
+ echo(" rather giving it as a argument");
+ echo(" Ex:< queue list > this command is equal to list -o queue \n");
+ echo(" -v --virtualhost After specifying the object type you can filter output with this option");
+ echo(" list objects with the given virtualhost which will help to find ");
+ echo(" identical queue objects with -n option");
+ echo(" ex: queue list -v develop ment");
+ echo(" -n --name After specifying what type of objects you want to monitor you can filter");
+ echo(" the output using -n option by specifying the name of the object you want ");
+ echo(" to monitor exactly");
+ echo(" ex: <list -o queue -n ping> : list all the queue objects having queue name");
+ echo(" of ping");
+ echo(" ex: <queue list -n ping -v development> list all the queue objects with name ");
+ echo(" of ping and virtualhost of developement \n");
+ echo(" -a --attribute ");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandview.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandview.java
new file mode 100644
index 0000000000..e3bcc7e543
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandview.java
@@ -0,0 +1,255 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularDataSupport;
+
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.utils.JMXinfo;
+
+public class Commandview extends CommandImpl
+{
+
+ public static final String COMMAND_NAME = "view";
+
+ private int number = 0;
+ private QueueObject objname;
+ private MBeanServerConnection mbsc;
+ private String method1;
+ private ObjectName queue;
+
+ public Commandview(JMXinfo info)
+ {
+ super(info);
+ this.mbsc = info.getmbserverconnector();
+ this.objname = new QueueObject(mbsc);
+ this.method1 = "viewMessages";
+
+ }
+
+ public void viewmessages()
+ {
+ objname.setQueryString(this.getObject(), this.getName(), this.getVirtualhost());
+ Set set = objname.returnObjects();
+ String header = "", temp_header = "", message_data = "", outline = "";
+
+ if (objname.getSet().size() != 0)
+ {
+ Iterator it = set.iterator();
+ this.queue = (ObjectName) it.next();
+ try
+ {
+ if (objname.getmessagecount(this.queue) == 0)
+ {
+ echo("Selected Queue doesn't contain any messages");
+ return;
+ }
+ if (this.number == 0)
+ this.number = objname.getmessagecount(this.queue);
+
+ if (objname.getmessagecount(this.queue) < this.number)
+ {
+ echo("Given number is Greater than the Queue Depth");
+ return;
+ }
+ else
+ {
+ Object[] params = { 1, this.number };
+ String[] signature = { new String("int"), new String("int") };
+ TabularDataSupport data = (TabularDataSupport) this.mbsc.invoke(queue, this.method1, params,
+ signature);
+
+ Set entrySet = data.entrySet();
+ ArrayList<Map.Entry> list = new ArrayList<Map.Entry>(entrySet);
+ if (list.size() != 0)
+ {// no data}
+ for (int i = 0; i < list.size(); i++)
+ {
+ CompositeData compositedata = (CompositeData) (list.get(i)).getValue();
+ List<String> itemNames = new ArrayList<String>(compositedata.getCompositeType().keySet());
+ if (i == 0) // display the table headers
+ {
+ for (int j = 0; j < itemNames.size(); j++)
+ {
+ temp_header = "";
+ if (j != 1) // skipping header information
+ {
+ temp_header = itemNames.get(j);
+ while (temp_header.length() < 15)
+ temp_header = " " + temp_header;
+
+ header = header + temp_header + "|";
+ }
+ else
+ continue;
+ }
+ echo(header);
+ while (outline.length() < header.length())
+ outline = outline + "-";
+ echo(outline);
+ }
+
+ for (int j = 0; j < itemNames.size(); j++)
+ {
+ temp_header = "";
+ if (j != 1)
+ {
+ temp_header = String.valueOf(compositedata.get(itemNames.get(j)));
+ while (temp_header.length() < 15)
+ temp_header = " " + temp_header;
+ message_data = message_data + temp_header + "|";
+ }
+ else
+ // header information is not displaying
+ // unless user specify header information is
+ // needed
+ continue;
+
+ }
+ echo(message_data);
+ header = "";
+ message_data = "";
+ }
+ }
+ else
+ {
+ System.out.println("No Data to Display");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+ else
+ {
+ if (hasName())
+ {
+
+ echo("The Queue you have specified is not in the current broker");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ if (object.compareToIgnoreCase("queue") == 0)
+ setObject(object);
+ else
+ {
+ unrecognizeoption();
+ echo("This command is only applicable for delete command so please start with queue");
+ }
+ if (checkoptionsetting("name") || checkoptionsetting("n"))
+ {
+ String name = optionchecker("name");
+ if (name == null)
+ name = optionchecker("n");
+
+ setName(name);
+ }
+ if (checkoptionsetting("virtualhost") || checkoptionsetting("v"))
+ {
+ String vhost = optionchecker("virtualhost");
+ if (vhost == null)
+ vhost = optionchecker("v");
+ setVirtualhost(vhost);
+ }
+ if (checkoptionsetting("top") || checkoptionsetting("t"))
+ {
+ String number = optionchecker("top");
+ if (number == null)
+ number = optionchecker("t");
+
+ setnumber(removeSpaces(number));
+ }
+ this.viewmessages();
+ }
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ printusage();
+ else
+ unrecognizeoption();
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:view [OPTION] ... [OBJECT TYPE]...\n");
+ echo("view the information about given number of messages from the given queue object\n");
+ echo("To specify the desired queue you have to give the virtualhost name and the queue name with following commands\n");
+ echo("Where possible options include:\n");
+ echo(" -v --virtualhost Give the virtuallhost name of the desired queue");
+ echo(" -n --name Give the queue name of the desired queue you want to view messages");
+ echo(" -t --top Give how many number of messages you want to delete from the top (Default = all the messages will be deleted");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+
+ }
+
+ private void setnumber(String number)
+ {
+ Integer i = new Integer(number);
+ this.number = i.intValue();
+ }
+
+ private static String removeSpaces(String s)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ", false);
+ String t = "";
+ while (st.hasMoreElements())
+ t += st.nextElement();
+ return t;
+ }
+
+ public int getnumber()
+ {
+ return number;
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandviewcontent.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandviewcontent.java
new file mode 100644
index 0000000000..d1ae1c1893
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandviewcontent.java
@@ -0,0 +1,248 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.commands;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.utils.JMXinfo;
+
+public class Commandviewcontent extends CommandImpl
+{
+
+ public static final String COMMAND_NAME = "viewcontent";
+
+ private long number = 0;
+ private QueueObject objname;
+ private MBeanServerConnection mbsc;
+ private String method1;
+ private ObjectName queue;
+
+ public Commandviewcontent(JMXinfo info)
+ {
+ super(info);
+ this.mbsc = info.getmbserverconnector();
+ this.objname = new QueueObject(mbsc);
+ this.method1 = "viewMessageContent";
+
+ }
+
+ public void viewcontent()
+ {
+ objname.setQueryString(getObject(), getName(), getVirtualhost());
+ Set set = objname.returnObjects();
+ String temp_header = "", header = "", message_data = "", encoding = null;
+
+ if (objname.getSet().size() != 0)
+ {
+ Iterator it = set.iterator();
+ this.queue = (ObjectName) it.next();
+ try
+ {
+ if (objname.getmessagecount(this.queue) == 0)
+ {
+ echo("Selected Queue doesn't contain any messages");
+ return;
+ }
+ if (this.number == 0)
+ {
+ echo("You haven't selected a MessageId Please use -id and give a message id");
+ echo("Or run view command with same arguemnts to view messageId list for the queue");
+ }
+ else
+ {
+ Object[] params = { this.number };
+ String[] signature = { new String("long") };
+ CompositeData data = (CompositeData) this.mbsc.invoke(queue, this.method1, params, signature);
+ List<String> itemNames = new ArrayList<String>(data.getCompositeType().keySet());
+ for (int j = 0; j < itemNames.size(); j++)
+ {
+ temp_header = "";
+ temp_header = itemNames.get(j);
+ while (temp_header.length() < 15)
+ temp_header = " " + temp_header;
+
+ header = header + temp_header + "|";
+ }
+ echo(header);
+ encoding = String.valueOf(data.get(itemNames.get(2))); // set
+ // the
+ // encoding
+ // at
+ // the
+ // beginning
+ // because
+ // encoding
+ // comes
+ // later
+ // in
+ // the
+ // loop
+ if (encoding == null || encoding.length() == 0)
+ {
+ encoding = Charset.defaultCharset().name();
+
+ }
+ for (int j = 0; j < itemNames.size(); j++)
+ {
+ temp_header = "";
+ if (j != 1)
+ {
+ temp_header = String.valueOf(data.get(itemNames.get(j)));
+ while (temp_header.length() < 15)
+ temp_header = " " + temp_header;
+ }
+ else
+ {
+ Byte[] arrayItems = (Byte[]) data.get(itemNames.get(j));
+ byte[] byteArray = new byte[arrayItems.length];
+ for (int i = 0; i < arrayItems.length; i++)
+ {
+ byteArray[i] = arrayItems[i];
+ temp_header = new String(byteArray, encoding);
+ while (temp_header.length() < 15)
+ temp_header = " " + temp_header;
+ }
+ }
+ message_data = message_data + temp_header + "|";
+
+ }
+ echo(message_data);
+ }
+ }
+ catch (Exception ex)
+ {
+ echo("Given MessageId is invalid, There's no message with the given messageId");
+ ex.printStackTrace();
+ return;
+ }
+
+ }
+ else
+ {
+ if (hasName())
+ {
+
+ echo("The Queue you have specified is not in the current broker");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ if (object.compareToIgnoreCase("queue") == 0)
+ setObject(object);
+ else
+ {
+ unrecognizeoption();
+ echo("This command is only applicable for delete command so please start with queue");
+ }
+ if (checkoptionsetting("name") || checkoptionsetting("n"))
+ {
+ String name = optionchecker("name");
+ if (name == null)
+ name = optionchecker("n");
+
+ setName(name);
+ }
+ if (checkoptionsetting("virtualhost") || checkoptionsetting("v"))
+ {
+ String vhost = optionchecker("virtualhost");
+ if (vhost == null)
+ vhost = optionchecker("v");
+ setVirtualhost(vhost);
+ }
+ if (checkoptionsetting("messageid") || checkoptionsetting("id"))
+ {
+ String number = optionchecker("id");
+ if (number == null)
+ number = optionchecker("id");
+
+ setnumber(removeSpaces(number));
+ }
+ this.viewcontent();
+ }
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ printusage();
+ else
+ unrecognizeoption();
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:viewcontent [OPTION] ... [OBJECT TYPE]...\n");
+ echo("view the information about given number of messages from the given queue object\n");
+ echo("To specify the desired queue you have to give the virtualhost name and the queue name with following commands\n");
+ echo("Where possible options include:\n");
+ echo(" -v --virtualhost Give the virtuallhost name of the desired queue");
+ echo(" -n --name Give the queue name of the desired queue you want to view messages");
+ echo(" -id Give the messageId of the required message you want to view the content");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+
+ }
+
+ private void setnumber(String number)
+ {
+ this.number = Long.valueOf(number);
+ }
+
+ private static String removeSpaces(String s)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ", false);
+ String t = "";
+ while (st.hasMoreElements())
+ t += st.nextElement();
+ return t;
+ }
+
+ public long getnumber()
+ {
+ return this.number;
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/AllObjects.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/AllObjects.java
new file mode 100644
index 0000000000..8b2099f3e0
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/AllObjects.java
@@ -0,0 +1,38 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+public class AllObjects extends ObjectNames
+{
+
+ public AllObjects(MBeanServerConnection mbsc)
+ {
+ super(mbsc);
+ }
+
+ public void setQueryString(String object, String name)
+ {
+ querystring = "org.apache.qpid:*";
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ConnectionObject.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ConnectionObject.java
new file mode 100644
index 0000000000..2746b2016f
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ConnectionObject.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+public class ConnectionObject extends ObjectNames
+{
+ public ConnectionObject(MBeanServerConnection mbsc)
+ {
+ /* calling parent classes constructor */
+ super(mbsc);
+ }
+
+ public void setQueryString(String object, String name, String vhost)
+ {
+ if (name != null && vhost == null)
+ querystring = "org.apache.qpid:type=Connection,name=" + name + ",*";
+ else if (name != null && vhost != null)
+ querystring = "org.apache.qpid:type=Connection,VirtualHost=" + vhost + ",name=" + name + ",*";
+ else if (name == null && vhost != null)
+ querystring = "org.apache.qpid:type=Connection,VirtualHost=" + vhost + ",*";
+ else
+ querystring = "org.apache.qpid:type=Connection,*";
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ExchangeObject.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ExchangeObject.java
new file mode 100644
index 0000000000..96d7e6e5dc
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ExchangeObject.java
@@ -0,0 +1,45 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+public class ExchangeObject extends ObjectNames
+{
+ public ExchangeObject(MBeanServerConnection mbsc)
+ {
+ super(mbsc);
+ }
+
+ public void setQueryString(String object, String name, String vhost)
+ {
+ if (name != null && vhost == null)
+ querystring = "org.apache.qpid:type=VirtualHost.Exchange,name=" + name + ",*";
+ else if (name != null && vhost != null)
+ querystring = "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=" + vhost + ",name=" + name + ",*";
+ else if (name == null && vhost != null)
+ querystring = "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=" + vhost + ",*";
+ else
+ querystring = "org.apache.qpid:type=VirtualHost.Exchange,*";
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ObjectNames.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ObjectNames.java
new file mode 100644
index 0000000000..1432f18018
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ObjectNames.java
@@ -0,0 +1,591 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands.objects;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.Attribute;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.common.mbeans.ManagedQueue;
+
+public class ObjectNames
+{
+ public String querystring = null;
+ public MBeanServerConnection mbsc;
+ public Set<ObjectName> set = null;
+ public String attributes = "";
+ public String attributevalues = "";// = null;
+
+ private static final Map<String,Integer> QUEUE_ATTRIBUTES = new HashMap<String,Integer>();
+ static
+ {
+ QUEUE_ATTRIBUTES.put(ManagedQueue.ATTR_NAME, 1);
+ QUEUE_ATTRIBUTES.put(ManagedQueue.ATTR_DURABLE, 2);
+ QUEUE_ATTRIBUTES.put(ManagedQueue.ATTR_ACTIVE_CONSUMER_COUNT, 3);
+ QUEUE_ATTRIBUTES.put(ManagedQueue.ATTR_MSG_COUNT, 4);
+ QUEUE_ATTRIBUTES.put(ManagedQueue.ATTR_RCVD_MSG_COUNT, 5);
+ }
+
+ public ObjectNames(MBeanServerConnection mbsc)
+ {
+ this.mbsc = mbsc;
+ }
+
+ public Set<ObjectName> returnObjects()
+ {
+ try
+ {
+ set = mbsc.queryNames(new ObjectName(querystring), null);
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ return set;
+ }
+
+ public void echo(String str)
+ {
+ System.out.println(str);
+ }
+
+ /* display appropriate objects according to the ojbect type */
+
+ public void displayobjects(String output, String seperator)
+ {
+ Iterator it = set.iterator();
+ String line = "";
+ String temp2 = "";
+ int iterator = 0;
+ try
+ {
+ do
+ {
+ ObjectName temp_object = null;
+ if (it.hasNext())
+ {
+ temp_object = (ObjectName) it.next();
+ if (temp_object == null)
+ System.out.println("null test");
+ }
+ // echo(temp_object.getCanonicalKeyPropertyListString());
+ MBeanInfo bean_info = mbsc.getMBeanInfo(temp_object);
+ MBeanAttributeInfo[] attr_info = bean_info.getAttributes();
+ if (attr_info == null)
+ {
+ echo(temp_object.toString());
+ String temp = "";
+ while (temp_object.toString().length() > temp.length())
+ temp = "=" + temp;
+ if (output == null)
+ echo(temp);
+
+ }
+ else
+ {
+ for (MBeanAttributeInfo attr : attr_info)
+ {
+ Object toWrite = null;
+
+ try
+ {
+ String temp1 = attr.getName();
+ if (output == null)
+ {
+ while (temp1.length() < 15)
+ temp1 = " " + temp1;
+ attributes = attributes + temp1 + "|";
+ }
+ else if (output.compareToIgnoreCase("csv") == 0)
+ attributes = attributes + temp1 + seperator;
+ else
+ {
+ echo("Wrong output format current version is supporting only for CSV");
+ return;
+ }
+ }
+ catch (Exception x)
+ {
+ x.printStackTrace();
+ }
+ }
+ if (attributes.equalsIgnoreCase(""))
+ {
+ echo(temp_object.toString());
+ String temp = "";
+ while (temp_object.toString().length() > temp.length())
+ temp = "=" + temp;
+ echo(temp);
+ echo("There are no attributes for this object Type");
+ continue;
+ }
+ for (MBeanAttributeInfo attr : attr_info)
+ {
+ Object toWrite = null;
+ temp2 = null;
+ try
+ {
+ toWrite = mbsc.getAttribute(temp_object, attr.getName());
+ }
+ catch (Exception x)
+ {
+ temp2 = "-";
+ }
+ if (toWrite != null)
+ temp2 = toWrite.toString();
+ else
+ temp2 = "-";
+ if (output == null)
+ {
+
+ while (temp2.length() < 15)
+ temp2 = " " + temp2;
+
+ attributevalues = attributevalues + temp2 + "|";
+ }
+ else if (output.compareToIgnoreCase("csv") == 0)
+ attributevalues = attributevalues + temp2 + seperator;
+
+ // echo(temp1 + " " + temp2 + " " + temp3);
+
+ }
+ }
+ iterator++;
+ if (iterator == 1)
+ {
+ echo(attributes);
+ for (int i = 0; i < attributes.length(); i++)
+ line = line + "-";
+ if (output == null)
+ echo(line);
+ }
+ echo(attributevalues);
+ line = "";
+ attributes = "";
+ attributevalues = "";
+ } while (it.hasNext());
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void reportgenerator(String output, String seperator, List<String> column)
+ {
+ Iterator it = set.iterator();
+ String line = "";
+ String temp2 = "";
+ int iterator = 0;
+ try
+ {
+ do
+ {
+ ObjectName temp_object = null;
+ if (it.hasNext())
+ {
+ temp_object = (ObjectName) it.next();
+ if (temp_object == null)
+ System.out.println("null test");
+ }
+ // echo(temp_object.getCanonicalKeyPropertyListString());
+ MBeanInfo bean_info = mbsc.getMBeanInfo(temp_object);
+ MBeanAttributeInfo[] attr_info = bean_info.getAttributes();
+ if (attr_info == null)
+ {
+ echo(temp_object.toString());
+ String temp = "";
+ while (temp_object.toString().length() > temp.length())
+ temp = "=" + temp;
+ if (output == null)
+ echo(temp);
+
+ }
+ else
+ {
+ for (MBeanAttributeInfo attr : attr_info)
+ {
+ Object toWrite = null;
+
+ try
+ {
+ String temp1 = attr.getName();
+ if (column.contains(temp1))
+ {
+ if (output == null)
+ {
+ while (temp1.length() < 15)
+ temp1 = " " + temp1;
+ attributes = attributes + temp1 + "|";
+ }
+ else if (output.compareToIgnoreCase("csv") == 0)
+ attributes = attributes + temp1 + seperator;
+ else
+ {
+ echo("Wrong output format current version is supporting only for CSV");
+ return;
+ }
+ }
+ }
+ catch (Exception x)
+ {
+ x.printStackTrace();
+ }
+ }
+ if (attributes.equalsIgnoreCase(""))
+ {
+ echo(temp_object.toString());
+ String temp = "";
+ while (temp_object.toString().length() > temp.length())
+ temp = "=" + temp;
+ echo(temp);
+ echo("There are no attributes for this object Type");
+ return;
+ }
+ for (MBeanAttributeInfo attr : attr_info)
+ {
+ Object toWrite = null;
+ temp2 = null;
+ if (column.contains(attr.getName()))
+ {
+ try
+ {
+ toWrite = mbsc.getAttribute(temp_object, attr.getName());
+ }
+ catch (Exception x)
+ {
+ temp2 = "-";
+ }
+ if (toWrite != null)
+ temp2 = toWrite.toString();
+ else
+ temp2 = "-";
+ if (output == null)
+ {
+
+ while (temp2.length() < 15)
+ temp2 = " " + temp2;
+
+ attributevalues = attributevalues + temp2 + "|";
+ }
+ else if (output.compareToIgnoreCase("csv") == 0)
+ attributevalues = attributevalues + temp2 + seperator;
+
+ // echo(temp1 + " " + temp2 + " " + temp3);
+
+ }
+
+ }
+ }
+ iterator++;
+ if (iterator == 1)
+ {
+ echo(attributes);
+ for (int i = 0; i < attributes.length(); i++)
+ line = line + "-";
+ if (output == null)
+ echo(line);
+ }
+ echo(attributevalues);
+ line = "";
+ attributes = "";
+ attributevalues = "";
+ } while (it.hasNext());
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void displayqueues(String output, String seperator)
+ {
+ Iterator it = set.iterator();
+ String line = "";
+ int iterator = 0;
+ String temp1 = "";
+ String temp2 = "";
+ try
+ {
+ do
+ {
+ ObjectName temp_object = null;
+ if (it.hasNext())
+ {
+ temp_object = (ObjectName) it.next();
+ }
+ // echo(temp_object.getCanonicalKeyPropertyListString());
+ MBeanInfo bean_info = mbsc.getMBeanInfo(temp_object);
+ MBeanAttributeInfo[] attr_info = bean_info.getAttributes();
+ if (attr_info == null)
+ {
+ echo(temp_object.toString());
+ String temp = "";
+ while (temp_object.toString().length() > temp.length())
+ temp = "=" + temp;
+ if (output == null)
+ echo(temp);
+
+ }
+ else
+ {
+ for (MBeanAttributeInfo attr : attr_info)
+ {
+ Object toWrite = null;
+ Integer attr_count = QUEUE_ATTRIBUTES.get(attr.getName());
+
+ if(attr_count == null)
+ {
+ continue;
+ }
+
+ try
+ {
+ toWrite = mbsc.getAttribute(temp_object, attr.getName());
+ if (output == null)
+ {
+ switch (attr_count)
+ {
+ case 1:
+ case 2:
+ temp1 = attr.getName();
+ while (temp1.length() < 10)
+ temp1 = " " + temp1;
+ attributes = attributes + temp1 + "|";
+ temp2 = toWrite.toString();
+ while (temp2.length() < 10)
+ temp2 = " " + temp2;
+ attributevalues = attributevalues + temp2 + "|";
+ break;
+ case 3:
+ temp1 = attr.getName();
+ while (temp1.length() < 20)
+ temp1 = " " + temp1;
+ attributes = attributes + temp1 + "|";
+ temp2 = toWrite.toString();
+ while (temp2.length() < 20)
+ temp2 = " " + temp2;
+ attributevalues = attributevalues + temp2 + "|";
+ break;
+ case 4:
+ temp1 = attr.getName();
+ while (temp1.length() < 13)
+ temp1 = " " + temp1;
+ attributes = attributes + temp1 + "|";
+ temp2 = toWrite.toString();
+ while (temp2.length() < 13)
+ temp2 = " " + temp2;
+ attributevalues = attributevalues + temp2 + "|";
+ break;
+ case 5:
+ temp1 = attr.getName();
+ while (temp1.length() < 20)
+ temp1 = " " + temp1;
+ attributes = attributes + temp1 + "|";
+ temp2 = toWrite.toString();
+ while (temp2.length() < 20)
+ temp2 = " " + temp2;
+ attributevalues = attributevalues + temp2 + "|";
+ break;
+ }
+ }
+ else if (output.compareToIgnoreCase("csv") == 0)
+ {
+ temp1 = attr.getName();
+ attributes = attributes + temp1 + seperator;
+ temp2 = toWrite.toString();
+ attributevalues = attributevalues + temp2 + seperator;
+ }
+ else
+ {
+ echo("Wrong output format specified currently CLI supports only csv output format");
+ return;
+ }
+
+ }
+ catch (Exception x)
+ {
+ x.printStackTrace();
+ }
+
+ }
+ }
+ iterator++;
+ if (iterator == 1)
+ {
+ for (int i = 0; i < attributes.length(); i++)
+ line = line + "-";
+ if (output == null)
+ echo(line);
+ echo(attributes);
+ if (output == null)
+ echo(line);
+ }
+ echo(attributevalues);
+ line = "";
+ attributes = "";
+ attributevalues = "";
+ } while (it.hasNext());
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ public void displayinfo(String output, String seperator)
+ {
+ Iterator it = set.iterator();
+ String temp1, temp2 = "";
+ try
+ {
+ do
+ {
+
+ ObjectName temp_object = null;
+ if (it.hasNext())
+ {
+ temp_object = (ObjectName) it.next();
+ }
+ // echo(temp_object.getCanonicalKeyPropertyListString());
+ MBeanInfo bean_info = mbsc.getMBeanInfo(temp_object);
+ MBeanAttributeInfo[] attr_info = bean_info.getAttributes();
+ if (attr_info == null)
+ {
+ echo(temp_object.toString());
+ String temp = "";
+ while (temp_object.toString().length() > temp.length())
+ temp = "=" + temp;
+ echo(temp);
+
+ }
+ else
+ {
+ echo(temp_object.toString());
+ String temp = "";
+ while (temp_object.toString().length() > temp.length())
+ temp = "=" + temp;
+ echo(temp);
+
+ for (MBeanAttributeInfo attr : attr_info)
+ {
+ Object toWrite = null;
+
+ try
+ {
+ toWrite = mbsc.getAttribute(temp_object, attr.getName());
+ }
+ catch (Exception x)
+ {
+ temp2 = "-";
+ }
+ temp1 = attr.getName();
+ if (toWrite != null)
+ temp2 = toWrite.toString();
+
+ if (output == null)
+ {
+ while (temp1.length() < 35)
+ temp1 = " " + temp1;
+
+ while (temp2.length() < 35)
+ temp2 = " " + temp2;
+ echo(temp1 + " " + temp2);
+ }
+ else if (output.compareToIgnoreCase("csv") == 0)
+ echo(temp1 + seperator + temp2);
+ else
+ {
+ echo("Wrong output format specified currently CLI supports only csv output format");
+ return;
+ }
+ }
+ echo("");
+ echo("");
+
+ }
+ } while (it.hasNext());
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void setQueryString(String object, String name, String vhost)
+ {
+
+ }
+
+ public void setQueryStringforinfo(String object, String name, String virtualhost)
+ {
+
+ }
+
+ public String getQueryString()
+ {
+ return querystring;
+ }
+
+ public Set getSet()
+ {
+ return set;
+ }
+
+ public Object getAttribute(ObjectName object, String attribute)
+ {
+ try
+ {
+ return mbsc.getAttribute(object, attribute);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ public void setAttribute(ObjectName object, Attribute attribute)
+ {
+ try
+ {
+ mbsc.setAttribute(object, attribute);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/QueueObject.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/QueueObject.java
new file mode 100644
index 0000000000..fcf0464ced
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/QueueObject.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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.common.mbeans.ManagedQueue;
+
+public class QueueObject extends ObjectNames
+{
+ public QueueObject(MBeanServerConnection mbsc)
+ {
+ super(mbsc);
+ }
+
+ public void setQueryString(String object, String name, String vhost)
+ {
+ if (name != null && vhost == null)
+ querystring = "org.apache.qpid:type=VirtualHost.Queue,name=" + name + ",*";
+ else if (name != null && vhost != null)
+ querystring = "org.apache.qpid:type=VirtualHost.Queue,VirtualHost=" + vhost + ",name=" + name + ",*";
+ else if (name == null && vhost != null)
+ querystring = "org.apache.qpid:type=VirtualHost.Queue,VirtualHost=" + vhost + ",*";
+ else
+ querystring = "org.apache.qpid:type=VirtualHost.Queue,*";
+ }
+
+ public int getmessagecount(ObjectName queue)
+ {
+ Number depth = null;
+
+ try
+ {
+ depth = (Number) mbsc.getAttribute(queue, ManagedQueue.ATTR_MSG_COUNT);
+
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ if (depth != null)
+ return depth.intValue();
+ else
+ return -1;
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/UserManagementObject.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/UserManagementObject.java
new file mode 100644
index 0000000000..fd5bc0ca72
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/UserManagementObject.java
@@ -0,0 +1,38 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+public class UserManagementObject extends ObjectNames
+{
+ public UserManagementObject(MBeanServerConnection mbsc)
+ {
+ super(mbsc);
+ }
+
+ public void setQueryString(String object, String name, String vhost)
+ {
+ querystring = "org.apache.qpid:type=UserManagement,*";
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/VirtualHostObject.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/VirtualHostObject.java
new file mode 100644
index 0000000000..77f8b66ac0
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/VirtualHostObject.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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+public class VirtualHostObject extends ObjectNames
+{
+
+ public VirtualHostObject(MBeanServerConnection mbsc)
+ {
+ super(mbsc);
+ }
+
+ public void setQueryString(String object, String name, String vhost)
+ {
+ if (name != null && vhost == null)
+ querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,name=" + name + ",*";
+ else if (name != null && vhost != null)
+ querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=" + vhost + ",name=" + name
+ + ",*";
+ else if (name == null && vhost != null)
+ querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=" + vhost + ",*";
+ else
+ querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,*";
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOption.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOption.java
new file mode 100644
index 0000000000..a443d6f789
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOption.java
@@ -0,0 +1,104 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.utils;
+
+import java.util.ArrayList;
+
+public class CommandLineOption implements CommandLineOptionConstants
+{
+ private String type;
+ private ArrayList optionValues;
+
+ public CommandLineOption(String type, String[] values)
+ {
+ setOptionType(type);
+ ArrayList arrayList = new ArrayList(values.length);
+ for (int i = 0; i < values.length; i++)
+ {
+ arrayList.add(values[i]);
+ }
+ this.optionValues = arrayList;
+ }
+
+ private void setOptionType(String type)
+ {
+ // cater for the long options first
+ if (type.startsWith("--"))
+ {
+ type = type.replaceFirst("--", "");
+ }
+ if (type.startsWith("-"))
+ {
+ type = type.replaceFirst("-", "");
+ }
+
+ // we do not change the case of the option!
+
+ this.type = type;
+ }
+
+ /**
+ * @param type
+ */
+ public CommandLineOption(String type, ArrayList values)
+ {
+ setOptionType(type);
+
+ if (null != values)
+ {
+ this.optionValues = values;
+ }
+ }
+
+ /**
+ * @return Returns the type.
+ * @see CommandLineOptionConstants
+ */
+ public String getOptionType()
+ {
+ return type;
+ }
+
+ /**
+ * @return Returns the optionValues.
+ */
+ public String getOptionValue()
+ {
+ if ((optionValues != null) && (optionValues.size() > 0))
+ {
+ return (String) optionValues.get(0);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * @return Returns the optionValues.
+ */
+ public ArrayList getOptionValues()
+ {
+ return optionValues;
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionConstants.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionConstants.java
new file mode 100644
index 0000000000..be82dbfcaa
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionConstants.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.utils;
+
+public interface CommandLineOptionConstants
+{
+ static interface JMXCommandLineOptionConstants
+ {
+ String HOST_OPTION = "h";
+ String PORT_OPTION = "p";
+ String INTERVAL_OPTION = "i";
+ String REPORT_OPTION = "r";
+ String USER_OPTION = "u";
+ String PASSWORD_OPTION = "w";
+
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionParser.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionParser.java
new file mode 100644
index 0000000000..fbf87bac01
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionParser.java
@@ -0,0 +1,231 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.utils;
+
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.StringTokenizer;
+
+public class CommandLineOptionParser
+{
+ private static int STARTED = 0;
+ private static int NEW_OPTION = 1;
+ private static int SUB_PARAM_OF_OPTION = 2;
+
+ private Map commandlineoption;
+ private String commandname;
+
+ public CommandLineOptionParser(Map commandlineoptions)
+ {
+ this.commandlineoption = commandlineoptions;
+ }
+
+ public CommandLineOptionParser(String[] args)
+ {
+ /* check whether user just type the enter key */
+ this.commandlineoption = this.parse(args);
+
+ }
+
+ public CommandLineOptionParser(String[] args, String first)
+ {
+ this.commandname = first;
+ this.commandlineoption = this.parsefirst(args);
+ }
+
+ public Map parse(String[] args)
+ {
+ Map commandLineOptions = new HashMap();
+
+ if (0 == args.length)
+ {
+ return commandLineOptions;
+ }
+ else if (1 == args.length)
+ {
+ commandname = args[0];
+ return commandLineOptions;
+ }
+ /* when user is not giving the command line option with a "=" */
+ // if (!args[2].startsWith("-"))
+ // return commandLineOptions;
+ // State 0 means started
+ // State 1 means earlier one was a new -option
+ // State 2 means earlier one was a sub param of a -option
+ int state = STARTED;
+ ArrayList optionBundle = null;
+ String optionType = null;
+ CommandLineOption commandLineOption;
+ String newcommand = "";
+ String[] newargs;
+ int j;
+ if (args[1].compareTo("list") == 0 || args[1].compareTo("info") == 0 || args[1].compareTo("delete") == 0
+ || args[1].compareTo("move") == 0 || args[1].compareTo("view") == 0
+ || args[1].compareTo("viewcontent") == 0)
+ {
+ String object = args[0];
+ for (j = 0; j < (args.length - 1); j++)
+ {
+ newcommand = newcommand + args[j + 1] + " ";
+ }
+ newcommand = newcommand + "-o " + object;
+ newargs = newcommand.split(" ");
+ args = newargs;
+ }
+ else if (!args[1].startsWith("-")) // if user give command like list
+ // queue or something without minus
+ // argument
+ return commandLineOptions; // for the second wordxi
+
+ commandname = args[0];
+ for (int i = 0; i < args.length; i++)
+ {
+ if (args[i].startsWith("-"))
+ {
+ if (STARTED == state)
+ {
+ // fresh one
+ state = NEW_OPTION;
+ optionType = args[i];
+ }
+ else if (SUB_PARAM_OF_OPTION == state || NEW_OPTION == state)
+ {
+ // new one but old one should be saved
+ commandLineOption = new CommandLineOption(optionType, optionBundle);
+ commandLineOptions.put(commandLineOption.getOptionType(), commandLineOption);
+ state = NEW_OPTION;
+ optionType = args[i];
+ optionBundle = null;
+
+ }
+ }
+ else
+ {
+ if (NEW_OPTION == state)
+ {
+ optionBundle = new ArrayList();
+ optionBundle.add(args[i]);
+ state = SUB_PARAM_OF_OPTION;
+
+ }
+ else if (SUB_PARAM_OF_OPTION == state)
+ {
+ optionBundle.add(args[i]);
+ }
+
+ }
+ }
+ commandLineOption = new CommandLineOption(optionType, optionBundle);
+ commandLineOptions.put(commandLineOption.getOptionType(), commandLineOption);
+ return commandLineOptions;
+
+ }
+
+ public Map parsefirst(String[] args)
+ {
+ Map commandLineOptions = new HashMap();
+ if (0 == args.length)
+ {
+ return commandLineOptions;
+ }
+ else if (1 == args.length)
+ {
+ return commandLineOptions;
+ }
+ /* when user is not giving the command line option with a "=" */
+ // if (!args[2].startsWith("-"))
+ // return commandLineOptions;
+ // State 0 means started
+ // State 1 means earlier one was a new -option
+ // State 2 means earlier one was a sub param of a -option
+ int state = STARTED;
+ ArrayList optionBundle = null;
+ String optionType = null;
+ CommandLineOption commandLineOption;
+ String newcommand = "";
+ String[] newargs;
+ int j;
+
+ for (int i = 0; i < args.length; i++)
+ {
+ if (args[i].startsWith("-"))
+ {
+ if (STARTED == state)
+ {
+ // fresh one
+ state = NEW_OPTION;
+ optionType = args[i];
+ }
+ else if (SUB_PARAM_OF_OPTION == state || NEW_OPTION == state)
+ {
+ // new one but old one should be saved
+ commandLineOption = new CommandLineOption(optionType, optionBundle);
+ commandLineOptions.put(commandLineOption.getOptionType(), commandLineOption);
+ state = NEW_OPTION;
+ optionType = args[i];
+ optionBundle = null;
+
+ }
+ }
+ else
+ {
+ if (NEW_OPTION == state)
+ {
+ optionBundle = new ArrayList();
+ optionBundle.add(args[i]);
+ state = SUB_PARAM_OF_OPTION;
+
+ }
+ else if (SUB_PARAM_OF_OPTION == state)
+ {
+ optionBundle.add(args[i]);
+ }
+
+ }
+ }
+ commandLineOption = new CommandLineOption(optionType, optionBundle);
+ commandLineOptions.put(commandLineOption.getOptionType(), commandLineOption);
+ return commandLineOptions;
+
+ }
+
+ public Map getAlloptions()
+ {
+ return this.commandlineoption;
+ }
+
+ public String getcommandname()
+ {
+ return this.commandname;
+ }
+
+ private static String removeSpaces(String s)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ", false);
+ String t = "";
+ while (st.hasMoreElements())
+ t += st.nextElement();
+ return t;
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfigProperty.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfigProperty.java
new file mode 100644
index 0000000000..55240054a9
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfigProperty.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.utils;
+
+public class JMXConfigProperty
+{
+
+ private static final String DEFAULT_HOST_NAME = "localhost";
+ private static final String DEFAULT_PORT = "8999";
+ private static final String DEFAULT_INTERVAL = "4000";
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfiguration.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfiguration.java
new file mode 100644
index 0000000000..76aab11e25
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfiguration.java
@@ -0,0 +1,182 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.utils;
+
+import java.util.Map;
+
+public class JMXConfiguration
+{
+ private String hostname = "localhost";
+ private String port = "8999";
+ private String interval = "40000";
+ private String outputpath = ".";
+ private String report_file = "report.output";
+ private boolean isreport_mode = false;
+ private String username = null;
+ private String password = null;
+
+ public JMXConfiguration(Map map)
+ {
+ if (checkoptionsetting(CommandLineOptionConstants.JMXCommandLineOptionConstants.HOST_OPTION, map))
+ {
+ this.hostname = optionchecker(CommandLineOptionConstants.JMXCommandLineOptionConstants.HOST_OPTION, map);
+ }
+ if (checkoptionsetting(CommandLineOptionConstants.JMXCommandLineOptionConstants.PORT_OPTION, map))
+ {
+ this.port = optionchecker(CommandLineOptionConstants.JMXCommandLineOptionConstants.PORT_OPTION, map);
+ }
+ if (checkoptionsetting(CommandLineOptionConstants.JMXCommandLineOptionConstants.REPORT_OPTION, map))
+ {
+
+ this.report_file = optionchecker(CommandLineOptionConstants.JMXCommandLineOptionConstants.REPORT_OPTION,
+ map);
+ }
+ if (checkoptionsetting(CommandLineOptionConstants.JMXCommandLineOptionConstants.USER_OPTION, map))
+ {
+
+ this.setUsername(optionchecker(CommandLineOptionConstants.JMXCommandLineOptionConstants.USER_OPTION, map));
+ }
+
+ if (checkoptionsetting(CommandLineOptionConstants.JMXCommandLineOptionConstants.PASSWORD_OPTION, map))
+ {
+ this.setPassword(optionchecker(CommandLineOptionConstants.JMXCommandLineOptionConstants.PASSWORD_OPTION,
+ map));
+ }
+
+ }
+
+ public void sethostname(String hostname)
+ {
+ this.hostname = hostname;
+ }
+
+ public void setport(String port)
+ {
+ this.port = port;
+ }
+
+ public void setinterval(String interval)
+ {
+ this.interval = interval;
+ }
+
+ public void setoutputpath(String output)
+ {
+ this.outputpath = output;
+ }
+
+ public String gethostname()
+ {
+ return this.hostname;
+ }
+
+ public String getport()
+ {
+ return this.port;
+ }
+
+ public String getinterval()
+ {
+ return this.interval;
+ }
+
+ public String getoutputpath()
+ {
+ return this.outputpath;
+ }
+
+ public CommandLineOption loadoption(String option, Map options)
+ {
+ CommandLineOption op = null;
+ if (option != null)
+ {
+ op = (CommandLineOption) options.get(option);
+
+ }
+ return op;
+
+ }
+
+ public void setreportfile(String reportfile)
+ {
+ this.report_file = reportfile;
+ this.isreport_mode = true;
+
+ }
+
+ public boolean isreportmode()
+ {
+ return this.isreport_mode;
+ }
+
+ public String getreportfile()
+ {
+ return this.report_file;
+ }
+
+ public String optionchecker(String option_letter, Map map)
+ {
+
+ if (map == null)
+ return null;
+ CommandLineOption option = (CommandLineOption) map.get(option_letter);
+ if (option == null)
+ return null;
+ String value = option.getOptionValue();
+ return value;
+ }
+
+ public boolean checkoptionsetting(String option_letter, Map map)
+ {
+ if (map == null)
+ return false;
+ CommandLineOption option = (CommandLineOption) map.get(option_letter);
+ if (option == null)
+ return false;
+ String value = option.getOptionType();
+
+ if (value != null)
+ return true;
+ else
+ return false;
+ }
+
+ public void setUsername(String username)
+ {
+ this.username = username;
+ }
+
+ public String getUsername()
+ {
+ return username;
+ }
+
+ public void setPassword(String password)
+ {
+ this.password = password;
+ }
+
+ public String getPassword()
+ {
+ return password;
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXinfo.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXinfo.java
new file mode 100644
index 0000000000..09de4a248f
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXinfo.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.utils;
+
+import javax.management.remote.JMXConnector;
+import javax.management.MBeanServerConnection;
+
+public class JMXinfo
+{
+ private JMXConnector jmxconnector;
+ private CommandLineOptionParser input;
+ private MBeanServerConnection mbserverconnector;
+
+ public JMXinfo(JMXConnector jmxc, CommandLineOptionParser input, MBeanServerConnection mbsc)
+ {
+ this.jmxconnector = jmxc;
+ this.input = input;
+ this.mbserverconnector = mbsc;
+ }
+
+ public JMXConnector getjmxconnectot()
+ {
+ return jmxconnector;
+ }
+
+ public CommandLineOptionParser getCommandLineOptionParser()
+ {
+ return input;
+ }
+
+ public MBeanServerConnection getmbserverconnector()
+ {
+ return mbserverconnector;
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/AllTest.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/AllTest.java
new file mode 100644
index 0000000000..d9758245cd
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/AllTest.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;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.apache.qpid.commands.*;
+import org.apache.qpid.commands.objects.*;
+import org.apache.qpid.utils.TestCommandLineOption;
+import org.apache.qpid.utils.TestCommandLineOptionParser;
+import org.apache.qpid.utils.TestJMXConfiguration;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses( { TestCommand.class, TestCommandExecutionEngine.class, TestCommandLineOption.class,
+ TestCommandLineOptionParser.class, TestConnector.class, TestJMXConfiguration.class, TestAllObject.class,
+ TestConnectionObject.class, TestExchangeObject.class, TestQueueObject.class, TestVirtualHostObject.class,
+ TestUserManagementObject.class, TestCommanddelete.class, TestCommandlist.class, TestCommandinfo.class,
+ TestCommandmove.class, TestCommandview.class, TestCommandviewcontent.class, TestCommandLineInterpreter.class
+
+})
+public class AllTest
+{
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/ConnectionConstants.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/ConnectionConstants.java
new file mode 100644
index 0000000000..90163460ce
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/ConnectionConstants.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;
+
+public interface ConnectionConstants
+{
+ String BROKER_HOSTNAME = "localhost";
+ String BROKER_PORT = "8999";
+ String USERNAME = "guest";
+ String PASSWORD = "guest";
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandExecutionEngine.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandExecutionEngine.java
new file mode 100644
index 0000000000..6889e8faad
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandExecutionEngine.java
@@ -0,0 +1,73 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid;
+
+import java.io.IOException;
+
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.utils.JMXinfo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCommandExecutionEngine
+{
+ String line;
+ String[] command;
+ CommandLineOptionParser commandlineoptionparser;
+ JMXinfo info;
+ CommandExecutionEngine engine;
+ Connector connector;
+
+ @Before
+ public void setup() throws Exception
+ {
+
+ connector = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+
+ }
+
+ @Test
+ public void TestCommandSelector() throws Exception
+ {
+ line = "list -o queue";
+ command = line.split(" ");
+ commandlineoptionparser = new CommandLineOptionParser(command);
+ info = new JMXinfo(connector.getConnector(), commandlineoptionparser, connector.getMBeanServerConnection());
+ engine = new CommandExecutionEngine(info);
+ Assert.assertEquals(engine.CommandSelector(), true);
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ connector.getConnector().close();
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandLineInterpreter.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandLineInterpreter.java
new file mode 100644
index 0000000000..07344598bf
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandLineInterpreter.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;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCommandLineInterpreter
+{
+
+ // CommandLineInterpreter test = new CommandLineInterpreter();
+ /*
+ * In this class there are only methodes which are displaying data on
+ * console so no test can be written
+ */
+ String command = "-h " + ConnectionConstants.BROKER_HOSTNAME + " -p " + ConnectionConstants.BROKER_PORT
+ + " info -o queue -n ping -v test";
+ Connector conn = null;
+ JMXConnector jmxc = null;
+ MBeanServerConnection mbsc = null;
+ CommandLineOptionParser parser = null;
+
+ String[] args = null;
+
+ @Before
+ public void startup() throws Exception
+ {
+ args = command.split(" ");
+ // System.out.println(args[0]);
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ jmxc = conn.getConnector();
+ mbsc = conn.getMBeanServerConnection();
+ parser = new CommandLineOptionParser(args, args[0]);
+
+ }
+
+ @Test
+ public void TestSetQueryString() throws Exception
+ {
+ CommandLineInterpreter.oneshotmode(args, parser, jmxc, mbsc);
+ Assert.assertEquals(args[0], "info");
+ Assert.assertEquals(args[1], "-o");
+ Assert.assertEquals(args[2], "queue");
+ Assert.assertEquals(args[3], "-n");
+ Assert.assertEquals(args[4], "ping");
+ Assert.assertEquals(args[5], "-v");
+ Assert.assertEquals(args[6], "test");
+ }
+
+ @After
+ public void cleanup()
+ {
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestConnector.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestConnector.java
new file mode 100644
index 0000000000..ea450b5caa
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestConnector.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;
+
+import java.io.IOException;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXServiceURL;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestConnector
+{
+ Connector test;
+ JMXServiceURL svc_url;
+ JMXConnector connector;
+ MBeanServerConnection mbsc;
+
+ @Before
+ public void setup() throws Exception
+ {
+ test = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ String url = "service:jmx:rmi:///jndi/rmi://localhost:8999/jmxrmi";
+
+ }
+
+ @Test
+ public void testGetConnector()
+ {
+ Assert.assertEquals(test.getConnector(), test.getConnector());
+ }
+
+ @Test
+ public void testGetMBeanServerConnection()
+ {
+ Assert.assertEquals(test.getMBeanServerConnection(), test.getMBeanServerConnection());
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+
+ test.getConnector().close();
+ test = null;
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace(); // To change body of catch statement use File |
+ // Settings | File Templates.
+ }
+ test = null;
+ }
+
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerHolder.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestReportGenerator.java
index 8345803d56..c14f4bb1bb 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerHolder.java
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestReportGenerator.java
@@ -18,9 +18,9 @@
* under the License.
*
*/
-package org.apache.qpid.test.utils;
+package org.apache.qpid;
-public interface BrokerHolder
+public class TestReportGenerator
{
- void shutdown();
+
}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommand.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommand.java
new file mode 100644
index 0000000000..085d7220e9
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommand.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.commands;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.Command;
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.utils.JMXinfo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCommand
+{
+ String command = "list -o queue";
+ String[] list;
+ Connector test;
+ MBeanServerConnection mbsc;
+ JMXinfo info;
+ CommandLineOptionParser parser;
+ Command cmd;
+
+ @Before
+ public void setup() throws Exception
+ {
+ list = command.split(" ");
+ parser = new CommandLineOptionParser(list);
+ test = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ info = new JMXinfo(test.getConnector(), parser, test.getMBeanServerConnection());
+ cmd = new Commandinfo(info);
+
+ }
+
+ @Test
+ public void TestOptionChecker()
+ {
+ Assert.assertEquals(cmd.optionchecker("o"), "queue");
+ }
+
+ @Test
+ public void TestCheckOptionSetting()
+ {
+ Assert.assertEquals(cmd.checkoptionsetting("o"), true);
+ Assert.assertEquals(cmd.checkoptionsetting("p"), false);
+ }
+
+ @After
+ public void cleanup()
+ {
+ parser = null;
+ test = null;
+ info = null;
+ cmd = null;
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommanddelete.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommanddelete.java
new file mode 100644
index 0000000000..60249c6940
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommanddelete.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.commands;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.Before;
+import org.junit.Assert;
+import org.apache.qpid.ConnectorFactory;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.utils.JMXinfo;
+import org.apache.qpid.utils.CommandLineOptionParser;
+
+import javax.management.remote.JMXConnector;
+import javax.management.MBeanServerConnection;
+
+public class TestCommanddelete
+{
+ JMXinfo info = null;
+ String command = "delete -o queue -n ping -v test -t 1";
+ Commanddelete delete = null;
+ Connector conn;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ JMXConnector jmxc = conn.getConnector();
+ MBeanServerConnection mbsc = conn.getMBeanServerConnection();
+ CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" "));
+ info = new JMXinfo(jmxc, parser, mbsc);
+ delete = new Commanddelete(info);
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ delete.execute();
+ Assert.assertEquals(delete.getObject(), "queue");
+ Assert.assertEquals(delete.getVirtualhost(), "test");
+ Assert.assertEquals(delete.getName(), "ping");
+ Assert.assertEquals(delete.getnumber(), 1);
+
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandinfo.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandinfo.java
new file mode 100644
index 0000000000..24263eea73
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandinfo.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.commands;
+
+import org.apache.qpid.utils.JMXinfo;
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.apache.qpid.ConnectionConstants;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.Assert;
+import org.junit.After;
+
+import javax.management.remote.JMXConnector;
+import javax.management.MBeanServerConnection;
+
+public class TestCommandinfo
+{
+ JMXinfo info = null;
+ String command = "info -o queue -n ping -v test";
+ CommandImpl infocommand = null;
+ Connector conn = null;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ JMXConnector jmxc = conn.getConnector();
+ MBeanServerConnection mbsc = conn.getMBeanServerConnection();
+ CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" "));
+ info = new JMXinfo(jmxc, parser, mbsc);
+ infocommand = new Commandinfo(info);
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ infocommand.execute();
+ Assert.assertEquals(infocommand.getObject(), "queue");
+ Assert.assertEquals(infocommand.getVirtualhost(), "test");
+ Assert.assertEquals(infocommand.getName(), "ping");
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandlist.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandlist.java
new file mode 100644
index 0000000000..ac759889fd
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandlist.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.commands;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.utils.JMXinfo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCommandlist
+{
+ /*
+ * All the methods in Commandlist doesn't have any arguments and no return
+ * type.
+ */
+ JMXinfo info = null;
+ String command = "list -o queue -n ping -v test";
+ Commandlist list = null;
+ Connector conn = null;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ JMXConnector jmxc = conn.getConnector();
+ MBeanServerConnection mbsc = conn.getMBeanServerConnection();
+ CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" "));
+ info = new JMXinfo(jmxc, parser, mbsc);
+ list = new Commandlist(info);
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ list.execute();
+ Assert.assertEquals(list.getObject(), "queue");
+ Assert.assertEquals(list.getVirtualhost(), "test");
+ Assert.assertEquals(list.getName(), "ping");
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandmove.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandmove.java
new file mode 100644
index 0000000000..3ff7890662
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandmove.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.commands;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.utils.JMXinfo;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.After;
+import org.junit.Assert;
+
+import javax.management.remote.JMXConnector;
+import javax.management.MBeanServerConnection;
+
+public class TestCommandmove
+{
+ JMXinfo info = null;
+ String command = "move -o queue -n1 ping -v1 test -n2 message_queue -fmid 10 -tmid 12";
+ Commandmove move = null;
+ Connector conn = null;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ JMXConnector jmxc = conn.getConnector();
+ MBeanServerConnection mbsc = conn.getMBeanServerConnection();
+ CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" "));
+ info = new JMXinfo(jmxc, parser, mbsc);
+ move = new Commandmove(info);
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ move.execute();
+ Assert.assertEquals(move.getObject(), "queue");
+ Assert.assertEquals(move.getVirtualhost(), "test");
+ Assert.assertEquals(move.getname1(), "ping");
+ Assert.assertEquals(move.getname2(), "message_queue");
+ Assert.assertEquals(move.getfmid(), 10);
+ Assert.assertEquals(move.gettmid(), 12);
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandview.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandview.java
new file mode 100644
index 0000000000..f46b8626b8
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandview.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.commands;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.ConnectorFactory;
+import org.apache.qpid.Connector;
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.utils.JMXinfo;
+import org.junit.Test;
+import org.junit.Before;
+import org.junit.After;
+import org.junit.Assert;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+
+public class TestCommandview
+{
+ JMXinfo info = null;
+ String command = "view -o queue -n ping -v test -t 10";
+ Commandview view = null;
+ Connector conn = null;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ JMXConnector jmxc = conn.getConnector();
+ MBeanServerConnection mbsc = conn.getMBeanServerConnection();
+ CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" "));
+ info = new JMXinfo(jmxc, parser, mbsc);
+ view = new Commandview(info);
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ view.execute();
+ Assert.assertEquals(view.getObject(), "queue");
+ Assert.assertEquals(view.getVirtualhost(), "test");
+ Assert.assertEquals(view.getName(), "ping");
+ Assert.assertEquals(view.getnumber(), 10);
+
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandviewcontent.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandviewcontent.java
new file mode 100644
index 0000000000..f4a8f22aff
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandviewcontent.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.commands;
+
+import org.apache.qpid.utils.JMXinfo;
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.apache.qpid.ConnectionConstants;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.After;
+import org.junit.Assert;
+
+import javax.management.remote.JMXConnector;
+import javax.management.MBeanServerConnection;
+
+public class TestCommandviewcontent
+{
+ JMXinfo info = null;
+ String command = "viewcontent -o queue -n ping -v test -id 10";
+ Commandviewcontent viewcontent = null;
+ Connector conn = null;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ JMXConnector jmxc = conn.getConnector();
+ MBeanServerConnection mbsc = conn.getMBeanServerConnection();
+ CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" "));
+ info = new JMXinfo(jmxc, parser, mbsc);
+ viewcontent = new Commandviewcontent(info);
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ viewcontent.execute();
+ Assert.assertEquals(viewcontent.getObject(), "queue");
+ Assert.assertEquals(viewcontent.getnumber(), 10);
+ Assert.assertEquals(viewcontent.getName(), "ping");
+ Assert.assertEquals(viewcontent.getVirtualhost(), "test");
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestAllObject.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestAllObject.java
new file mode 100644
index 0000000000..af993e9205
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestAllObject.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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestAllObject {
+ Connector conn;
+ MBeanServerConnection mbsc;
+ AllObjects test;
+ String test1,test2;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME,ConnectionConstants.BROKER_PORT, ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ mbsc = conn.getMBeanServerConnection();
+ test = new AllObjects(mbsc);
+ test1 = "empty input1";
+ test2 = "empty input2";
+
+
+ }
+ @Test
+ public void TestSetQueryString()
+ {
+ test.setQueryString(test1,test2);
+ Assert.assertEquals(test.querystring,"org.apache.qpid:*");
+
+ }
+
+ @After
+ public void cleanup()
+ {
+ try{
+ conn.getConnector().close();
+ }catch(Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestConnectionObject.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestConnectionObject.java
new file mode 100644
index 0000000000..f91a519108
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestConnectionObject.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestConnectionObject
+{
+ Connector conn;
+ MBeanServerConnection mbsc;
+ ConnectionObject test;
+ String test1, test2, test3;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ mbsc = conn.getMBeanServerConnection();
+ test = new ConnectionObject(mbsc);
+ test1 = "ping";
+ test2 = "test";
+ test3 = "object";
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ test.setQueryString(test3, test1, null);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=Connection,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=Connection,VirtualHost=test,*");
+ test.querystring = null;
+ test.setQueryString(test3, test1, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=Connection,VirtualHost=test,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, null);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=Connection,*");
+
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestExchangeObject.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestExchangeObject.java
new file mode 100644
index 0000000000..5ffbe9854f
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestExchangeObject.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestExchangeObject
+{
+ Connector conn;
+ MBeanServerConnection mbsc;
+ ExchangeObject test;
+ String test1, test2, test3;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ mbsc = conn.getMBeanServerConnection();
+ test = new ExchangeObject(mbsc);
+ test1 = "ping";
+ test2 = "test";
+ test3 = "object";
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ test.setQueryString(test3, test1, null);
+ // System.out.println(test.querystring);
+ // System.out.println("org.apache.qpid:type=VitualHost.Exchange,name=ping,*");
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.Exchange,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=test,*");
+ test.querystring = null;
+ test.setQueryString(test3, test1, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=test,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, null);
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AmqpProtocolVersion.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestObjectNames.java
index e925d7a1ec..600c567368 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AmqpProtocolVersion.java
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestObjectNames.java
@@ -18,6 +18,9 @@
* under the License.
*
*/
-package org.apache.qpid.server.protocol;
+package org.apache.qpid.commands.objects;
-public enum AmqpProtocolVersion { v0_8, v0_9, v0_9_1, v0_10 } \ No newline at end of file
+public class TestObjectNames
+{
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestQueueObject.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestQueueObject.java
new file mode 100644
index 0000000000..fb7f42e1ae
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestQueueObject.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestQueueObject
+{
+ Connector conn;
+ MBeanServerConnection mbsc;
+ QueueObject test;
+ String test1, test2, test3;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ mbsc = conn.getMBeanServerConnection();
+ test = new QueueObject(mbsc);
+ test1 = "ping";
+ test2 = "test";
+ test3 = "object";
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ test.setQueryString(test3, test1, null);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.Queue,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.Queue,VirtualHost=test,*");
+ test.querystring = null;
+ test.setQueryString(test3, test1, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.Queue,VirtualHost=test,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, null);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.Queue,*");
+
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestUserManagementObject.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestUserManagementObject.java
new file mode 100644
index 0000000000..863bf62311
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestUserManagementObject.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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestUserManagementObject
+{
+ Connector conn;
+ MBeanServerConnection mbsc;
+ UserManagementObject test;
+ String test1, test2, test3;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ mbsc = conn.getMBeanServerConnection();
+ test = new UserManagementObject(mbsc);
+ test1 = "ping";
+ test2 = "test";
+ test3 = "object";
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ test.setQueryString(test3, test1, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=UserManagement,*");
+
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestVirtualHostObject.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestVirtualHostObject.java
new file mode 100644
index 0000000000..29c4db30a5
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestVirtualHostObject.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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestVirtualHostObject
+{
+ Connector conn;
+ MBeanServerConnection mbsc;
+ VirtualHostObject test;
+ String test1, test2, test3;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ mbsc = conn.getMBeanServerConnection();
+ test = new VirtualHostObject(mbsc);
+ test1 = "ping";
+ test2 = "test";
+ test3 = "object";
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ test.setQueryString(test3, test1, null);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.VirtualHostManager,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=test,*");
+ test.querystring = null;
+ test.setQueryString(test3, test1, test2);
+ Assert.assertEquals(test.querystring,
+ "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=test,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, null);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.VirtualHostManager,*");
+
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOption.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOption.java
new file mode 100644
index 0000000000..e2a03f52ad
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOption.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.utils;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCommandLineOption
+{
+ String input1;
+ String input2;
+ String options;
+ String[] list;
+ CommandLineOption option;
+
+ @Before
+ public void setup()
+ {
+ input1 = "-h";
+ input2 = "--help";
+ options = "localhost testing";
+ list = options.split(" ");
+ option = new CommandLineOption(input1, list);
+
+ }
+
+ @Test
+ public void TestGetOptinValue()
+ {
+ Assert.assertEquals(option.getOptionValue(), "localhost");
+ }
+
+ @Test
+ public void TestGetOptionType()
+ {
+ Assert.assertEquals(option.getOptionType(), "h");
+ }
+
+ @After
+ public void cleanup()
+ {
+ option = null;
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOptionParser.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOptionParser.java
new file mode 100644
index 0000000000..964c350fc5
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOptionParser.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.utils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCommandLineOptionParser
+{
+ CommandLineOptionParser parser;
+ String[] input;
+ CommandLineOption option1;
+ CommandLineOption option2;
+ ArrayList list1;
+ ArrayList list2;
+
+ @Before
+ public void setup()
+ {
+ String temp = "run -h localhost -p 23232";
+ input = temp.split(" ");
+ parser = new CommandLineOptionParser(input);
+ list1 = new ArrayList();
+ list2 = new ArrayList();
+ }
+
+ @Test
+ public void TestParse()
+ {
+ Map hash = new HashMap();
+
+ list1.add("localhost");
+ list2.add("23232");
+ option1 = new CommandLineOption("h", list1);
+ option2 = new CommandLineOption("p", list2);
+ hash.put("h", option1);
+ hash.put("p", option2);
+ option1 = (CommandLineOption) parser.parse(input).get("h");
+ Assert.assertEquals(option1.getOptionType(), "h");
+ Assert.assertEquals(option1.getOptionValue(), "localhost");
+ option1 = (CommandLineOption) parser.parse(input).get("p");
+ Assert.assertEquals(option1.getOptionType(), "p");
+ Assert.assertEquals(option1.getOptionValue(), "23232");
+ Assert.assertEquals(parser.parse(input).size(), hash.size());
+ }
+
+ @After
+ public void cleanup()
+ {
+ parser = null;
+ option1 = null;
+ option2 = null;
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfigProperty.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfigProperty.java
new file mode 100644
index 0000000000..20234d1153
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfigProperty.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.utils;
+
+public class TestJMXConfigProperty
+{
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfiguration.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfiguration.java
new file mode 100644
index 0000000000..40cde00953
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfiguration.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.utils;
+
+import java.util.ArrayList;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestJMXConfiguration
+{
+ CommandLineOptionParser clop;
+ JMXConfiguration jmc;
+ CommandLineOption option;
+ String[] input;
+
+ @Before
+ public void setup()
+ {
+ String temp = "command -h 127.0.0.1 -p 1234";
+ input = temp.split(" ");
+ clop = new CommandLineOptionParser(input);
+ jmc = new JMXConfiguration(clop.getAlloptions());
+ }
+
+ @Test
+ public void TestLoadOption()
+ {
+ ArrayList list = new ArrayList();
+ list.add("127.0.0.1");
+ option = new CommandLineOption("-h", list);
+ CommandLineOption expect = jmc.loadoption("h", clop.getAlloptions());
+ Assert.assertEquals(expect.getOptionType(), option.getOptionType());
+ Assert.assertEquals(expect.getOptionValue(), option.getOptionValue());
+ }
+
+ @After
+ public void cleanup()
+ {
+ clop = null;
+ jmc = null;
+ option = null;
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXinfo.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXinfo.java
new file mode 100644
index 0000000000..aae39bcb37
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXinfo.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.utils;
+
+public class TestJMXinfo
+{
+ /*
+ * this class is having only three simple getter methods. Therefore no
+ * testcases
+ */
+}
diff --git a/qpid/java/maven-settings.xml b/qpid/java/maven-settings.xml
deleted file mode 100644
index 985f39b6f1..0000000000
--- a/qpid/java/maven-settings.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<settings>
-</settings>
diff --git a/qpid/java/module.xml b/qpid/java/module.xml
index c7819febf4..d3954a1544 100644
--- a/qpid/java/module.xml
+++ b/qpid/java/module.xml
@@ -66,8 +66,6 @@
<property name="module.release.bz2" location="${module.release}/${module.namever}.tar.bz2"/>
<property name="module.genpom.args" value=""/>
- <property name="maven.remote.repo" value="file://${module.release.base}/maven"/>
-
<property name="broker.log.prefix" value="BROKER: "/>
<property name="broker.log.interleave" value="true"/>
@@ -77,7 +75,6 @@
<property name="module.coverage" location="${module.build}/coverage"/>
<property name="cobertura.datafile" location="${module.instrumented}/cobetura.ser"/>
-
<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}"/>
@@ -223,8 +220,8 @@
<arg line='"${project.root}/genpom"'/>
<arg line='-s "${project.root}/lib/poms"'/>
<arg line='-o "${build.scratch}/qpid-${module.name}.pom"'/>
- <arg line="-u ${project.url}"/>
- <arg line="-g ${project.groupid}"/>
+ <arg line="-u http://qpid.apache.org"/>
+ <arg line="-g org.apache.qpid"/>
<arg line="-v ${project.version}${maven.version.suffix}"/>
<arg line="-p qpid"/>
<arg line='-m "${module.depends}"'/>
@@ -240,14 +237,14 @@
<artifact:pom id="module.pom" file="${build.scratch}/qpid-${module.name}.pom"/>
- <artifact:install file="${module.jar}" pomRefId="module.pom" settingsFile="${maven.settings.xml}">
+ <artifact:install file="${module.jar}" pomRefId="module.pom">
<localRepository path="${maven.local.repo}"/>
</artifact:install>
- <artifact:deploy file="${module.jar}" pomRefId="module.pom" uniqueVersion="${maven.unique.version}" settingsFile="${maven.settings.xml}">
+ <artifact:deploy file="${module.jar}" pomRefId="module.pom" uniqueVersion="${maven.unique.version}">
<attach file="${module.source.jar}" classifier="sources"/>
<localRepository path="${maven.local.repo}"/>
- <remoteRepository url="${maven.remote.repo}"/>
+ <remoteRepository url="file://${module.release.base}/maven"/>
</artifact:deploy>
</target>
@@ -295,7 +292,7 @@
</target>
- <property name="profile" value="java-mms.0-10"/>
+ <property name="profile" value="default"/>
<property name="testprofile.file" value="${test.profiles}/${profile}.testprofile"/>
<available file="${testprofile.file}" property="testprofile.file.present"/>
@@ -303,14 +300,15 @@
<property file="${testprofile.file}" prefix="preload"/>
<property name="preload.include" value=""/>
- <property name="profiles" value="${preload.include} ${profile}"/>
+ <condition property="profiles"
+ value="${preload.include} ${profile}"
+ else="default ${preload.include} ${profile}">
+ <equals arg1="${profile}" arg2="default"/>
+ </condition>
<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">
- <filelist dir="${test.profiles}" files="testprofile.defaults"/>
<filelist dir="${test.profiles}" files="${_profile_files}"/>
</concat>
<property file="${build.scratch}/test-${profile}.properties"/>
@@ -319,13 +317,12 @@
<globmapper from="*" to="${test.profiles}/*"/>
</map>
+
<condition property="dontruntest" value="dontruntest" else="runtest">
<contains substring="${module.name}" string="${exclude.modules}" />
</condition>
<property name="jvm.args" value=""/>
- <property name="broker.existing.qpid.work" value=""/>
-
<target name="test" depends="build,compile-tests" if="module.test.src.exists"
unless="${dontruntest}" description="execute unit tests">
@@ -346,6 +343,14 @@
<sysproperty key="log4j.configuration" value="${log4j.configuration}"/>
<sysproperty key="java.naming.factory.initial" value="${java.naming.factory.initial}"/>
<sysproperty key="java.naming.provider.url" value="${java.naming.provider.url}"/>
+ <sysproperty key="broker" value="${broker}"/>
+ <sysproperty key="broker.clean" value="${broker.clean}"/>
+ <sysproperty key="broker.clean.between.tests" value="${broker.clean.between.tests}"/>
+ <sysproperty key="broker.persistent" value="${broker.persistent}"/>
+ <sysproperty key="broker.version" value="${broker.version}"/>
+ <sysproperty key="broker.ready" value="${broker.ready}" />
+ <sysproperty key="broker.stopped" value="${broker.stopped}" />
+ <sysproperty key="broker.config" value="${broker.config}" />
<sysproperty key="messagestore.class.name" value="${messagestore.class.name}" />
<sysproperty key="test.output" value="${module.results}"/>
<sysproperty key="qpid.amqp.version" value="${qpid.amqp.version}"/>
@@ -396,15 +401,6 @@
</target>
- <target name="report-module" description="generate junit reports for each module">
- <junitreport todir="${module.results}">
- <fileset dir="${module.results}">
- <include name="TEST-*.xml"/>
- </fileset>
- <report format="frames" todir="${module.results}/report/html"/>
- </junitreport>
- </target>
-
<target name="touch-failed" if="test.failures">
<touch file="${module.failed}"/>
<touch file="${build.failed}"/>
@@ -651,6 +647,9 @@
<fileset dir="${module.classes}">
<include name="**/*.class"/>
</fileset>
+ <fileset dir="${module.test.classes}">
+ <include name="**/*.class"/>
+ </fileset>
</cobertura-instrument>
</target>
@@ -815,84 +814,4 @@ qpid.name=${project.name}
<touch file="${velocity.timestamp}" />
</target>
- <target name="eclipse" depends="eclipse-setup,eclipse-project,eclipse-source-only,eclipse-source-and-test"/>
-
- <target name="eclipse-setup">
- <taskdef name="eclipse" classname="prantl.ant.eclipse.EclipseTask" />
-
- <!-- Build set of directories representing the dependencies -->
-
- <dirset id="eclipse.required.projectdirs.path" dir="${project.root}" includes="${module.depends} ${module.test.depends} neverBeEmpty">
- <!-- Select only those projects from module.depends that contain a build.xml. This serves to exclude dependencies that
- don't become Eclipse projects e.g. broker-plugins and common-tests -->
- <present targetdir="${project.root}">
- <mapper type="glob" from="*" to="*/build.xml"/>
- </present>
- </dirset>
-
- <!-- Convert from the set of directories into Eclipse project names proceeded by forward slashes -->
-
- <pathconvert property="eclipse.required.projectnames" refid="eclipse.required.projectdirs.path" pathsep=" " dirsep="-">
- <map from="${project.root}${file.separator}" to=''/>
- </pathconvert>
- <map property="eclipse.required.slashedprojectnames" value="${eclipse.required.projectnames}" join="${path.separator}">
- <globmapper from="*" to="/*"/>
- </map>
-
- <echo message="Ant module dependencies : ${module.depends} ${module.test.depends} converted to Eclipse required project(s): ${eclipse.required.slashedprojectnames}"/>
- <path id="eclipse.required.slashedprojectnames.path">
- <pathelement path="${eclipse.required.slashedprojectnames}"/>
- </path>
- </target>
-
- <!-- Create the Eclipse .project -->
- <target name="eclipse-project">
- <eclipse updatealways="${eclipse.updatealways}">
- <project name="${module.name}"/>
-
- <!-- If the Eclipse task were to ever support the generation of
- linked resources, we would configure it to generate
- the following:
-
- scratch_src -> ${module.precompiled}
-
- in each project. This would avoid the 'linked sources'
- manual step documented on the Wiki.
- -->
- </eclipse>
- </target>
-
- <!-- Create the Eclipse .classpath -->
- <target name="eclipse-source-only" unless="module.test.src.exists">
- <eclipse updatealways="${eclipse.updatealways}">
- <settings>
- <jdtcore compilercompliance="${eclipse.compilercompliance}" />
- </settings>
- <classpath>
- <container path="${eclipse.container}" />
- <source path="${module.src}" />
- <source pathref="eclipse.required.slashedprojectnames.path" />
- <library pathref="module.libs"/>
- <output path="classes" />
- </classpath>
- </eclipse>
- </target>
-
- <!-- Create the Eclipse .classpath -->
- <target name="eclipse-source-and-test" if="module.test.src.exists">
- <eclipse updatealways="${eclipse.updatealways}">
- <settings>
- <jdtcore compilercompliance="${eclipse.compilercompliance}" />
- </settings>
- <classpath>
- <container path="${eclipse.container}" />
- <source path="${module.src}" />
- <source path="${module.test.src}" />
- <source pathref="eclipse.required.slashedprojectnames.path" />
- <library pathref="module.libs"/>
- <library pathref="module.test.libs"/>
- <output path="classes" />
- </classpath>
- </eclipse>
- </target>
</project>
diff --git a/qpid/java/perftests/src/main/java/org/apache/qpid/test/testcases/MessageThroughputPerf.java b/qpid/java/perftests/src/main/java/org/apache/qpid/test/testcases/MessageThroughputPerf.java
new file mode 100644
index 0000000000..e2e97ab6f8
--- /dev/null
+++ b/qpid/java/perftests/src/main/java/org/apache/qpid/test/testcases/MessageThroughputPerf.java
@@ -0,0 +1,207 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.testcases;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.NDC;
+
+import org.apache.qpid.test.framework.Assertion;
+import org.apache.qpid.test.framework.Circuit;
+import org.apache.qpid.test.framework.FrameworkBaseCase;
+import org.apache.qpid.test.framework.MessagingTestConfigProperties;
+import org.apache.qpid.test.framework.sequencers.CircuitFactory;
+
+import org.apache.qpid.junit.extensions.TestThreadAware;
+import org.apache.qpid.junit.extensions.TimingController;
+import org.apache.qpid.junit.extensions.TimingControllerAware;
+import org.apache.qpid.junit.extensions.util.ParsedProperties;
+import org.apache.qpid.junit.extensions.util.TestContextProperties;
+
+import java.util.LinkedList;
+
+/**
+ * MessageThroughputPerf runs a test over a {@link Circuit} controlled by the test parameters. It logs timings of
+ * the time required to receive samples consisting of batches of messages.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Measure message throughput accross a test circuit. <td> {@link Circuit}
+ * </table>
+ *
+ * @todo Check that all of the messages were sent. Check that the receiving end got the same number of messages as
+ * the publishing end.
+ *
+ * @todo Set this up to run with zero sized tests. Size zero means send forever. Continuous sending to be interrupted
+ * by completion of the test duration, or shutdown hook when the user presses Ctrl-C.
+ */
+public class MessageThroughputPerf extends FrameworkBaseCase implements TimingControllerAware, TestThreadAware
+{
+ /** Used for debugging. */
+ private static final Logger log = Logger.getLogger(MessageThroughputPerf.class);
+
+ /** Holds the timing controller, used to log test timings from self-timed tests. */
+ private TimingController timingController;
+
+ /** Thread local to hold the per-thread test setup fields. */
+ ThreadLocal<PerThreadSetup> threadSetup = new ThreadLocal<PerThreadSetup>();
+
+ /**
+ * Creates a new test case with the specified name.
+ *
+ * @param name The test case name.
+ */
+ public MessageThroughputPerf(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * Performs the a basic P2P test case.
+ *
+ * @param numMessages The number of messages to send in the test.
+ */
+ public void testThroughput(int numMessages)
+ {
+ log.debug("public void testThroughput(): called");
+
+ PerThreadSetup setup = threadSetup.get();
+ assertNoFailures(setup.testCircuit.test(numMessages, new LinkedList<Assertion>()));
+ }
+
+ /**
+ * Should provide a translation from the junit method name of a test to its test case name as known to the test
+ * clients that will run the test. The purpose of this is to convert the JUnit method name into the correct test
+ * case name to place into the test invite. For example the method "testP2P" might map onto the interop test case
+ * name "TC2_BasicP2P".
+ *
+ * @param methodName The name of the JUnit test method.
+ *
+ * @return The name of the corresponding interop test case.
+ */
+ public String getTestCaseNameForTestMethod(String methodName)
+ {
+ log.debug("public String getTestCaseNameForTestMethod(String methodName = " + methodName + "): called");
+
+ return "DEFAULT_CIRCUIT_TEST";
+ }
+
+ /**
+ * Used by test runners that can supply a {@link org.apache.qpid.junit.extensions.TimingController} to set the
+ * controller on an aware test.
+ *
+ * @param controller The timing controller.
+ */
+ public void setTimingController(TimingController controller)
+ {
+ timingController = controller;
+ }
+
+ /**
+ * Overrides the parent setUp method so that the in-vm broker creation is not done on a per test basis.
+ *
+ * @throws Exception Any exceptions allowed to fall through and fail the test.
+ */
+ protected void setUp() throws Exception
+ {
+ NDC.push(getName());
+
+ setTestProps(TestContextProperties.getInstance(MessagingTestConfigProperties.defaults));
+ }
+
+ /**
+ * Overrides the parent setUp method so that the in-vm broker clean-up is not done on a per test basis.
+ */
+ protected void tearDown()
+ {
+ NDC.pop();
+ }
+
+ /**
+ * Performs test fixture creation on a per thread basis. This will only be called once for each test thread.
+ */
+ public void threadSetUp()
+ {
+ // Run the test setup tasks. This may create an in-vm broker, if a decorator has injected a task for this.
+ getTaskHandler().runSetupTasks();
+
+ // Get the test parameters, any overrides on the command line will have been applied.
+ ParsedProperties testProps = TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
+
+ // Customize the test parameters.
+ testProps.setProperty("TEST_NAME", "DEFAULT_CIRCUIT_TEST");
+ testProps.setProperty(MessagingTestConfigProperties.SEND_DESTINATION_NAME_ROOT_PROPNAME, "testqueue");
+
+ // Get the test circuit factory to create test circuits and run the standard test procedure through.
+ CircuitFactory circuitFactory = getCircuitFactory();
+
+ // Create the test circuit. This projects the circuit onto the available test nodes and connects it up.
+ Circuit testCircuit = circuitFactory.createCircuit(null, testProps);
+
+ // Store the test configuration for the thread.
+ PerThreadSetup setup = new PerThreadSetup();
+ setup.testCircuit = testCircuit;
+ threadSetup.set(setup);
+ }
+
+ /**
+ * Called after all threads have completed their setup.
+ */
+ public void postThreadSetUp()
+ {
+ //Nothing to do here, potentially implement preFill as per PingTestPerf.
+ }
+
+ /**
+ * Called when a test thread is destroyed.
+ */
+ public void threadTearDown()
+ {
+ // Run the test teardown tasks. This may destroy the in-vm broker, if a decorator has injected a task for this.
+ getTaskHandler().runSetupTasks();
+ }
+
+ /**
+ * Holds the per-thread test configurations.
+ */
+ protected static class PerThreadSetup
+ {
+ /** Holds the test circuit to run tests on. */
+ Circuit testCircuit;
+ }
+
+ /**
+ * Compiles all the tests in this class into a suite.
+ *
+ * @return The test suite.
+ */
+ public static Test suite()
+ {
+ // Build a new test suite
+ TestSuite suite = new TestSuite("Qpid Throughput Performance Tests");
+
+ suite.addTest(new MessageThroughputPerf("testThroughput"));
+
+ return suite;
+ }
+}
diff --git a/qpid/java/resources/NOTICE b/qpid/java/resources/NOTICE
index add7753a4b..607c1c1580 100644
--- a/qpid/java/resources/NOTICE
+++ b/qpid/java/resources/NOTICE
@@ -10,6 +10,13 @@ available from
http://www.slf4j.org/
+Concurrency utlitity classes are provided by the backport-util-concurrent
+library package, which is open source software, written by
+Dawid Kurzyniec, and copyright by Distributed Computing Laboratory,
+Emory University. The original software is available from
+
+ http://dcl.mathcs.emory.edu/util/backport-util-concurrent/
+
Data compression support is provided by the JZLib library package,
which is open source software, written by JCraft, and copyright
by JCraft. The original software is available from
diff --git a/qpid/java/systests/etc/config-systests-ServerConfigurationTest-New.xml b/qpid/java/systests/etc/config-systests-ServerConfigurationTest-New.xml
new file mode 100644
index 0000000000..d1dce019dd
--- /dev/null
+++ b/qpid/java/systests/etc/config-systests-ServerConfigurationTest-New.xml
@@ -0,0 +1,78 @@
+<?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>
+ <work>${QPID_WORK}</work>
+ <conf>${QPID_HOME}/etc</conf>
+ <passwordDir>${conf}</passwordDir>
+ <plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>
+ <cache-directory>${QPID_WORK}/cache</cache-directory>
+ <connector>
+ <transport>nio</transport>
+ <port>5672</port>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
+ </connector>
+ <management>
+ <enabled>false</enabled>
+ <jmxport>8999</jmxport>
+ </management>
+ <advanced>
+ <filterchain enableExecutorPool="true"/>
+ <enablePooledAllocator>false</enablePooledAllocator>
+ <enableDirectBuffers>false</enableDirectBuffers>
+ <framesize>65535</framesize>
+ <compressBufferOnQueue>false</compressBufferOnQueue>
+ </advanced>
+
+ <security>
+ <principal-databases>
+ <principal-database>
+ <name>passwordfile</name>
+ <class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
+ <attributes>
+ <attribute>
+ <name>passwordFile</name>
+ <value>${passwordDir}/passwd</value>
+ </attribute>
+ </attributes>
+ </principal-database>
+ </principal-databases>
+
+ <jmx>
+ <access>${passwordDir}/jmxremote.access</access>
+ <principal-database>passwordfile</principal-database>
+ </jmx>
+ </security>
+
+ <virtualhosts>${conf}/virtualhosts-ServerConfigurationTest-New.xml</virtualhosts>
+
+ <heartbeat>
+ <delay>0</delay>
+ <timeoutFactor>2.0</timeoutFactor>
+ </heartbeat>
+ <queue>
+ <auto_register>true</auto_register>
+ </queue>
+</broker>
+
+
diff --git a/qpid/java/systests/etc/config-systests-ServerConfigurationTest-Old.xml b/qpid/java/systests/etc/config-systests-ServerConfigurationTest-Old.xml
new file mode 100644
index 0000000000..1de0389533
--- /dev/null
+++ b/qpid/java/systests/etc/config-systests-ServerConfigurationTest-Old.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<configuration>
+<work>${QPID_WORK}</work>
+<conf>${QPID_HOME}/etc</conf>
+<passwordDir>${conf}</passwordDir>
+<plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>
+<cache-directory>${QPID_WORK}/cache</cache-directory>
+<connector>
+<transport>nio</transport>
+<port>5672</port>
+<socketReceiveBuffer>32768</socketReceiveBuffer>
+<socketSendBuffer>32768</socketSendBuffer>
+</connector>
+<management>
+<enabled>false</enabled>
+<jmxport>8999</jmxport>
+</management>
+<advanced>
+<filterchain enableExecutorPool="true"/>
+<enablePooledAllocator>false</enablePooledAllocator>
+<enableDirectBuffers>false</enableDirectBuffers>
+<framesize>65535</framesize>
+<compressBufferOnQueue>false</compressBufferOnQueue>
+</advanced>
+<security>
+<principal-databases>
+<principal-database>
+<name>passwordfile</name>
+<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
+<attributes>
+<attribute>
+<name>passwordFile</name>
+<value>${passwordDir}/passwd</value>
+</attribute>
+</attributes>
+</principal-database>
+</principal-databases>
+<jmx>
+<access>${passwordDir}/jmxremote.access</access>
+<principal-database>passwordfile</principal-database>
+</jmx>
+</security>
+<virtualhosts>${conf}/virtualhosts-ServerConfigurationTest-New.xml
+<default>dev-only</default>
+<virtualhost>
+<name>dev-only</name>
+<dev-only>
+<store>
+<class>org.apache.qpid.server.store.MemoryMessageStore</class>
+<environment-path>${work}/bdbstore/dev-only-store</environment-path>
+</store>
+<queues>
+<exchange>amq.direct</exchange>
+<maximumQueueDepth>102400</maximumQueueDepth>
+<maximumMessageSize>20480</maximumMessageSize>
+<maximumMessageAge>60000</maximumMessageAge>
+<queue>
+<name>dev-queue</name>
+</queue>
+</queues>
+</dev-only>
+</virtualhost>
+</virtualhosts>
+<heartbeat>
+<delay>0</delay>
+<timeoutFactor>2.0</timeoutFactor>
+</heartbeat>
+<queue>
+<auto_register>true</auto_register>
+</queue>
+</configuration>
diff --git a/qpid/java/systests/etc/config-systests-acl-settings.xml b/qpid/java/systests/etc/config-systests-acl-settings.xml
new file mode 100644
index 0000000000..eebc75f05f
--- /dev/null
+++ b/qpid/java/systests/etc/config-systests-acl-settings.xml
@@ -0,0 +1,26 @@
+<?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>
+ <virtualhosts>${QPID_HOME}/etc/virtualhosts-systests-acl.xml</virtualhosts>
+</broker>
+
+
diff --git a/qpid/java/systests/etc/config-systests-acl.xml b/qpid/java/systests/etc/config-systests-acl.xml
new file mode 100644
index 0000000000..535108235e
--- /dev/null
+++ b/qpid/java/systests/etc/config-systests-acl.xml
@@ -0,0 +1,30 @@
+<?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="${test.config}" optional="true"/>
+ <xml fileName="${QPID_HOME}/etc/config-systests-acl-settings.xml"/>
+ <xml fileName="${QPID_HOME}/etc/config-systests-settings.xml"/>
+ <xml fileName="${QPID_HOME}/etc/config.xml"/>
+ </override>
+</configuration>
diff --git a/qpid/java/systests/etc/config-systests-firewall-2.xml b/qpid/java/systests/etc/config-systests-firewall-2.xml
index f16cce6b85..38ff9ddbb0 100644
--- a/qpid/java/systests/etc/config-systests-firewall-2.xml
+++ b/qpid/java/systests/etc/config-systests-firewall-2.xml
@@ -35,10 +35,17 @@
<keystorePath>/path/to/keystore.ks</keystorePath>
<keystorePassword>keystorepass</keystorePassword>
</ssl>
+ <qpidnio>false</qpidnio>
+ <protectio>
+ <enabled>false</enabled>
+ <readBufferLimitSize>262144</readBufferLimitSize>
+ <writeBufferLimitSize>262144</writeBufferLimitSize>
+ </protectio>
+ <transport>nio</transport>
<port>5672</port>
<sslport>8672</sslport>
- <socketReceiveBuffer>262144</socketReceiveBuffer>
- <socketSendBuffer>262144</socketSendBuffer>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
</connector>
<management>
<enabled>false</enabled>
@@ -61,8 +68,10 @@
</advanced>
<security>
- <pd-auth-manager>
+ <principal-databases>
+ <!-- Example use of Base64 encoded MD5 hashes for authentication via CRAM-MD5-Hashed -->
<principal-database>
+ <name>passwordfile</name>
<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
<attributes>
<attribute>
@@ -71,10 +80,15 @@
</attribute>
</attributes>
</principal-database>
- </pd-auth-manager>
+ </principal-databases>
<msg-auth>false</msg-auth>
+ <jmx>
+ <access>${conf}/jmxremote.access</access>
+ <principal-database>passwordfile</principal-database>
+ </jmx>
+
<firewall default-action="deny"/>
</security>
diff --git a/qpid/java/systests/etc/config-systests-firewall-3.xml b/qpid/java/systests/etc/config-systests-firewall-3.xml
index 71644e4185..6c0ee7ee3c 100644
--- a/qpid/java/systests/etc/config-systests-firewall-3.xml
+++ b/qpid/java/systests/etc/config-systests-firewall-3.xml
@@ -35,10 +35,17 @@
<keystorePath>/path/to/keystore.ks</keystorePath>
<keystorePassword>keystorepass</keystorePassword>
</ssl>
+ <qpidnio>false</qpidnio>
+ <protectio>
+ <enabled>false</enabled>
+ <readBufferLimitSize>262144</readBufferLimitSize>
+ <writeBufferLimitSize>262144</writeBufferLimitSize>
+ </protectio>
+ <transport>nio</transport>
<port>5672</port>
<sslport>8672</sslport>
- <socketReceiveBuffer>262144</socketReceiveBuffer>
- <socketSendBuffer>262144</socketSendBuffer>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
</connector>
<management>
<enabled>false</enabled>
@@ -61,8 +68,10 @@
</advanced>
<security>
- <pd-auth-manager>
+ <principal-databases>
+ <!-- Example use of Base64 encoded MD5 hashes for authentication via CRAM-MD5-Hashed -->
<principal-database>
+ <name>passwordfile</name>
<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
<attributes>
<attribute>
@@ -71,10 +80,15 @@
</attribute>
</attributes>
</principal-database>
- </pd-auth-manager>
+ </principal-databases>
<msg-auth>false</msg-auth>
+ <jmx>
+ <access>${conf}/jmxremote.access</access>
+ <principal-database>passwordfile</principal-database>
+ </jmx>
+
<firewall default-action="deny">
<rule access="allow" network="127.0.0.1"/>
</firewall>
diff --git a/qpid/java/systests/etc/virtualhosts-ServerConfigurationTest-New.xml b/qpid/java/systests/etc/virtualhosts-ServerConfigurationTest-New.xml
new file mode 100644
index 0000000000..1b6845662b
--- /dev/null
+++ b/qpid/java/systests/etc/virtualhosts-ServerConfigurationTest-New.xml
@@ -0,0 +1,45 @@
+<?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.
+ -
+ -->
+<virtualhosts>
+ <default>dev-only</default>
+ <virtualhost>
+ <name>dev-only</name>
+ <dev-only>
+ <queues>
+ <exchange>amq.direct</exchange>
+ <!-- Small defaults for development -->
+ <maximumQueueDepth>102400</maximumQueueDepth> <!-- 100k -->
+ <maximumMessageSize>20480</maximumMessageSize> <!-- 20kb -->
+ <maximumMessageAge>60000</maximumMessageAge> <!-- 1 mins -->
+
+ <queue>
+ <name>dev-queue</name>
+ </queue>
+ </queues>
+ <store>
+ <class>org.apache.qpid.server.store.MemoryMessageStore</class>
+ <environment-path>${QPID_WORK}/bdbstore/dev-only-store</environment-path>
+ </store>
+ </dev-only>
+ </virtualhost>
+</virtualhosts>
+ \ No newline at end of file
diff --git a/qpid/java/systests/etc/virtualhosts-systests-acl-settings.xml b/qpid/java/systests/etc/virtualhosts-systests-acl-settings.xml
new file mode 100644
index 0000000000..ffbace569f
--- /dev/null
+++ b/qpid/java/systests/etc/virtualhosts-systests-acl-settings.xml
@@ -0,0 +1,180 @@
+<?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.
+ -
+ -->
+<virtualhosts>
+ <virtualhost>
+ <name>test</name>
+ <test>
+ <queues>
+ <exchange>amq.direct</exchange>
+ <!-- 4Mb -->
+ <maximumQueueDepth>4235264</maximumQueueDepth>
+ <!-- 2Mb -->
+ <maximumMessageSize>2117632</maximumMessageSize>
+ <!-- 10 mins -->
+ <maximumMessageAge>600000</maximumMessageAge>
+ </queues>
+
+
+ <security>
+ <access_control_list>
+ <!-- This section grants pubish rights to an exchange + routing key pair -->
+ <publish>
+ <exchanges>
+ <exchange>
+ <name>amq.direct</name>
+ <routing_keys>
+ <!-- Allow clients to publish requests -->
+ <routing_key>
+ <value>example.RequestQueue</value>
+ <users>
+ <user>client</user>
+ </users>
+ </routing_key>
+
+ <!-- Allow the processor to respond to a client on their Temporary Topic -->
+ <routing_key>
+ <value>tmp_*</value>
+ <users>
+ <user>server</user>
+ </users>
+ </routing_key>
+ <routing_key>
+ <value>TempQueue*</value>
+ <users>
+ <user>server</user>
+ </users>
+ </routing_key>
+ </routing_keys>
+ </exchange>
+ </exchanges>
+ </publish>
+
+ <!-- This section grants users the ability to consume from the broker -->
+ <consume>
+ <queues>
+ <temporary>
+ <users>
+ <user>client</user>
+ </users>
+ </temporary>
+
+ <!-- Only allow the server to consume from the Request Queue-->
+ <queue>
+ <name>example.RequestQueue</name>
+ <users>
+ <user>server</user>
+ </users>
+ </queue>
+
+ <!-- Allow client and server to consume from the kipper Queue-->
+ <queue>
+ <name>clientid:kipper</name>
+ <users>
+ <user>client</user>
+ <user>server</user>
+ </users>
+ </queue>
+ </queues>
+ </consume>
+
+ <!-- This section grants users the ability to create queues and exchanges -->
+ <create>
+ <queues>
+ <temporary>
+ <users>
+ <user>client</user>
+ </users>
+ </temporary>
+
+ <!-- Allow clients to create queue on this exchange-->
+ <queue>
+ <exchanges>
+ <exchange>
+ <name>amq.direct</name>
+ <users>
+ <user>client</user>
+ <user>server</user>
+ </users>
+ </exchange>
+ <exchange>
+ <name>amq.topic</name>
+ <users>
+ <user>client</user>
+ <user>server</user>
+ </users>
+ </exchange>
+ </exchanges>
+ </queue>
+
+ <!-- everyone can create the kipper queue -->
+ <queue>
+ <name>clientid:kipper</name>
+ <users>
+ <user>client</user>
+ <user>server</user>
+ </users>
+ </queue>
+
+ <!-- Allow the server to create the Request Queue-->
+ <queue>
+ <name>example.RequestQueue</name>
+ <users>
+ <user>server</user>
+ </users>
+ </queue>
+ </queues>
+ </create>
+
+ <delete>
+ <queues>
+ <!-- only client can delete the kipper queue -->
+ <queue>
+ <name>clientid:kipper</name>
+ <users>
+ <user>client</user>
+ </users>
+ </queue>
+ </queues>
+ </delete>
+ </access_control_list>
+ </security>
+ </test>
+ </virtualhost>
+
+ <virtualhost>
+ <name>test2</name>
+ <test2>
+ <security>
+ <access_control_list>
+ <!-- This section grants specific users full permissions to all artifacts in this virtualhost -->
+ <access>
+ <users>
+ <user>guest</user>
+ </users>
+ </access>
+ </access_control_list>
+ </security>
+ </test2>
+ </virtualhost>
+</virtualhosts>
+
+
diff --git a/qpid/java/systests/etc/virtualhosts-systests-acl.xml b/qpid/java/systests/etc/virtualhosts-systests-acl.xml
new file mode 100644
index 0000000000..4a56c39de0
--- /dev/null
+++ b/qpid/java/systests/etc/virtualhosts-systests-acl.xml
@@ -0,0 +1,29 @@
+<?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="${test.virtualhosts}" optional="true"/>
+ <xml fileName="${QPID_HOME}/etc/virtualhosts-systests-acl-settings.xml"/>
+ <xml fileName="${QPID_HOME}/etc/virtualhosts.xml"/>
+ </override>
+</configuration>
diff --git a/qpid/java/systests/src/main/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java b/qpid/java/systests/src/main/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java
new file mode 100644
index 0000000000..5323ad28bf
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.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.mina.transport.vmpipe.support;
+
+import org.apache.mina.common.IdleStatus;
+
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * This file is a patch to override MINA, because of the IdentityHashMap bug. Workaround to be supplied in MINA 1.0.7.
+ * This patched file will be removed once upgraded onto a newer MINA.
+ *
+ * Dectects idle sessions and fires <tt>sessionIdle</tt> events to them.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ */
+public class VmPipeIdleStatusChecker
+{
+ private static final VmPipeIdleStatusChecker INSTANCE = new VmPipeIdleStatusChecker();
+
+ public static VmPipeIdleStatusChecker getInstance()
+ {
+ return INSTANCE;
+ }
+
+ private final Map sessions = new HashMap(); // will use as a set
+
+ private final Worker worker = new Worker();
+
+ private VmPipeIdleStatusChecker()
+ {
+ worker.start();
+ }
+
+ public void addSession(VmPipeSessionImpl session)
+ {
+ synchronized (sessions)
+ {
+ sessions.put(session, session);
+ }
+ }
+
+ private class Worker extends Thread
+ {
+ private Worker()
+ {
+ super("VmPipeIdleStatusChecker");
+ setDaemon(true);
+ }
+
+ public void run()
+ {
+ for (;;)
+ {
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e)
+ { }
+
+ long currentTime = System.currentTimeMillis();
+
+ synchronized (sessions)
+ {
+ Iterator it = sessions.keySet().iterator();
+ while (it.hasNext())
+ {
+ VmPipeSessionImpl session = (VmPipeSessionImpl) it.next();
+ if (!session.isConnected())
+ {
+ it.remove();
+ }
+ else
+ {
+ notifyIdleSession(session, currentTime);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void notifyIdleSession(VmPipeSessionImpl session, long currentTime)
+ {
+ notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.BOTH_IDLE), IdleStatus.BOTH_IDLE,
+ Math.max(session.getLastIoTime(), session.getLastIdleTime(IdleStatus.BOTH_IDLE)));
+ notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.READER_IDLE), IdleStatus.READER_IDLE,
+ Math.max(session.getLastReadTime(), session.getLastIdleTime(IdleStatus.READER_IDLE)));
+ notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.WRITER_IDLE), IdleStatus.WRITER_IDLE,
+ Math.max(session.getLastWriteTime(), session.getLastIdleTime(IdleStatus.WRITER_IDLE)));
+ }
+
+ private void notifyIdleSession0(VmPipeSessionImpl session, long currentTime, long idleTime, IdleStatus status,
+ long lastIoTime)
+ {
+ if ((idleTime > 0) && (lastIoTime != 0) && ((currentTime - lastIoTime) >= idleTime))
+ {
+ session.increaseIdleCount(status);
+ session.getFilterChain().fireSessionIdle(session, status);
+ }
+ }
+
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java
index 986297bfe1..ca10126aa7 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java
@@ -30,6 +30,7 @@ import javax.jms.TextMessage;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.client.transport.TransportConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/client/DispatcherTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/client/DispatcherTest.java
index 29a44ecec3..a8a23c2c41 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/client/DispatcherTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/client/DispatcherTest.java
@@ -36,6 +36,7 @@ import javax.jms.Session;
import javax.naming.Context;
import javax.naming.spi.InitialContextFactory;
+import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.jndi.PropertiesFileInitialContextFactory;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.slf4j.Logger;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java
new file mode 100644
index 0000000000..29b4dd82a7
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.client;
+
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.client.transport.TransportConnection;
+
+import java.io.File;
+import java.security.Provider;
+import java.security.Security;
+import java.util.List;
+import java.util.LinkedList;
+
+/**
+ * QPID-1394 : Test to ensure that the client can register their custom JCAProviders after the broker to ensure that
+ * the Qpid custom authentication SASL plugins are used.
+ */
+public class MultipleJCAProviderRegistrationTest extends QpidBrokerTestCase
+{
+
+ public void setUp() throws Exception
+ {
+ _broker = VM;
+
+ super.setUp();
+ }
+
+ public void test() throws Exception
+ {
+ // Get the providers before connection
+ Provider[] providers = Security.getProviders();
+
+ // Force the client to load the providers
+ getConnection();
+
+ Provider[] afterConnectionCreation = Security.getProviders();
+
+ // Find the additions
+ List additions = new LinkedList();
+ for (Provider afterCreation : afterConnectionCreation)
+ {
+ boolean found = false;
+ for (Provider provider : providers)
+ {
+ if (provider == afterCreation)
+ {
+ found=true;
+ break;
+ }
+ }
+
+ // Record added registies
+ if (!found)
+ {
+ additions.add(afterCreation);
+ }
+ }
+
+ assertTrue("Client did not register any providers", additions.size() > 0);
+ }
+
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageTest.java
index bf96dae02e..004ce5ea8f 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageTest.java
@@ -27,7 +27,6 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.UUID;
import javax.jms.Connection;
import javax.jms.JMSException;
@@ -52,7 +51,6 @@ public class AMQPEncodedMapMessageTest extends QpidBrokerTestCase
private Session _session;
MessageConsumer _consumer;
MessageProducer _producer;
- UUID myUUID = UUID.randomUUID();
public void setUp() throws Exception
{
@@ -121,8 +119,7 @@ public class AMQPEncodedMapMessageTest extends QpidBrokerTestCase
m.setFloat("Float", Integer.MAX_VALUE + 5000);
m.setInt("Int", Integer.MAX_VALUE - 5000);
m.setShort("Short", (short)58);
- m.setString("String", "Hello");
- m.setObject("uuid", myUUID);
+ m.setString("String", "Hello");
_producer.send(m);
AMQPEncodedMapMessage msg = (AMQPEncodedMapMessage)_consumer.receive(RECEIVE_TIMEOUT);
@@ -143,7 +140,6 @@ public class AMQPEncodedMapMessageTest extends QpidBrokerTestCase
assertEquals(Integer.MAX_VALUE - 5000,m.getInt("Int"));
assertEquals((short)58,m.getShort("Short"));
assertEquals("Hello",m.getString("String"));
- assertEquals(myUUID,(UUID)m.getObject("uuid"));
}
@@ -153,11 +149,7 @@ public class AMQPEncodedMapMessageTest extends QpidBrokerTestCase
List<Integer> myList = getList();
- m.setObject("List", myList);
-
- List<UUID> uuidList = new ArrayList<UUID>();
- uuidList.add(myUUID);
- m.setObject("uuid-list", uuidList);
+ m.setObject("List", myList);
_producer.send(m);
AMQPEncodedMapMessage msg = (AMQPEncodedMapMessage)_consumer.receive(RECEIVE_TIMEOUT);
@@ -175,10 +167,6 @@ public class AMQPEncodedMapMessageTest extends QpidBrokerTestCase
assertEquals(i,j.intValue());
i++;
}
-
- List<UUID> list2 = (List<UUID>)msg.getObject("uuid-list");
- assertNotNull("UUID List not received",list2);
- assertEquals(myUUID,list2.get(0));
}
public void testMessageWithMapEntries() throws JMSException
@@ -186,12 +174,8 @@ public class AMQPEncodedMapMessageTest extends QpidBrokerTestCase
MapMessage m = _session.createMapMessage();
Map<String,String> myMap = getMap();
- m.setObject("Map", myMap);
-
- Map<String,UUID> uuidMap = new HashMap<String,UUID>();
- uuidMap.put("uuid", myUUID);
- m.setObject("uuid-map", uuidMap);
+ m.setObject("Map", myMap);
_producer.send(m);
AMQPEncodedMapMessage msg = (AMQPEncodedMapMessage)_consumer.receive(RECEIVE_TIMEOUT);
@@ -207,10 +191,6 @@ public class AMQPEncodedMapMessageTest extends QpidBrokerTestCase
assertEquals("String" + i,map.get("Key" + i));
i++;
}
-
- Map<String,UUID> map2 = (Map<String,UUID>)msg.getObject("uuid-map");
- assertNotNull("Map not received",map2);
- assertEquals(myUUID,map2.get("uuid"));
}
public void testMessageWithNestedListsAndMaps() throws JMSException
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/jms/xa/XAResourceTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/jms/xa/XAResourceTest.java
deleted file mode 100644
index d7ee203fdf..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/jms/xa/XAResourceTest.java
+++ /dev/null
@@ -1,116 +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.jms.xa;
-
-import javax.jms.XAConnection;
-import javax.jms.XAConnectionFactory;
-import javax.jms.XASession;
-import javax.transaction.xa.XAResource;
-
-import org.apache.qpid.client.AMQConnectionFactory;
-import org.apache.qpid.jms.ConnectionURL;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-import org.apache.qpid.util.FileUtils;
-
-public class XAResourceTest extends QpidBrokerTestCase
-{
-
- private static final String FACTORY_NAME = "default";
- private static final String ALT_FACTORY_NAME = "connection2";
-
- /*
- * Test with multiple XAResources originating from the same connection factory. XAResource(s) will be equal,
- * as they originate from the same session.
- */
- public void testIsSameRMSingleCF() throws Exception
- {
- XAConnectionFactory factory = getConnectionFactory(FACTORY_NAME);
- XAConnection conn = factory.createXAConnection();
- XASession session = conn.createXASession();
- XAResource xaResource1 = session.getXAResource();
- XAResource xaResource2 = session.getXAResource();
-
- assertEquals("XAResource objects not equal", xaResource1, xaResource2);
- assertTrue("isSameRM not true for identical objects", xaResource1.isSameRM(xaResource2));
-
- session.close();
- conn.close();
- }
-
- /*
- * Test with multiple XAResources originating from different connection factory's and different sessions. XAResources will not be
- * equal as they do not originate from the same session. As the UUID from the broker will be the same, isSameRM will be true.
- *
- */
- public void testIsSameRMMultiCF() throws Exception
- {
- startBroker(FAILING_PORT);
- ConnectionURL url = getConnectionFactory(FACTORY_NAME).getConnectionURL();
- XAConnectionFactory factory = new AMQConnectionFactory(url);
- XAConnectionFactory factory2 = new AMQConnectionFactory(url);
- XAConnectionFactory factory3 = getConnectionFactory(ALT_FACTORY_NAME);
-
- XAConnection conn = factory.createXAConnection();
- XAConnection conn2 = factory2.createXAConnection();
- XAConnection conn3 = factory3.createXAConnection();
-
- XASession session = conn.createXASession();
- XASession session2 = conn2.createXASession();
- XASession session3 = conn3.createXASession();
-
- XAResource xaResource1 = session.getXAResource();
- XAResource xaResource2 = session2.getXAResource();
- XAResource xaResource3 = session3.getXAResource();
-
- assertFalse("XAResource objects should not be equal", xaResource1.equals(xaResource2));
- assertTrue("isSameRM not true for identical objects", xaResource1.isSameRM(xaResource2));
- assertFalse("isSameRM true for XA Resources created by two different brokers", xaResource1.isSameRM(xaResource3));
-
- conn.close();
- conn2.close();
- conn3.close();
- }
-
- @Override
- public void stopBroker(int port) throws Exception
- {
- if (isBrokerPresent(port))
- {
- super.stopBroker(port);
- }
- }
-
- @Override
- public void tearDown() throws Exception
- {
- try
- {
- super.tearDown();
- }
- finally
- {
- // Ensure we shutdown any secondary brokers
- stopBroker(FAILING_PORT);
- FileUtils.deleteDirectory(System.getProperty("QPID_WORK") + "/" + getFailingPort());
- }
- }
-
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageConnectionStatisticsTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageConnectionStatisticsTest.java
deleted file mode 100644
index 9839c6e475..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageConnectionStatisticsTest.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.management.jmx;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jms.Connection;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-
-/**
- * Test enabling generation of message statistics on a per-connection basis.
- */
-public class MessageConnectionStatisticsTest extends MessageStatisticsTestCase
-{
- public void configureStatistics() throws Exception
- {
- // no statistics generation configured
- }
-
- /**
- * Test statistics on a single connection
- */
- public void testEnablingStatisticsPerConnection() throws Exception
- {
- ManagedBroker vhost = _jmxUtils.getManagedBroker("test");
-
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- List<String> addresses = new ArrayList<String>();
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- assertEquals("Incorrect connection total", 0, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 0, mc.getTotalDataReceived());
- assertFalse("Connection statistics should not be enabled", mc.isStatisticsEnabled());
-
- addresses.add(mc.getRemoteAddress());
- }
- assertEquals("Incorrect vhost total", 0, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost data", 0, vhost.getTotalDataReceived());
-
- Connection test = new AMQConnection(_brokerUrl, USER, USER, "clientid", "test");
- test.start();
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- if (addresses.contains(mc.getRemoteAddress()))
- {
- continue;
- }
- mc.setStatisticsEnabled(true);
- assertEquals("Incorrect connection total", 0, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 0, mc.getTotalDataReceived());
- }
-
- sendUsing(test, 5, 200);
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- if (addresses.contains(mc.getRemoteAddress()))
- {
- assertEquals("Incorrect connection total", 0, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 0, mc.getTotalDataReceived());
- assertFalse("Connection statistics should not be enabled", mc.isStatisticsEnabled());
- }
- else
- {
- assertEquals("Incorrect connection total", 5, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 1000, mc.getTotalDataReceived());
- assertTrue("Connection statistics should be enabled", mc.isStatisticsEnabled());
- }
- }
- assertEquals("Incorrect vhost total", 0, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost data", 0, vhost.getTotalDataReceived());
- assertFalse("Vhost statistics should not be enabled", vhost.isStatisticsEnabled());
-
- test.close();
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsConfigurationTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsConfigurationTest.java
deleted file mode 100644
index 383c4c00a8..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsConfigurationTest.java
+++ /dev/null
@@ -1,162 +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.jmx;
-
-import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-
-/**
- * Test enabling generation of message statistics on a per-connection basis.
- */
-public class MessageStatisticsConfigurationTest extends MessageStatisticsTestCase
-{
- public void configureStatistics() throws Exception
- {
- setConfigurationProperty("statistics.generation.broker", Boolean.toString(getName().contains("Broker")));
- setConfigurationProperty("statistics.generation.virtualhosts", Boolean.toString(getName().contains("Virtualhost")));
- setConfigurationProperty("statistics.generation.connections", Boolean.toString(getName().contains("Connection")));
- }
-
- /**
- * Just broker statistics.
- */
- public void testGenerateBrokerStatistics() throws Exception
- {
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- assertEquals("Incorrect connection total", 0, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 0, mc.getTotalDataReceived());
- assertFalse("Connection statistics should not be enabled", mc.isStatisticsEnabled());
- }
-
- ManagedBroker vhost = _jmxUtils.getManagedBroker("test");
- assertEquals("Incorrect vhost data", 0, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost data", 0, vhost.getTotalDataReceived());
- assertFalse("Vhost statistics should not be enabled", vhost.isStatisticsEnabled());
-
- assertEquals("Incorrect server total messages", 5, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server total data", 1000, _jmxUtils.getServerInformation().getTotalDataReceived());
- assertTrue("Server statistics should be enabled", _jmxUtils.getServerInformation().isStatisticsEnabled());
- }
-
- /**
- * Just virtualhost statistics.
- */
- public void testGenerateVirtualhostStatistics() throws Exception
- {
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- assertEquals("Incorrect connection total", 0, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 0, mc.getTotalDataReceived());
- assertFalse("Connection statistics should not be enabled", mc.isStatisticsEnabled());
- }
-
- ManagedBroker vhost = _jmxUtils.getManagedBroker("test");
- assertEquals("Incorrect vhost data", 5, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost data", 1000, vhost.getTotalDataReceived());
- assertTrue("Vhost statistics should be enabled", vhost.isStatisticsEnabled());
-
- assertEquals("Incorrect server total messages", 0, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server total data", 0, _jmxUtils.getServerInformation().getTotalDataReceived());
- assertFalse("Server statistics should not be enabled", _jmxUtils.getServerInformation().isStatisticsEnabled());
- }
-
- /**
- * Just connection statistics.
- */
- public void testGenerateConnectionStatistics() throws Exception
- {
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- assertEquals("Incorrect connection total", 5, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 1000, mc.getTotalDataReceived());
- assertTrue("Connection statistics should be enabled", mc.isStatisticsEnabled());
- }
-
- ManagedBroker vhost = _jmxUtils.getManagedBroker("test");
- assertEquals("Incorrect vhost data", 0, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost data", 0, vhost.getTotalDataReceived());
- assertFalse("Vhost statistics should not be enabled", vhost.isStatisticsEnabled());
-
- assertEquals("Incorrect server total messages", 0, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server total data", 0, _jmxUtils.getServerInformation().getTotalDataReceived());
- assertFalse("Server statistics should not be enabled", _jmxUtils.getServerInformation().isStatisticsEnabled());
- }
-
- /**
- * Both broker and virtualhost statistics.
- */
- public void testGenerateBrokerAndVirtualhostStatistics() throws Exception
- {
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- assertEquals("Incorrect connection total", 0, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 0, mc.getTotalDataReceived());
- assertFalse("Connection statistics should not be enabled", mc.isStatisticsEnabled());
- }
-
- ManagedBroker vhost = _jmxUtils.getManagedBroker("test");
- assertEquals("Incorrect vhost data", 5, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost data", 1000, vhost.getTotalDataReceived());
- assertTrue("Vhost statistics should be enabled", vhost.isStatisticsEnabled());
-
- assertEquals("Incorrect server total messages", 5, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server total data", 1000, _jmxUtils.getServerInformation().getTotalDataReceived());
- assertTrue("Server statistics should be enabled", _jmxUtils.getServerInformation().isStatisticsEnabled());
- }
-
- /**
- * Broker, virtualhost and connection statistics.
- */
- public void testGenerateBrokerVirtualhostAndConnectionStatistics() throws Exception
- {
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- assertEquals("Incorrect connection total", 5, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 1000, mc.getTotalDataReceived());
- assertTrue("Connection statistics should be enabled", mc.isStatisticsEnabled());
- }
-
- ManagedBroker vhost = _jmxUtils.getManagedBroker("test");
- assertEquals("Incorrect vhost data", 5, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost data", 1000, vhost.getTotalDataReceived());
- assertTrue("Vhost statistics should be enabled", vhost.isStatisticsEnabled());
-
- assertEquals("Incorrect server total messages", 5, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server total data", 1000, _jmxUtils.getServerInformation().getTotalDataReceived());
- assertTrue("Server statistics should be enabled", _jmxUtils.getServerInformation().isStatisticsEnabled());
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsDeliveryTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsDeliveryTest.java
deleted file mode 100644
index e657856d0e..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsDeliveryTest.java
+++ /dev/null
@@ -1,110 +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.jmx;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jms.Connection;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.Session;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-
-/**
- * Test statistics for delivery and receipt.
- */
-public class MessageStatisticsDeliveryTest extends MessageStatisticsTestCase
-{
- public void configureStatistics() throws Exception
- {
- setConfigurationProperty("statistics.generation.broker", "true");
- setConfigurationProperty("statistics.generation.virtualhosts", "true");
- setConfigurationProperty("statistics.generation.connections", "true");
- }
-
- public void testDeliveryAndReceiptStatistics() throws Exception
- {
- ManagedBroker vhost = _jmxUtils.getManagedBroker("test");
-
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- List<String> addresses = new ArrayList<String>();
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- assertEquals("Incorrect connection delivery total", 0, mc.getTotalMessagesDelivered());
- assertEquals("Incorrect connection delivery data", 0, mc.getTotalDataDelivered());
- assertEquals("Incorrect connection receipt total", 5, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection receipt data", 1000, mc.getTotalDataReceived());
-
- addresses.add(mc.getRemoteAddress());
- }
-
- assertEquals("Incorrect vhost delivery total", 0, vhost.getTotalMessagesDelivered());
- assertEquals("Incorrect vhost delivery data", 0, vhost.getTotalDataDelivered());
- assertEquals("Incorrect vhost receipt total", 5, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost receipt data", 1000, vhost.getTotalDataReceived());
-
- Connection test = new AMQConnection(_brokerUrl, USER, USER, "clientid", "test");
- test.start();
- receiveUsing(test, 5);
-
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- if (addresses.contains(mc.getRemoteAddress()))
- {
- assertEquals("Incorrect connection delivery total", 0, mc.getTotalMessagesDelivered());
- assertEquals("Incorrect connection delivery data", 0, mc.getTotalDataDelivered());
- assertEquals("Incorrect connection receipt total", 5, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection receipt data", 1000, mc.getTotalDataReceived());
- }
- else
- {
- assertEquals("Incorrect connection delivery total", 5, mc.getTotalMessagesDelivered());
- assertEquals("Incorrect connection delivery data", 1000, mc.getTotalDataDelivered());
- assertEquals("Incorrect connection receipt total", 0, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection receipt data", 0, mc.getTotalDataReceived());
- }
- }
- assertEquals("Incorrect vhost delivery total", 5, vhost.getTotalMessagesDelivered());
- assertEquals("Incorrect vhost delivery data", 1000, vhost.getTotalDataDelivered());
- assertEquals("Incorrect vhost receipt total", 5, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost receipt data", 1000, vhost.getTotalDataReceived());
-
- test.close();
- }
-
- protected void receiveUsing(Connection con, int number) throws Exception
- {
- Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
- createQueue(session);
- MessageConsumer consumer = session.createConsumer(_queue);
- for (int i = 0; i < number; i++)
- {
- Message msg = consumer.receive(100);
- assertNotNull("Message " + i + " was not received", msg);
- }
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsReportingTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsReportingTest.java
deleted file mode 100644
index 180440c0d6..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsReportingTest.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.management.jmx;
-
-import java.util.List;
-
-import org.apache.qpid.util.LogMonitor;
-
-/**
- * Test generation of message statistics reporting.
- */
-public class MessageStatisticsReportingTest extends MessageStatisticsTestCase
-{
- protected LogMonitor _monitor;
-
- public void configureStatistics() throws Exception
- {
- setConfigurationProperty("statistics.generation.broker", "true");
- setConfigurationProperty("statistics.generation.virtualhosts", "true");
-
- if (getName().equals("testEnabledStatisticsReporting"))
- {
- setConfigurationProperty("statistics.reporting.period", "10");
- }
-
- _monitor = new LogMonitor(_outputFile);
- }
-
- /**
- * Test enabling reporting.
- */
- 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());
- }
-
- /**
- * Test not enabling reporting.
- */
- public void testNotEnabledStatisticsReporting() 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", 0, brokerStatsData.size());
- assertEquals("Incorrect number of broker message stats log messages", 0, brokerStatsMessages.size());
- assertEquals("Incorrect number of virtualhost data stats log messages", 0, vhostStatsData.size());
- assertEquals("Incorrect number of virtualhost message stats log messages", 0, vhostStatsMessages.size());
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTest.java
deleted file mode 100644
index 824ae41b97..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTest.java
+++ /dev/null
@@ -1,218 +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.jmx;
-
-import javax.jms.Connection;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-
-/**
- * Test generation of message statistics.
- */
-public class MessageStatisticsTest extends MessageStatisticsTestCase
-{
- public void configureStatistics() throws Exception
- {
- setConfigurationProperty("statistics.generation.broker", "true");
- setConfigurationProperty("statistics.generation.virtualhosts", "true");
- setConfigurationProperty("statistics.generation.connections", "true");
- }
-
- /**
- * Test message totals.
- */
- public void testMessageTotals() throws Exception
- {
- sendUsing(_test, 10, 100);
- sendUsing(_dev, 20, 100);
- sendUsing(_local, 5, 100);
- sendUsing(_local, 5, 100);
- sendUsing(_local, 5, 100);
- Thread.sleep(2000);
-
- ManagedBroker test = _jmxUtils.getManagedBroker("test");
- ManagedBroker dev = _jmxUtils.getManagedBroker("development");
- ManagedBroker local = _jmxUtils.getManagedBroker("localhost");
-
- if (!isBroker010())
- {
- long total = 0;
- long data = 0;
- for (ManagedConnection mc : _jmxUtils.getAllManagedConnections())
- {
- total += mc.getTotalMessagesReceived();
- data += mc.getTotalDataReceived();
- }
- assertEquals("Incorrect connection total", 45, total);
- assertEquals("Incorrect connection data", 4500, data);
- }
- assertEquals("Incorrect server total", 45, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server data", 4500, _jmxUtils.getServerInformation().getTotalDataReceived());
-
- if (!isBroker010())
- {
- long testTotal = 0;
- long testData = 0;
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- testTotal += mc.getTotalMessagesReceived();
- testData += mc.getTotalDataReceived();
- }
- assertEquals("Incorrect test connection total", 10, testTotal);
- assertEquals("Incorrect test connection data", 1000, testData);
- }
- assertEquals("Incorrect test vhost total", 10, test.getTotalMessagesReceived());
- assertEquals("Incorrect test vhost data", 1000, test.getTotalDataReceived());
-
- if (!isBroker010())
- {
- long devTotal = 0;
- long devData = 0;
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("development"))
- {
- devTotal += mc.getTotalMessagesReceived();
- devData += mc.getTotalDataReceived();
- }
- assertEquals("Incorrect test connection total", 20, devTotal);
- assertEquals("Incorrect test connection data", 2000, devData);
- }
- assertEquals("Incorrect development total", 20, dev.getTotalMessagesReceived());
- assertEquals("Incorrect development data", 2000, dev.getTotalDataReceived());
-
- if (!isBroker010())
- {
- long localTotal = 0;
- long localData = 0;
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("localhost"))
- {
- localTotal += mc.getTotalMessagesReceived();
- localData += mc.getTotalDataReceived();
- }
- assertEquals("Incorrect test connection total", 15, localTotal);
- assertEquals("Incorrect test connection data", 1500, localData);
- }
- assertEquals("Incorrect localhost total", 15, local.getTotalMessagesReceived());
- assertEquals("Incorrect localhost data", 1500, local.getTotalDataReceived());
- }
-
- /**
- * Test message totals when a connection is closed.
- */
- public void testMessageTotalsWithClosedConnections() throws Exception
- {
- Connection temp = new AMQConnection(_brokerUrl, USER, USER, "clientid", "test");
- temp.start();
-
- sendUsing(_test, 10, 100);
- sendUsing(temp, 10, 100);
- sendUsing(_test, 10, 100);
- Thread.sleep(2000);
-
- temp.close();
-
- ManagedBroker test = _jmxUtils.getManagedBroker("test");
-
- if (!isBroker010())
- {
- long total = 0;
- long data = 0;
- for (ManagedConnection mc : _jmxUtils.getAllManagedConnections())
- {
- total += mc.getTotalMessagesReceived();
- data += mc.getTotalDataReceived();
- }
- assertEquals("Incorrect active connection total", 20, total);
- assertEquals("Incorrect active connection data", 2000, data);
- }
- assertEquals("Incorrect server total", 30, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server data", 3000, _jmxUtils.getServerInformation().getTotalDataReceived());
-
- if (!isBroker010())
- {
- long testTotal = 0;
- long testData = 0;
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- testTotal += mc.getTotalMessagesReceived();
- testData += mc.getTotalDataReceived();
- }
- assertEquals("Incorrect test active connection total", 20, testTotal);
- assertEquals("Incorrect test active connection data", 20 * 100, testData);
- }
- assertEquals("Incorrect test vhost total", 30, test.getTotalMessagesReceived());
- assertEquals("Incorrect test vhost data", 30 * 100, test.getTotalDataReceived());
- }
-
- /**
- * Test message peak rate generation.
- */
- public void testMessagePeakRates() throws Exception
- {
- sendUsing(_test, 2, 10);
- Thread.sleep(10000);
- sendUsing(_dev, 4, 10);
- Thread.sleep(10000);
-
- ManagedBroker test = _jmxUtils.getManagedBroker("test");
- ManagedBroker dev = _jmxUtils.getManagedBroker("development");
-
- assertApprox("Incorrect test vhost peak messages", 0.2d, 1.0d, test.getPeakMessageReceiptRate());
- assertApprox("Incorrect test vhost peak data", 0.2d, 10.0d, test.getPeakDataReceiptRate());
- assertApprox("Incorrect dev vhost peak messages", 0.2d, 2.0d, dev.getPeakMessageReceiptRate());
- assertApprox("Incorrect dev vhost peak data", 0.2d, 20.0d, dev.getPeakDataReceiptRate());
-
- assertApprox("Incorrect server peak messages", 0.2d, 2.0d, _jmxUtils.getServerInformation().getPeakMessageReceiptRate());
- assertApprox("Incorrect server peak data", 0.2d, 20.0d, _jmxUtils.getServerInformation().getPeakDataReceiptRate());
- }
-
- /**
- * Test message totals when a vhost has its statistics reset
- */
- public void testMessageTotalVhostReset() throws Exception
- {
- sendUsing(_test, 10, 10);
- sendUsing(_dev, 10, 10);
- Thread.sleep(2000);
-
- ManagedBroker test = _jmxUtils.getManagedBroker("test");
- ManagedBroker dev = _jmxUtils.getManagedBroker("development");
-
- assertEquals("Incorrect test vhost total messages", 10, test.getTotalMessagesReceived());
- assertEquals("Incorrect test vhost total data", 100, test.getTotalDataReceived());
- assertEquals("Incorrect dev vhost total messages", 10, dev.getTotalMessagesReceived());
- assertEquals("Incorrect dev vhost total data", 100, dev.getTotalDataReceived());
-
- assertEquals("Incorrect server total messages", 20, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server total data", 200, _jmxUtils.getServerInformation().getTotalDataReceived());
-
- test.resetStatistics();
-
- assertEquals("Incorrect test vhost total messages", 0, test.getTotalMessagesReceived());
- assertEquals("Incorrect test vhost total data", 0, test.getTotalDataReceived());
- assertEquals("Incorrect dev vhost total messages", 10, dev.getTotalMessagesReceived());
- assertEquals("Incorrect dev vhost total data", 100, dev.getTotalDataReceived());
-
- assertEquals("Incorrect server total messages", 20, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server total data", 200, _jmxUtils.getServerInformation().getTotalDataReceived());
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTestCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTestCase.java
deleted file mode 100644
index a5b3aa283c..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTestCase.java
+++ /dev/null
@@ -1,128 +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.jmx;
-
-import javax.jms.Connection;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQDestination;
-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.test.utils.JMXTestUtils;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-/**
- * Test generation of message statistics.
- */
-public abstract class MessageStatisticsTestCase extends QpidBrokerTestCase
-{
- protected static final String USER = "admin";
-
- protected JMXTestUtils _jmxUtils;
- protected Connection _test, _dev, _local;
- protected String _queueName = "statistics";
- protected Destination _queue;
- protected String _brokerUrl;
-
- @Override
- public void setUp() throws Exception
- {
- _jmxUtils = new JMXTestUtils(this, USER, USER);
- _jmxUtils.setUp();
-
- configureStatistics();
-
- 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();
-
- _jmxUtils.open();
- }
-
- protected void createQueue(Session session) throws AMQException, JMSException
- {
- _queue = new AMQQueue(ExchangeDefaults.DIRECT_EXCHANGE_NAME, _queueName);
- if (!((AMQSession<?,?>) session).isQueueBound((AMQDestination) _queue))
- {
- ((AMQSession<?,?>) session).createQueue(new AMQShortString(_queueName), false, true, false, null);
- ((AMQSession<?,?>) session).declareAndBind((AMQDestination) new AMQQueue(ExchangeDefaults.DIRECT_EXCHANGE_NAME, _queueName));
- }
- }
-
-
- @Override
- public void tearDown() throws Exception
- {
- _jmxUtils.close();
-
- _test.close();
- _dev.close();
- _local.close();
-
- super.tearDown();
- }
-
- /**
- * Configure statistics generation properties on the broker.
- */
- public abstract void configureStatistics() throws Exception;
-
- protected void sendUsing(Connection con, int number, int size) throws Exception
- {
- Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
- createQueue(session);
- MessageProducer producer = session.createProducer(_queue);
- String content = new String(new byte[size]);
- TextMessage msg = session.createTextMessage(content);
- for (int i = 0; i < number; i++)
- {
- producer.send(msg);
- }
- }
-
- /**
- * Asserts that the actual value is within the expected value plus or
- * minus the given error.
- */
- public void assertApprox(String message, double error, double expected, double actual)
- {
- double min = expected * (1.0d - error);
- double max = expected * (1.0d + error);
- String assertion = String.format("%s: expected %f +/- %d%%, actual %f",
- message, expected, (int) (error * 100.0d), actual);
- assertTrue(assertion, actual > min && actual < max);
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java
index 27b4de0a8e..f9227c53ba 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java
@@ -70,13 +70,13 @@ public class BrokerStartupTest extends AbstractTestLogging
{
// This logging startup code only occurs when you run a Java broker,
// that broker must be started via Main so not an InVM broker.
- if (isJavaBroker() && isExternalBroker() && !isInternalBroker())
+ if (isJavaBroker() && isExternalBroker())
{
//Remove test Log4j config from the commandline
- _brokerCommand = _brokerCommand.substring(0, _brokerCommand.indexOf("-l"));
+ _broker = _broker.substring(0, _broker.indexOf("-l"));
// Add an invalid value
- _brokerCommand += " -l invalid";
+ _broker += " -l invalid";
// 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
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java
index 6d379e14d8..d4c550bc08 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java
@@ -61,6 +61,21 @@ public class ServerConfigurationFileTest extends QpidBrokerTestCase
_serverConfig.getConfig().getProperty(property));
}
+ public void testProtectIOEnabled() throws ConfigurationException
+ {
+ validatePropertyDefinedInFile(ServerConfiguration.CONNECTOR_PROTECTIO_ENABLED);
+ }
+
+ public void testProtectIOReadBufferLimitSize() throws ConfigurationException
+ {
+ validatePropertyDefinedInFile(ServerConfiguration.CONNECTOR_PROTECTIO_READ_BUFFER_LIMIT_SIZE);
+ }
+
+ public void testProtectIOWriteBufferLimitSize() throws ConfigurationException
+ {
+ validatePropertyDefinedInFile(ServerConfiguration.CONNECTOR_PROTECTIO_WRITE_BUFFER_LIMIT_SIZE);
+ }
+
public void testStatusUpdates() throws ConfigurationException
{
validatePropertyDefinedInFile(ServerConfiguration.STATUS_UPDATES);
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java
index 4a92f04b30..2d89d319d7 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java
@@ -83,9 +83,15 @@ public class MessagingTestConfigProperties
/** Holds the name of the default connection factory configuration property. */
public static final String CONNECTION_PROPNAME = "connectionfactory.broker";
+ /** Defeins the default connection configuration. */
+ public static final String CONNECTION_DEFAULT = "amqp://guest:guest@clientid/?brokerlist='vm://:1'";
+
/** Holds the name of the property to get the test broker url from. */
public static final String BROKER_PROPNAME = "qpid.test.broker";
+ /** Holds the default broker url for the test. */
+ public static final String BROKER_DEFAULT = "vm://:1";
+
/** Holds the name of the property to get the test broker virtual path. */
public static final String VIRTUAL_HOST_PROPNAME = "virtualHost";
@@ -268,6 +274,7 @@ public class MessagingTestConfigProperties
static
{
defaults.setPropertyIfNull(INITIAL_CONTEXT_FACTORY_PROPNAME, INITIAL_CONTEXT_FACTORY_DEFAULT);
+ defaults.setPropertyIfNull(CONNECTION_PROPNAME, CONNECTION_DEFAULT);
defaults.setPropertyIfNull(MESSAGE_SIZE_PROPNAME, MESSAGE_SIZE_DEAFULT);
defaults.setPropertyIfNull(PUBLISHER_PRODUCER_BIND_PROPNAME, PUBLISHER_PRODUCER_BIND_DEFAULT);
defaults.setPropertyIfNull(PUBLISHER_CONSUMER_BIND_PROPNAME, PUBLISHER_CONSUMER_BIND_DEFAULT);
@@ -277,6 +284,7 @@ public class MessagingTestConfigProperties
defaults.setPropertyIfNull(RECEIVE_DESTINATION_NAME_ROOT_PROPNAME, RECEIVE_DESTINATION_NAME_ROOT_DEFAULT);
defaults.setPropertyIfNull(PERSISTENT_MODE_PROPNAME, PERSISTENT_MODE_DEFAULT);
defaults.setPropertyIfNull(TRANSACTED_PROPNAME, TRANSACTED_DEFAULT);
+ defaults.setPropertyIfNull(BROKER_PROPNAME, BROKER_DEFAULT);
defaults.setPropertyIfNull(VIRTUAL_HOST_PROPNAME, VIRTUAL_HOST_DEFAULT);
defaults.setPropertyIfNull(RATE_PROPNAME, RATE_DEFAULT);
defaults.setPropertyIfNull(VERBOSE_PROPNAME, VERBOSE_DEFAULT);
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/failover/FailoverMethodTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/failover/FailoverMethodTest.java
index 11db513e00..ec222ff03d 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/failover/FailoverMethodTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/failover/FailoverMethodTest.java
@@ -20,39 +20,58 @@
*/
package org.apache.qpid.server.failover;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
+import junit.framework.TestCase;
import org.apache.qpid.AMQDisconnectedException;
import org.apache.qpid.AMQException;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.client.transport.TransportConnection;
+import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.url.URLSyntaxException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionListener
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import java.util.concurrent.CountDownLatch;
+
+public class FailoverMethodTest extends InternalBrokerBaseCase implements ExceptionListener
{
private CountDownLatch _failoverComplete = new CountDownLatch(1);
protected static final Logger _logger = LoggerFactory.getLogger(FailoverMethodTest.class);
+ @Override
+ public void createBroker() throws Exception
+ {
+ super.createBroker();
+ TransportConnection.createVMBroker(ApplicationRegistry.DEFAULT_INSTANCE);
+ }
+ @Override
+ public void stopBroker()
+ {
+ TransportConnection.killVMBroker(ApplicationRegistry.DEFAULT_INSTANCE);
+ super.stopBroker();
+ }
/**
* Test that the round robin method has the correct delays.
- * The first connection will work but the localhost connection should fail but the duration it takes
+ * The first connection to vm://:1 will work but the localhost connection should fail but the duration it takes
* to report the failure is what is being tested.
*
+ * @throws URLSyntaxException
+ * @throws InterruptedException
+ * @throws JMSException
*/
- public void testFailoverRoundRobinDelay() throws Exception
+ public void testFailoverRoundRobinDelay() throws URLSyntaxException, InterruptedException, JMSException
{
- //note: The first broker has no connect delay and the default 1 retry
+ //note: The VM broker has no connect delay and the default 1 retry
// while the tcp:localhost broker has 3 retries with a 2s connect delay
String connectionString = "amqp://guest:guest@/test?brokerlist=" +
- "'tcp://:" + getPort() +
+ "'vm://:" + ApplicationRegistry.DEFAULT_INSTANCE +
";tcp://localhost:5670?connectdelay='2000',retries='3''";
AMQConnectionURL url = new AMQConnectionURL(connectionString);
@@ -66,9 +85,7 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
stopBroker();
- _failoverComplete.await(30, TimeUnit.SECONDS);
- assertEquals("failoverLatch was not decremented in given timeframe",
- 0, _failoverComplete.getCount());
+ _failoverComplete.await();
long end = System.currentTimeMillis();
@@ -95,9 +112,10 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
}
}
- public void testFailoverSingleDelay() throws Exception
+ public void testFailoverSingleDelay() throws URLSyntaxException, AMQVMBrokerCreationException,
+ InterruptedException, JMSException
{
- String connectionString = "amqp://guest:guest@/test?brokerlist='tcp://localhost:" + getPort() + "?connectdelay='2000',retries='3''";
+ String connectionString = "amqp://guest:guest@/test?brokerlist='vm://:1?connectdelay='2000',retries='3''";
AMQConnectionURL url = new AMQConnectionURL(connectionString);
@@ -110,9 +128,7 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
stopBroker();
- _failoverComplete.await(30, TimeUnit.SECONDS);
- assertEquals("failoverLatch was not decremented in given timeframe",
- 0, _failoverComplete.getCount());
+ _failoverComplete.await();
long end = System.currentTimeMillis();
@@ -144,10 +160,6 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
_logger.debug("Received AMQDisconnectedException");
_failoverComplete.countDown();
}
- else
- {
- _logger.error("Unexpected underlying exception", e.getLinkedException());
- }
}
/**
@@ -156,37 +168,28 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
*
* Test validates that there is a connection delay as required on initial
* connection.
+ *
+ * @throws URLSyntaxException
+ * @throws AMQVMBrokerCreationException
+ * @throws InterruptedException
+ * @throws JMSException
*/
- public void testNoFailover() throws Exception
+ public void testNoFailover() throws URLSyntaxException, AMQVMBrokerCreationException,
+ InterruptedException, JMSException
{
- if (!isInternalBroker())
- {
- // QPID-3359
- // These tests always used to be inVM tests, then QPID-2815, with removal of ivVM,
- // converted the test to use QpidBrokerTestCase. However, since then we notice this
- // test fails on slower CI boxes. It turns out the test design is *extremely*
- // sensitive the length of time the broker takes to start up.
- //
- // Making the test a same-VM test to temporarily avoid the issue. In long term, test
- // needs redesigned to avoid the issue.
- return;
- }
-
int CONNECT_DELAY = 2000;
- String connectionString = "amqp://guest:guest@/test?brokerlist='tcp://localhost:" + getPort() + "?connectdelay='" + CONNECT_DELAY + "'," +
+ String connectionString = "amqp://guest:guest@/test?brokerlist='vm://:1?connectdelay='" + CONNECT_DELAY + "'," +
"retries='3'',failover='nofailover'";
-
AMQConnectionURL url = new AMQConnectionURL(connectionString);
- Thread brokerStart = null;
try
{
//Kill initial broker
stopBroker();
//Create a thread to start the broker asynchronously
- brokerStart = new Thread(new Runnable()
+ Thread brokerStart = new Thread(new Runnable()
{
public void run()
{
@@ -195,7 +198,7 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
//Wait before starting broker
// The wait should allow atleast 1 retries to fail before broker is ready
Thread.sleep(750);
- startBroker();
+ createBroker();
}
catch (Exception e)
{
@@ -209,6 +212,7 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
brokerStart.start();
long start = System.currentTimeMillis();
+
//Start the connection so it will use the retries
AMQConnection connection = new AMQConnection(url, null);
@@ -224,16 +228,13 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
//Ensure we collect the brokerStart thread
brokerStart.join();
- brokerStart = null;
start = System.currentTimeMillis();
//Kill connection
stopBroker();
- _failoverComplete.await(30, TimeUnit.SECONDS);
- assertEquals("failoverLatch was not decremented in given timeframe",
- 0, _failoverComplete.getCount());
+ _failoverComplete.await();
end = System.currentTimeMillis();
@@ -248,23 +249,6 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
{
fail(e.getMessage());
}
- finally
- {
- // Guard against the case where the broker took too long to start
- // and the initial connection failed to be formed.
- if (brokerStart != null)
- {
- brokerStart.join();
- }
- }
- }
-
- public void stopBroker(int port) throws Exception
- {
- if (isBrokerPresent(port))
- {
- super.stopBroker(port);
- }
}
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java
index 58b2edfee2..05aaf16af1 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java
@@ -176,7 +176,7 @@ public class AlertingTest extends AbstractTestLogging
startBroker();
- if (isInternalBroker())
+ if (!isExternalBroker())
{
assertEquals("Alert Max Msg Count is not correct", 5, ApplicationRegistry.getInstance().getVirtualHostRegistry().
getVirtualHost(VIRTUALHOST).getQueueRegistry().getQueue(new AMQShortString(_destination.getQueueName())).
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java
index 9155b84365..8fd2c085c3 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java
@@ -21,8 +21,6 @@
package org.apache.qpid.server.logging;
import junit.framework.AssertionFailedError;
-
-import org.apache.qpid.server.BrokerOptions;
import org.apache.qpid.server.Main;
import org.apache.qpid.transport.ConnectionException;
import org.apache.qpid.util.LogMonitor;
@@ -153,12 +151,12 @@ public class BrokerLoggingTest extends AbstractTestLogging
{
// This logging startup code only occurs when you run a Java broker,
// that broker must be started via Main so not an InVM broker.
- if (isJavaBroker() && isExternalBroker() && !isInternalBroker())
+ if (isJavaBroker() && isExternalBroker())
{
String TESTID = "BRK-1007";
//Remove test Log4j config from the commandline
- _brokerCommand = _brokerCommand.substring(0, _brokerCommand.indexOf("-l"));
+ _broker = _broker.substring(0, _broker.indexOf("-l"));
startBroker();
@@ -205,7 +203,7 @@ public class BrokerLoggingTest extends AbstractTestLogging
1, findMatches(TESTID).size());
//3
- String defaultLog4j = System.getProperty(QPID_HOME) + "/" + BrokerOptions.DEFAULT_LOG_CONFIG_FILE;
+ String defaultLog4j = _configFile.getParent() + "/" + Main.DEFAULT_LOG_CONFIG_FILENAME;
assertTrue("Log4j file(" + defaultLog4j + ") details not correctly logged:" + getMessageString(log),
getMessageString(log).endsWith(defaultLog4j));
@@ -242,11 +240,12 @@ public class BrokerLoggingTest extends AbstractTestLogging
*/
public void testBrokerStartupCustomLog4j() throws Exception
{
- // This logging startup code only occurs when you run a Java broker
+ // This logging startup code only occurs when you run a Java broker,
+ // that broker must be started via Main so not an InVM broker.
if (isJavaBroker() && isExternalBroker())
{
// Get custom -l value used during testing for the broker startup
- String customLog4j = _brokerCommand.substring(_brokerCommand.indexOf("-l") + 2);
+ String customLog4j = _broker.substring(_broker.indexOf("-l") + 2);
String TESTID = "BRK-1007";
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ChannelLoggingTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ChannelLoggingTest.java
index 1b2ec9c092..02d0d6f334 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ChannelLoggingTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ChannelLoggingTest.java
@@ -77,7 +77,7 @@ public class ChannelLoggingTest extends AbstractTestLogging
validateMessageID("CHN-1001", log);
assertEquals("Incorrect Channel in actor:"+fromActor(log), isBroker010()? 0 : 1, getChannelID(fromActor(log)));
- if (!isBroker010())
+ if (isBroker08())
{
// Wait to ensure that the CHN-1004 message is logged
waitForMessage("CHN-1004");
@@ -89,7 +89,7 @@ public class ChannelLoggingTest extends AbstractTestLogging
log = getLogMessage(results, 0);
// MESSAGE [con:0(guest@anonymous(3273383)/test)/ch:1] CHN-1004 : Prefetch Size (bytes) {0,number} : Count {1,number}
validateMessageID("CHN-1004", log);
- assertEquals("Incorrect Channel in actor:"+fromActor(log), 1, getChannelID(fromActor(log)));
+ assertEquals("Incorrect Channel in actor:"+fromActor(log), isBroker010()? 0 : 1, getChannelID(fromActor(log)));
assertTrue("Prefetch Count not correct",getMessageString(fromMessage(log)).endsWith("Count "+PREFETCH));
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ManagementLoggingTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ManagementLoggingTest.java
index 9feca7279e..595c0d5f35 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ManagementLoggingTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ManagementLoggingTest.java
@@ -76,8 +76,9 @@ public class ManagementLoggingTest extends AbstractTestLogging
*/
public void testManagementStartupEnabled() throws Exception
{
- // This test only works on java brokers
- if (isJavaBroker())
+ // This test only works on external java brokers due to the fact that
+ // Management is disabled on InVM brokers.
+ if (isJavaBroker() && isExternalBroker())
{
startBrokerAndCreateMonitor(true, false);
@@ -129,7 +130,9 @@ public class ManagementLoggingTest extends AbstractTestLogging
*/
public void testManagementStartupDisabled() throws Exception
{
- if (isJavaBroker())
+ // This test only works on external java brokers due to the fact that
+ // Management is disabled on InVM brokers.
+ if (isJavaBroker() && isExternalBroker())
{
startBrokerAndCreateMonitor(false, false);
@@ -188,7 +191,9 @@ public class ManagementLoggingTest extends AbstractTestLogging
*/
public void testManagementStartupRMIEntries() throws Exception
{
- if (isJavaBroker())
+ // This test only works on external java brokers due to the fact that
+ // Management is disabled on InVM brokers.
+ if (isJavaBroker() && isExternalBroker())
{
startBrokerAndCreateMonitor(true, false);
@@ -245,7 +250,9 @@ public class ManagementLoggingTest extends AbstractTestLogging
*/
public void testManagementStartupSSLKeystore() throws Exception
{
- if (isJavaBroker())
+ // This test only works on external java brokers due to the fact that
+ // Management is disabled on InVM brokers.
+ if (isJavaBroker() && isExternalBroker())
{
startBrokerAndCreateMonitor(true, true);
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java
index 398c83a8d8..a5aec3edce 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java
@@ -78,10 +78,21 @@ public class NoLocalAfterRecoveryTest extends QpidBrokerTestCase implements Conn
BrokerDetails details = _connectionURL.getBrokerDetails(0);
- // This will attempt to failover for 3 seconds.
- // Local testing suggests failover takes 2 seconds
- details.setProperty(BrokerDetails.OPTIONS_RETRY, "10");
- details.setProperty(BrokerDetails.OPTIONS_CONNECT_DELAY, "500");
+ // Due to the problem with SingleServer delaying on all connection
+ // attempts. So using a high retry value.
+ if (_broker.equals(VM))
+ {
+ // Local testing suggests InVM restart takes under a second
+ details.setProperty(BrokerDetails.OPTIONS_RETRY, "5");
+ details.setProperty(BrokerDetails.OPTIONS_CONNECT_DELAY, "200");
+ }
+ else
+ {
+ // This will attempt to failover for 3 seconds.
+ // Local testing suggests failover takes 2 seconds
+ details.setProperty(BrokerDetails.OPTIONS_RETRY, "10");
+ details.setProperty(BrokerDetails.OPTIONS_CONNECT_DELAY, "500");
+ }
super.setUp();
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java
deleted file mode 100644
index 460270e188..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.server.queue;
-
-import java.util.Random;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.jms.Connection;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageListener;
-import javax.jms.Session;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-public class MultipleTransactedBatchProducerTest extends QpidBrokerTestCase
-{
- private static final Logger _logger = Logger.getLogger(MultipleTransactedBatchProducerTest.class);
-
- private static final int MESSAGE_COUNT = 1000;
- private static final int BATCH_SIZE = 50;
- private static final int NUM_PRODUCERS = 2;
- private static final int NUM_CONSUMERS = 3;
- private static final Random RANDOM = new Random();
-
- private CountDownLatch _receivedLatch;
- private String _queueName;
-
- private volatile String _failMsg;
-
- public void setUp() throws Exception
- {
- //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");
- super.setUp();
- _queueName = getTestQueueName();
- _failMsg = null;
- }
-
- /**
- * When there are multiple producers submitting batches of messages to a given
- * queue using transacted sessions, it is highly probable that concurrent
- * enqueue() activity will occur and attempt delivery of their message to the
- * same subscription. In this scenario it is likely that one of the attempts
- * will succeed and the other will result in use of the deliverAsync() method
- * to start a queue Runner and ensure delivery of the message.
- *
- * A defect within the processQueue() method used by the Runner would mean that
- * delivery of these messages may not occur, should the Runner stop before all
- * messages have been processed. Such a defect was discovered and found to be
- * most visible when Selectors are used such that one and only one subscription
- * can/will accept any given message, but multiple subscriptions are present,
- * and one of the earlier subscriptions receives more messages than the others.
- *
- * This test is to validate that the processQueue() method is able to correctly
- * deliver all of the messages present for asynchronous delivery to subscriptions,
- * by utilising multiple batch transacted producers to create the scenario and
- * ensure all messages are received by a consumer.
- */
- public void testMultipleBatchedProducersWithMultipleConsumersUsingSelectors() throws Exception
- {
- String selector1 = ("(\"" + _queueName +"\" % " + NUM_CONSUMERS + ") = 0");
- String selector2 = ("(\"" + _queueName +"\" % " + NUM_CONSUMERS + ") = 1");
- String selector3 = ("(\"" + _queueName +"\" % " + NUM_CONSUMERS + ") = 2");
-
- //create consumers
- Connection conn1 = getConnection();
- conn1.setExceptionListener(new ExceptionHandler("conn1"));
- Session sess1 = conn1.createSession(true, Session.SESSION_TRANSACTED);
- MessageConsumer cons1 = sess1.createConsumer(sess1.createQueue(_queueName), selector1);
- cons1.setMessageListener(new Cons(sess1,"consumer1"));
-
- Connection conn2 = getConnection();
- conn2.setExceptionListener(new ExceptionHandler("conn2"));
- Session sess2 = conn2.createSession(true, Session.SESSION_TRANSACTED);
- MessageConsumer cons2 = sess2.createConsumer(sess2.createQueue(_queueName), selector2);
- cons2.setMessageListener(new Cons(sess2,"consumer2"));
-
- Connection conn3 = getConnection();
- conn3.setExceptionListener(new ExceptionHandler("conn3"));
- Session sess3 = conn3.createSession(true, Session.SESSION_TRANSACTED);
- MessageConsumer cons3 = sess3.createConsumer(sess3.createQueue(_queueName), selector3);
- cons3.setMessageListener(new Cons(sess3,"consumer3"));
-
- conn1.start();
- conn2.start();
- conn3.start();
-
- //create producers
- Connection connA = getConnection();
- connA.setExceptionListener(new ExceptionHandler("connA"));
- Connection connB = getConnection();
- connB.setExceptionListener(new ExceptionHandler("connB"));
- Thread producer1 = new Thread(new ProducerThread(connA, _queueName, "producer1"));
- Thread producer2 = new Thread(new ProducerThread(connB, _queueName, "producer2"));
-
- producer1.start();
- Thread.sleep(10);
- producer2.start();
-
- //await delivery of the messages
- boolean result = _receivedLatch.await(75, TimeUnit.SECONDS);
-
- assertNull("Test failed because: " + String.valueOf(_failMsg), _failMsg);
- assertTrue("Some of the messages were not all recieved in the given timeframe, remaining count was: "+_receivedLatch.getCount(),
- result);
-
- }
-
- @Override
- public Message createNextMessage(Session session, int msgCount) throws JMSException
- {
- Message message = super.createNextMessage(session,msgCount);
-
- //bias at least 50% of the messages to the first consumers selector because
- //the issue presents itself primarily when an earlier subscription completes
- //delivery after the later subscriptions
- int val;
- if (msgCount % 2 == 0)
- {
- val = 0;
- }
- else
- {
- val = RANDOM.nextInt(Integer.MAX_VALUE);
- }
-
- message.setIntProperty(_queueName, val);
-
- return message;
- }
-
- private class Cons implements MessageListener
- {
- private Session _sess;
- private String _desc;
-
- public Cons(Session sess, String desc)
- {
- _sess = sess;
- _desc = desc;
- }
-
- public void onMessage(Message message)
- {
- _receivedLatch.countDown();
- int msgCount = 0;
- int msgID = 0;
- try
- {
- msgCount = message.getIntProperty(INDEX);
- msgID = message.getIntProperty(_queueName);
- }
- catch (JMSException e)
- {
- _logger.error(_desc + " received exception: " + e.getMessage(), e);
- failAsyncTest(e.getMessage());
- }
-
- _logger.info("Consumer received message:"+ msgCount + " with ID: " + msgID);
-
- try
- {
- _sess.commit();
- }
- catch (JMSException e)
- {
- _logger.error(_desc + " received exception: " + e.getMessage(), e);
- failAsyncTest(e.getMessage());
- }
- }
- }
-
- private class ProducerThread implements Runnable
- {
- private Connection _conn;
- private String _dest;
- private String _desc;
-
- public ProducerThread(Connection conn, String dest, String desc)
- {
- _conn = conn;
- _dest = dest;
- _desc = desc;
- }
-
- public void run()
- {
- try
- {
- Session session = _conn.createSession(true, Session.SESSION_TRANSACTED);
- sendMessage(session, session.createQueue(_dest), MESSAGE_COUNT, BATCH_SIZE);
- }
- catch (Exception e)
- {
- _logger.error(_desc + " received exception: " + e.getMessage(), e);
- failAsyncTest(e.getMessage());
- }
- }
- }
-
- private class ExceptionHandler implements javax.jms.ExceptionListener
- {
- private String _desc;
-
- public ExceptionHandler(String description)
- {
- _desc = description;
- }
-
- public void onException(JMSException e)
- {
- _logger.error(_desc + " received exception: " + e.getMessage(), e);
- failAsyncTest(e.getMessage());
- }
- }
-
- private void failAsyncTest(String msg)
- {
- _logger.error("Failing test because: " + msg);
- _failMsg = msg;
- }
-} \ No newline at end of file
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/PriorityTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/PriorityTest.java
index 2ce1251eab..6203e8a194 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/PriorityTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/PriorityTest.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.queue;
import junit.framework.TestCase;
import junit.framework.Assert;
import org.apache.log4j.Logger;
+import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.AMQQueue;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
index 7f8f71d965..f845ff1214 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
@@ -52,6 +52,7 @@ import org.apache.qpid.url.URLSyntaxException;
*
* TODO move the pre broker-startup setup method invocation code to {@link QpidBrokerTestCase}
*
+ * @see SimpleACLTest
* @see ExternalACLTest
* @see ExternalACLFileTest
* @see ExternalACLJMXTest
@@ -64,7 +65,10 @@ public abstract class AbstractACLTestCase extends QpidBrokerTestCase implements
protected CountDownLatch _exceptionReceived;
/** Override this to return the name of the configuration XML file. */
- public abstract String getConfig();
+ public String getConfig()
+ {
+ return "config-systests-acl.xml";
+ }
/** Override this to setup external ACL files for virtual hosts. */
public List<String> getHostList()
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
index d1ba725721..4603cc1862 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
@@ -18,620 +18,11 @@
*/
package org.apache.qpid.server.security.acl;
-import java.io.IOException;
import java.util.Arrays;
import java.util.List;
-import javax.jms.Connection;
-import javax.jms.DeliveryMode;
-import javax.jms.IllegalStateException;
-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;
-import javax.jms.Topic;
-import javax.jms.TopicSubscriber;
-import javax.naming.NamingException;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.url.URLSyntaxException;
-
-/**
- * Tests the V2 ACLs. The tests perform basic AMQP operations like creating queues or excahnges and publishing and consuming messages, using
- * JMS to contact the broker.
- */
-public class ExternalACLTest extends AbstractACLTestCase
+public class ExternalACLTest extends SimpleACLTest
{
- public void testAccessAuthorizedSuccess() throws AMQException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
- Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
- conn.start();
-
- //Do something to show connection is active.
- sess.rollback();
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Connection was not created due to:" + e);
- }
- }
-
- public void testAccessVhostAuthorisedGuestSuccess() throws IOException, Exception
- {
- //The 'guest' user has no access to the 'test' vhost, as tested below in testAccessNoRights(), and so
- //is unable to perform actions such as connecting (and by extension, creating a queue, and consuming
- //from a queue etc). In order to test the vhost-wide 'access' ACL right, the 'guest' user has been given
- //this right in the 'test2' vhost.
-
- try
- {
- //get a connection to the 'test2' vhost using the guest user and perform various actions.
- Connection conn = getConnection("test2", "guest", "guest");
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
- conn.start();
-
- //create Queues and consumers for each
- Queue namedQueue = sess.createQueue("vhostAccessCreatedQueue" + getTestQueueName());
- Queue tempQueue = sess.createTemporaryQueue();
- MessageConsumer consumer = sess.createConsumer(namedQueue);
- MessageConsumer tempConsumer = sess.createConsumer(tempQueue);
-
- //send a message to each queue (also causing an exchange declare)
- MessageProducer sender = ((AMQSession<?, ?>) sess).createProducer(null);
- ((org.apache.qpid.jms.MessageProducer) sender).send(namedQueue, sess.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
- ((org.apache.qpid.jms.MessageProducer) sender).send(tempQueue, sess.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
-
- //consume the messages from the queues
- consumer.receive(2000);
- tempConsumer.receive(2000);
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
- }
-
- public void testAccessNoRightsFailure() throws Exception
- {
- try
- {
- Connection conn = getConnection("test", "guest", "guest");
- Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
- conn.start();
- sess.rollback();
-
- fail("Connection was created.");
- }
- catch (JMSException e)
- {
- // JMSException -> linkedException -> cause = AMQException (403 or 320)
- Exception linkedException = e.getLinkedException();
- assertNotNull("There was no linked exception", linkedException);
- Throwable cause = linkedException.getCause();
- assertNotNull("Cause was null", cause);
- assertTrue("Wrong linked exception type", cause instanceof AMQException);
- AMQConstant errorCode = isBroker010() ? AMQConstant.CONTEXT_IN_USE : AMQConstant.ACCESS_REFUSED;
- assertEquals("Incorrect error code received", errorCode, ((AMQException) cause).getErrorCode());
- }
- }
-
- public void testClientDeleteQueueSuccess() throws Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
- Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
- conn.start();
-
- // create kipper
- Topic kipper = sess.createTopic("kipper");
- TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
-
- subscriber.close();
- sess.unsubscribe("kipper");
-
- //Do something to show connection is active.
- sess.rollback();
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
- }
-
- public void testServerDeleteQueueFailure() throws Exception
- {
- try
- {
- Connection conn = getConnection("test", "server", "guest");
- Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
- conn.start();
-
- // create kipper
- Topic kipper = sess.createTopic("kipper");
- TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
-
- subscriber.close();
- sess.unsubscribe("kipper");
-
- //Do something to show connection is active.
- sess.rollback();
- conn.close();
- }
- catch (JMSException e)
- {
- // JMSException -> linedException = AMQException.403
- check403Exception(e.getLinkedException());
- }
- }
-
- public void testClientConsumeFromTempQueueSuccess() throws AMQException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- sess.createConsumer(sess.createTemporaryQueue());
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
- }
-
- public void testClientConsumeFromNamedQueueFailure() throws NamingException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- sess.createConsumer(sess.createQueue("IllegalQueue"));
-
- fail("Test failed as consumer was created.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
- }
-
- public void testClientCreateTemporaryQueueSuccess() throws JMSException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- //Create Temporary Queue - can't use the createTempQueue as QueueName is null.
- ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("doesnt_matter_as_autodelete_means_tmp"),
- true, false, false);
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
- }
-
- public void testClientCreateNamedQueueFailure() throws NamingException, JMSException, AMQException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- //Create a Named Queue
- ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("IllegalQueue"), false, false, false);
-
- fail("Test failed as Queue creation succeded.");
- //conn will be automatically closed
- }
- catch (AMQException e)
- {
- check403Exception(e);
- }
- }
-
- public void testClientPublishUsingTransactionSuccess() throws AMQException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
-
- conn.start();
-
- MessageProducer sender = sess.createProducer(sess.createQueue("example.RequestQueue"));
-
- sender.send(sess.createTextMessage("test"));
-
- //Send the message using a transaction as this will allow us to retrieve any errors that occur on the broker.
- sess.commit();
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test publish failed:" + e);
- }
- }
-
- public void testClientPublishValidQueueSuccess() throws AMQException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- MessageProducer sender = ((AMQSession<?, ?>) sess).createProducer(null);
-
- Queue queue = sess.createQueue("example.RequestQueue");
-
- // Send a message that we will wait to be sent, this should give the broker time to process the msg
- // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
- // queue existence.
- ((org.apache.qpid.jms.MessageProducer) sender).send(queue, sess.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test publish failed:" + e);
- }
- }
-
- public void testClientPublishInvalidQueueSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- MessageProducer sender = ((AMQSession<?, ?>) session).createProducer(null);
-
- Queue queue = session.createQueue("Invalid");
-
- // Send a message that we will wait to be sent, this should give the broker time to close the connection
- // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
- // queue existence.
- ((org.apache.qpid.jms.MessageProducer) sender).send(queue, session.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
-
- // Test the connection with a valid consumer
- // This may fail as the session may be closed before the queue or the consumer created.
- Queue temp = session.createTemporaryQueue();
-
- session.createConsumer(temp).close();
-
- //Connection should now be closed and will throw the exception caused by the above send
- conn.close();
-
- fail("Close is not expected to succeed.");
- }
- catch (IllegalStateException e)
- {
- _logger.info("QPID-2345: Session became closed and we got that error rather than the authentication error.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
- }
-
- public void testServerConsumeFromNamedQueueValid() throws AMQException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "server", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- sess.createConsumer(sess.createQueue("example.RequestQueue"));
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
- }
-
- public void testServerConsumeFromNamedQueueInvalid() throws AMQException, URLSyntaxException, NamingException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- sess.createConsumer(sess.createQueue("Invalid"));
-
- fail("Test failed as consumer was created.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
- }
-
- public void testServerConsumeFromTemporaryQueue() throws AMQException, URLSyntaxException, NamingException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "server", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- sess.createConsumer(sess.createTemporaryQueue());
-
- fail("Test failed as consumer was created.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
- }
-
- public void testServerCreateNamedQueueValid() throws JMSException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "server", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- //Create Temporary Queue
- ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("example.RequestQueue"), false, false, false);
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
- }
-
- public void testServerCreateNamedQueueInvalid() throws JMSException, URLSyntaxException, AMQException, NamingException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "server", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- //Create a Named Queue
- ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("IllegalQueue"), false, false, false);
-
- fail("Test failed as creation succeded.");
- }
- catch (Exception e)
- {
- check403Exception(e);
- }
- }
-
- public void testServerCreateTemporaryQueueInvalid() throws NamingException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "server", "guest");
- Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- session.createTemporaryQueue();
-
- fail("Test failed as creation succeded.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
- }
-
- public void testServerCreateAutoDeleteQueueInvalid() throws NamingException, JMSException, AMQException, Exception
- {
- try
- {
- Connection connection = getConnection("test", "server", "guest");
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- connection.start();
-
- ((AMQSession<?, ?>) session).createQueue(new AMQShortString("again_ensure_auto_delete_queue_for_temporary"),
- true, false, false);
-
- fail("Test failed as creation succeded.");
- }
- catch (Exception e)
- {
- check403Exception(e);
- }
- }
-
- /**
- * This test uses both the cilent and sender to validate that the Server is able to publish to a temporary queue.
- * The reason the client must be involved is that the Server is unable to create its own Temporary Queues.
- *
- * @throws AMQException
- * @throws URLSyntaxException
- * @throws JMSException
- */
- public void testServerPublishUsingTransactionSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
- {
- //Set up the Server
- Connection serverConnection = getConnection("test", "server", "guest");
-
- Session serverSession = serverConnection.createSession(true, Session.SESSION_TRANSACTED);
-
- Queue requestQueue = serverSession.createQueue("example.RequestQueue");
-
- MessageConsumer server = serverSession.createConsumer(requestQueue);
-
- serverConnection.start();
-
- //Set up the consumer
- Connection clientConnection = getConnection("test", "client", "guest");
-
- //Send a test mesage
- Session clientSession = clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- Queue responseQueue = clientSession.createTemporaryQueue();
-
- MessageConsumer clientResponse = clientSession.createConsumer(responseQueue);
-
- clientConnection.start();
-
- Message request = clientSession.createTextMessage("Request");
-
- assertNotNull("Response Queue is null", responseQueue);
-
- request.setJMSReplyTo(responseQueue);
-
- clientSession.createProducer(requestQueue).send(request);
-
- try
- {
- Message msg = null;
-
- msg = server.receive(2000);
-
- while (msg != null && !((TextMessage) msg).getText().equals("Request"))
- {
- msg = server.receive(2000);
- }
-
- assertNotNull("Message not received", msg);
-
- assertNotNull("Reply-To is Null", msg.getJMSReplyTo());
-
- MessageProducer sender = serverSession.createProducer(msg.getJMSReplyTo());
-
- sender.send(serverSession.createTextMessage("Response"));
-
- //Send the message using a transaction as this will allow us to retrieve any errors that occur on the broker.
- serverSession.commit();
-
- //Ensure Response is received.
- Message clientResponseMsg = clientResponse.receive(2000);
- assertNotNull("Client did not receive response message,", clientResponseMsg);
- assertEquals("Incorrect message received", "Response", ((TextMessage) clientResponseMsg).getText());
-
- }
- catch (Exception e)
- {
- fail("Test publish failed:" + e);
- }
- finally
- {
- try
- {
- serverConnection.close();
- }
- finally
- {
- clientConnection.close();
- }
- }
- }
-
- public void testServerPublishInvalidQueueSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "server", "guest");
-
- ((AMQConnection) conn).setConnectionListener(this);
-
- Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- MessageProducer sender = ((AMQSession<?, ?>) session).createProducer(null);
-
- Queue queue = session.createQueue("Invalid");
-
- // Send a message that we will wait to be sent, this should give the broker time to close the connection
- // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
- // queue existence.
- ((org.apache.qpid.jms.MessageProducer) sender).send(queue, session.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
-
- // Test the connection with a valid consumer
- // This may not work as the session may be closed before the queue or consumer creation can occur.
- // The correct JMSexception with linked error will only occur when the close method is recevied whilst in
- // the failover safe block
- session.createConsumer(session.createQueue("example.RequestQueue")).close();
-
- //Connection should now be closed and will throw the exception caused by the above send
- conn.close();
-
- fail("Close is not expected to succeed.");
- }
- catch (IllegalStateException e)
- {
- _logger.info("QPID-2345: Session became closed and we got that error rather than the authentication error.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
- }
-
-
@Override
public String getConfig()
{
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java
new file mode 100644
index 0000000000..a50817e659
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java
@@ -0,0 +1,644 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * 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.acl;
+
+import java.io.IOException;
+
+import javax.jms.Connection;
+import javax.jms.DeliveryMode;
+import javax.jms.IllegalStateException;
+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;
+import javax.jms.Topic;
+import javax.jms.TopicSubscriber;
+import javax.naming.NamingException;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.url.URLSyntaxException;
+
+/**
+ * Basic access control list tests.
+ *
+ * These tests require an access control security plugin to be configured in the broker, and carry out various broker
+ * operations that will succeed or fail depending on the user and virtual host. See the {@code config-systests-acl-setup.xml}
+ * configuration file for the SimpleXML version of the ACLs used by the Java broker only, or the various {@code .txt}
+ * files in the system tests directory for the external version 3 ACL files used by both the Java and C++ brokers.
+ * <p>
+ * This class can be extended and the {@link #getConfig()} method overridden to run the same tests with a different type
+ * of access control mechanism. Extension classes should differ only in the configuration file used, but extra tests can be
+ * added that are specific to a particular configuration.
+ * <p>
+ * The tests perform basic AMQP operations like creating queues or excahnges and publishing and consuming messages, using
+ * JMS to contact the broker.
+ *
+ * @see ExternalACLTest
+ */
+public class SimpleACLTest extends AbstractACLTestCase
+{
+ public void testAccessAuthorizedSuccess() throws AMQException, URLSyntaxException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+ Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
+ conn.start();
+
+ //Do something to show connection is active.
+ sess.rollback();
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Connection was not created due to:" + e);
+ }
+ }
+
+ public void testAccessVhostAuthorisedGuestSuccess() throws IOException, Exception
+ {
+ //The 'guest' user has no access to the 'test' vhost, as tested below in testAccessNoRights(), and so
+ //is unable to perform actions such as connecting (and by extension, creating a queue, and consuming
+ //from a queue etc). In order to test the vhost-wide 'access' ACL right, the 'guest' user has been given
+ //this right in the 'test2' vhost.
+
+ try
+ {
+ //get a connection to the 'test2' vhost using the guest user and perform various actions.
+ Connection conn = getConnection("test2", "guest", "guest");
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ conn.start();
+
+ //create Queues and consumers for each
+ Queue namedQueue = sess.createQueue("vhostAccessCreatedQueue" + getTestQueueName());
+ Queue tempQueue = sess.createTemporaryQueue();
+ MessageConsumer consumer = sess.createConsumer(namedQueue);
+ MessageConsumer tempConsumer = sess.createConsumer(tempQueue);
+
+ //send a message to each queue (also causing an exchange declare)
+ MessageProducer sender = ((AMQSession<?, ?>) sess).createProducer(null);
+ ((org.apache.qpid.jms.MessageProducer) sender).send(namedQueue, sess.createTextMessage("test"),
+ DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
+ ((org.apache.qpid.jms.MessageProducer) sender).send(tempQueue, sess.createTextMessage("test"),
+ DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
+
+ //consume the messages from the queues
+ consumer.receive(2000);
+ tempConsumer.receive(2000);
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test failed due to:" + e.getMessage());
+ }
+ }
+
+ public void testAccessNoRightsFailure() throws Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "guest", "guest");
+ Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
+ conn.start();
+ sess.rollback();
+
+ fail("Connection was created.");
+ }
+ catch (JMSException e)
+ {
+ // JMSException -> linkedException -> cause = AMQException (403 or 320)
+ Exception linkedException = e.getLinkedException();
+ assertNotNull("There was no linked exception", linkedException);
+ Throwable cause = linkedException.getCause();
+ assertNotNull("Cause was null", cause);
+ assertTrue("Wrong linked exception type", cause instanceof AMQException);
+ AMQConstant errorCode = isBroker010() ? AMQConstant.CONTEXT_IN_USE : AMQConstant.ACCESS_REFUSED;
+ assertEquals("Incorrect error code received", errorCode, ((AMQException) cause).getErrorCode());
+ }
+ }
+
+ public void testClientDeleteQueueSuccess() throws Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+ Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
+ conn.start();
+
+ // create kipper
+ Topic kipper = sess.createTopic("kipper");
+ TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
+
+ subscriber.close();
+ sess.unsubscribe("kipper");
+
+ //Do something to show connection is active.
+ sess.rollback();
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test failed due to:" + e.getMessage());
+ }
+ }
+
+ public void testServerDeleteQueueFailure() throws Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "server", "guest");
+ Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
+ conn.start();
+
+ // create kipper
+ Topic kipper = sess.createTopic("kipper");
+ TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
+
+ subscriber.close();
+ sess.unsubscribe("kipper");
+
+ //Do something to show connection is active.
+ sess.rollback();
+ conn.close();
+ }
+ catch (JMSException e)
+ {
+ // JMSException -> linedException = AMQException.403
+ check403Exception(e.getLinkedException());
+ }
+ }
+
+ public void testClientConsumeFromTempQueueSuccess() throws AMQException, URLSyntaxException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ sess.createConsumer(sess.createTemporaryQueue());
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test failed due to:" + e.getMessage());
+ }
+ }
+
+ public void testClientConsumeFromNamedQueueFailure() throws NamingException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ sess.createConsumer(sess.createQueue("IllegalQueue"));
+
+ fail("Test failed as consumer was created.");
+ }
+ catch (JMSException e)
+ {
+ check403Exception(e.getLinkedException());
+ }
+ }
+
+ public void testClientCreateTemporaryQueueSuccess() throws JMSException, URLSyntaxException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ //Create Temporary Queue - can't use the createTempQueue as QueueName is null.
+ ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("doesnt_matter_as_autodelete_means_tmp"),
+ true, false, false);
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test failed due to:" + e.getMessage());
+ }
+ }
+
+ public void testClientCreateNamedQueueFailure() throws NamingException, JMSException, AMQException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ //Create a Named Queue
+ ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("IllegalQueue"), false, false, false);
+
+ fail("Test failed as Queue creation succeded.");
+ //conn will be automatically closed
+ }
+ catch (AMQException e)
+ {
+ check403Exception(e);
+ }
+ }
+
+ public void testClientPublishUsingTransactionSuccess() throws AMQException, URLSyntaxException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
+
+ conn.start();
+
+ MessageProducer sender = sess.createProducer(sess.createQueue("example.RequestQueue"));
+
+ sender.send(sess.createTextMessage("test"));
+
+ //Send the message using a transaction as this will allow us to retrieve any errors that occur on the broker.
+ sess.commit();
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test publish failed:" + e);
+ }
+ }
+
+ public void testClientPublishValidQueueSuccess() throws AMQException, URLSyntaxException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ MessageProducer sender = ((AMQSession<?, ?>) sess).createProducer(null);
+
+ Queue queue = sess.createQueue("example.RequestQueue");
+
+ // Send a message that we will wait to be sent, this should give the broker time to process the msg
+ // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
+ // queue existence.
+ ((org.apache.qpid.jms.MessageProducer) sender).send(queue, sess.createTextMessage("test"),
+ DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test publish failed:" + e);
+ }
+ }
+
+ public void testClientPublishInvalidQueueSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ MessageProducer sender = ((AMQSession<?, ?>) session).createProducer(null);
+
+ Queue queue = session.createQueue("Invalid");
+
+ // Send a message that we will wait to be sent, this should give the broker time to close the connection
+ // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
+ // queue existence.
+ ((org.apache.qpid.jms.MessageProducer) sender).send(queue, session.createTextMessage("test"),
+ DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
+
+ // Test the connection with a valid consumer
+ // This may fail as the session may be closed before the queue or the consumer created.
+ Queue temp = session.createTemporaryQueue();
+
+ session.createConsumer(temp).close();
+
+ //Connection should now be closed and will throw the exception caused by the above send
+ conn.close();
+
+ fail("Close is not expected to succeed.");
+ }
+ catch (IllegalStateException e)
+ {
+ _logger.info("QPID-2345: Session became closed and we got that error rather than the authentication error.");
+ }
+ catch (JMSException e)
+ {
+ check403Exception(e.getLinkedException());
+ }
+ }
+
+ public void testServerConsumeFromNamedQueueValid() throws AMQException, URLSyntaxException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "server", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ sess.createConsumer(sess.createQueue("example.RequestQueue"));
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test failed due to:" + e.getMessage());
+ }
+ }
+
+ public void testServerConsumeFromNamedQueueInvalid() throws AMQException, URLSyntaxException, NamingException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ sess.createConsumer(sess.createQueue("Invalid"));
+
+ fail("Test failed as consumer was created.");
+ }
+ catch (JMSException e)
+ {
+ check403Exception(e.getLinkedException());
+ }
+ }
+
+ public void testServerConsumeFromTemporaryQueue() throws AMQException, URLSyntaxException, NamingException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "server", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ sess.createConsumer(sess.createTemporaryQueue());
+
+ fail("Test failed as consumer was created.");
+ }
+ catch (JMSException e)
+ {
+ check403Exception(e.getLinkedException());
+ }
+ }
+
+ public void testServerCreateNamedQueueValid() throws JMSException, URLSyntaxException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "server", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ //Create Temporary Queue
+ ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("example.RequestQueue"), false, false, false);
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test failed due to:" + e.getMessage());
+ }
+ }
+
+ public void testServerCreateNamedQueueInvalid() throws JMSException, URLSyntaxException, AMQException, NamingException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "server", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ //Create a Named Queue
+ ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("IllegalQueue"), false, false, false);
+
+ fail("Test failed as creation succeded.");
+ }
+ catch (Exception e)
+ {
+ check403Exception(e);
+ }
+ }
+
+ public void testServerCreateTemporaryQueueInvalid() throws NamingException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "server", "guest");
+ Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ session.createTemporaryQueue();
+
+ fail("Test failed as creation succeded.");
+ }
+ catch (JMSException e)
+ {
+ check403Exception(e.getLinkedException());
+ }
+ }
+
+ public void testServerCreateAutoDeleteQueueInvalid() throws NamingException, JMSException, AMQException, Exception
+ {
+ try
+ {
+ Connection connection = getConnection("test", "server", "guest");
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ connection.start();
+
+ ((AMQSession<?, ?>) session).createQueue(new AMQShortString("again_ensure_auto_delete_queue_for_temporary"),
+ true, false, false);
+
+ fail("Test failed as creation succeded.");
+ }
+ catch (Exception e)
+ {
+ check403Exception(e);
+ }
+ }
+
+ /**
+ * This test uses both the cilent and sender to validate that the Server is able to publish to a temporary queue.
+ * The reason the client must be involved is that the Server is unable to create its own Temporary Queues.
+ *
+ * @throws AMQException
+ * @throws URLSyntaxException
+ * @throws JMSException
+ */
+ public void testServerPublishUsingTransactionSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
+ {
+ //Set up the Server
+ Connection serverConnection = getConnection("test", "server", "guest");
+
+ Session serverSession = serverConnection.createSession(true, Session.SESSION_TRANSACTED);
+
+ Queue requestQueue = serverSession.createQueue("example.RequestQueue");
+
+ MessageConsumer server = serverSession.createConsumer(requestQueue);
+
+ serverConnection.start();
+
+ //Set up the consumer
+ Connection clientConnection = getConnection("test", "client", "guest");
+
+ //Send a test mesage
+ Session clientSession = clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ Queue responseQueue = clientSession.createTemporaryQueue();
+
+ MessageConsumer clientResponse = clientSession.createConsumer(responseQueue);
+
+ clientConnection.start();
+
+ Message request = clientSession.createTextMessage("Request");
+
+ assertNotNull("Response Queue is null", responseQueue);
+
+ request.setJMSReplyTo(responseQueue);
+
+ clientSession.createProducer(requestQueue).send(request);
+
+ try
+ {
+ Message msg = null;
+
+ msg = server.receive(2000);
+
+ while (msg != null && !((TextMessage) msg).getText().equals("Request"))
+ {
+ msg = server.receive(2000);
+ }
+
+ assertNotNull("Message not received", msg);
+
+ assertNotNull("Reply-To is Null", msg.getJMSReplyTo());
+
+ MessageProducer sender = serverSession.createProducer(msg.getJMSReplyTo());
+
+ sender.send(serverSession.createTextMessage("Response"));
+
+ //Send the message using a transaction as this will allow us to retrieve any errors that occur on the broker.
+ serverSession.commit();
+
+ //Ensure Response is received.
+ Message clientResponseMsg = clientResponse.receive(2000);
+ assertNotNull("Client did not receive response message,", clientResponseMsg);
+ assertEquals("Incorrect message received", "Response", ((TextMessage) clientResponseMsg).getText());
+
+ }
+ catch (Exception e)
+ {
+ fail("Test publish failed:" + e);
+ }
+ finally
+ {
+ try
+ {
+ serverConnection.close();
+ }
+ finally
+ {
+ clientConnection.close();
+ }
+ }
+ }
+
+ public void testServerPublishInvalidQueueSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "server", "guest");
+
+ ((AMQConnection) conn).setConnectionListener(this);
+
+ Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ MessageProducer sender = ((AMQSession<?, ?>) session).createProducer(null);
+
+ Queue queue = session.createQueue("Invalid");
+
+ // Send a message that we will wait to be sent, this should give the broker time to close the connection
+ // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
+ // queue existence.
+ ((org.apache.qpid.jms.MessageProducer) sender).send(queue, session.createTextMessage("test"),
+ DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
+
+ // Test the connection with a valid consumer
+ // This may not work as the session may be closed before the queue or consumer creation can occur.
+ // The correct JMSexception with linked error will only occur when the close method is recevied whilst in
+ // the failover safe block
+ session.createConsumer(session.createQueue("example.RequestQueue")).close();
+
+ //Connection should now be closed and will throw the exception caused by the above send
+ conn.close();
+
+ fail("Close is not expected to succeed.");
+ }
+ catch (IllegalStateException e)
+ {
+ _logger.info("QPID-2345: Session became closed and we got that error rather than the authentication error.");
+ }
+ catch (JMSException e)
+ {
+ check403Exception(e.getLinkedException());
+ }
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java
index 2d99a44532..f40e95885d 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java
@@ -85,6 +85,12 @@ public class FirewallConfigTest extends QpidBrokerTestCase
public void testVhostAllowBrokerDeny() throws Exception
{
+ if (_broker.equals(VM))
+ {
+ //No point running this test with an InVM broker as the
+ //firewall plugin only functions for TCP connections.
+ return;
+ }
_configFile = new File(System.getProperty("QPID_HOME"), "etc/config-systests-firewall-2.xml");
@@ -119,6 +125,13 @@ public class FirewallConfigTest extends QpidBrokerTestCase
public void testVhostDenyBrokerAllow() throws Exception
{
+ if (_broker.equals(VM))
+ {
+ //No point running this test with an InVM broker as the
+ //firewall plugin only functions for TCP connections.
+ return;
+ }
+
_configFile = new File(System.getProperty("QPID_HOME"), "etc/config-systests-firewall-3.xml");
super.setUp();
@@ -264,6 +277,11 @@ public class FirewallConfigTest extends QpidBrokerTestCase
private void testFirewall(boolean initial, boolean inVhost, Runnable restartOrReload) throws Exception
{
+ if (_broker.equals(VM))
+ {
+ // No point running this test in a vm broker
+ return;
+ }
writeFirewallFile(initial, inVhost);
setConfigurationProperty("management.enabled", String.valueOf(true));
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java
index b5bb74327e..51589c705f 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java
@@ -25,37 +25,25 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
-import java.util.Properties;
-
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.Queue;
-import javax.jms.QueueReceiver;
-import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
-import javax.jms.TopicSession;
-import javax.jms.TopicSubscriber;
import javax.naming.Context;
-import javax.naming.InitialContext;
import org.apache.qpid.client.AMQAnyDestination;
-import org.apache.qpid.client.AMQConnection;
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;
-import org.apache.qpid.transport.ExecutionErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -199,7 +187,9 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
dest.getAddressName(),dest.getAddressName(), dest.getSourceNode().getDeclareArgs()));
}
-
+
+ // todo add tests for delete options
+
public void testCreateQueue() throws Exception
{
Session jmsSession = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
@@ -212,7 +202,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
"durable: true ," +
"x-declare: " +
"{" +
- "exclusive: true," +
+ "auto-delete: true," +
"arguments: {" +
"'qpid.max_size': 1000," +
"'qpid.max_count': 100" +
@@ -228,9 +218,6 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
"}";
AMQDestination dest = new AMQAnyDestination(addr);
MessageConsumer cons = jmsSession.createConsumer(dest);
- cons.close();
-
- // 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));
@@ -259,44 +246,12 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
(AMQSession_0_10)jmsSession).isQueueBound("amq.match",
dest.getAddressName(),null, args));
- MessageProducer prod = jmsSession.createProducer(dest);
- prod.send(jmsSession.createTextMessage("test"));
-
- MessageConsumer cons2 = jmsSession.createConsumer(jmsSession.createQueue("ADDR:my-queue"));
- Message m = cons2.receive(1000);
- assertNotNull("Should receive message sent to my-queue",m);
- assertEquals("The subject set in the message is incorrect","hello",m.getStringProperty(QpidMessageProperties.QPID_SUBJECT));
}
public void testCreateExchange() throws Exception
{
- createExchangeImpl(false, false);
- }
-
- /**
- * Verify creating an exchange via an Address, with supported
- * exchange-declare arguments.
- */
- public void testCreateExchangeWithArgs() throws Exception
- {
- createExchangeImpl(true, false);
- }
-
- /**
- * Verify that when creating an exchange via an Address, if a
- * nonsense argument is specified the broker throws an execution
- * exception back on the session with NOT_IMPLEMENTED status.
- */
- public void testCreateExchangeWithNonsenseArgs() throws Exception
- {
- createExchangeImpl(true, true);
- }
-
- private void createExchangeImpl(final boolean withExchangeArgs,
- final boolean useNonsenseArguments) throws Exception
- {
Session jmsSession = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
-
+
String addr = "ADDR:my-exchange/hello; " +
"{ " +
"create: always, " +
@@ -306,36 +261,17 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
"x-declare: " +
"{ " +
"type:direct, " +
- "auto-delete: true" +
- createExchangeArgsString(withExchangeArgs, useNonsenseArguments) +
+ "auto-delete: true, " +
+ "arguments: {" +
+ "'qpid.msg_sequence': 1, " +
+ "'qpid.ive': 1" +
+ "}" +
"}" +
"}" +
"}";
AMQDestination dest = new AMQAnyDestination(addr);
-
- MessageConsumer cons;
- try
- {
- cons = jmsSession.createConsumer(dest);
- if(useNonsenseArguments)
- {
- fail("Expected execution exception during exchange declare did not occur");
- }
- }
- catch(JMSException e)
- {
- if(useNonsenseArguments && e.getCause().getMessage().contains(ExecutionErrorCode.NOT_IMPLEMENTED.toString()))
- {
- //expected because we used an argument which the broker doesn't have functionality
- //for. We can't do the rest of the test as a result of the exception, just stop.
- return;
- }
- else
- {
- fail("Unexpected exception whilst creating consumer: " + e);
- }
- }
+ MessageConsumer cons = jmsSession.createConsumer(dest);
assertTrue("Exchange not created as expected",(
(AMQSession_0_10)jmsSession).isExchangeExist(dest, (ExchangeNode)dest.getTargetNode() , true));
@@ -350,66 +286,16 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
cons = jmsSession.createConsumer(dest);
}
- private String createExchangeArgsString(final boolean withExchangeArgs,
- final boolean useNonsenseArguments)
- {
- String argsString;
-
- if(withExchangeArgs && useNonsenseArguments)
- {
- argsString = ", arguments: {" +
- "'abcd.1234.wxyz': 1, " +
- "}";
- }
- else if(withExchangeArgs)
- {
- argsString = ", arguments: {" +
- "'qpid.msg_sequence': 1, " +
- "'qpid.ive': 1" +
- "}";
- }
- else
- {
- argsString = "";
- }
-
- return argsString;
- }
-
- 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));
-
- assertTrue("Queue not bound as expected",(
- (AMQSession_0_10)jmsSession).isQueueBound("",
- dest.getAddressName(),dest.getAddressName(), null));
-
- assertTrue("Queue not bound as expected",(
- (AMQSession_0_10)jmsSession).isQueueBound("amq.direct",
- dest.getAddressName(),"test", null));
-
- assertTrue("Queue not bound as expected",(
- (AMQSession_0_10)jmsSession).isQueueBound("amq.topic",
- dest.getAddressName(),"a.#", null));
-
- Address a = Address.parse(headersBinding);
- assertTrue("Queue not bound as expected",(
- (AMQSession_0_10)jmsSession).isQueueBound("amq.match",
- dest.getAddressName(),null, a.getOptions()));
- }
-
- /**
- * Test goal: Verifies that a producer and consumer creation triggers the correct
- * behavior for x-bindings specified in node props.
- */
public void testBindQueueWithArgs() throws Exception
{
+ Session jmsSession = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
- Session jmsSession = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
String headersBinding = "{exchange: 'amq.match', arguments: {x-match: any, dep: sales, loc: CA}}";
- String addr = "node: " +
+ String addr = "ADDR:my-queue/hello; " +
+ "{ " +
+ "create: always, " +
+ "node: " +
"{" +
"durable: true ," +
"x-declare: " +
@@ -424,14 +310,28 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
"}" +
"}";
+ AMQDestination dest = new AMQAnyDestination(addr);
+ MessageConsumer cons = jmsSession.createConsumer(dest);
+
+ assertTrue("Queue not created as expected",(
+ (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+
+ assertTrue("Queue not bound as expected",(
+ (AMQSession_0_10)jmsSession).isQueueBound("",
+ dest.getAddressName(),dest.getAddressName(), null));
- AMQDestination dest1 = new AMQAnyDestination("ADDR:my-queue/hello; {create: receiver, " +addr);
- MessageConsumer cons = jmsSession.createConsumer(dest1);
- checkQueueForBindings(jmsSession,dest1,headersBinding);
+ assertTrue("Queue not bound as expected",(
+ (AMQSession_0_10)jmsSession).isQueueBound("amq.direct",
+ dest.getAddressName(),"test", null));
+
+ assertTrue("Queue not bound as expected",(
+ (AMQSession_0_10)jmsSession).isQueueBound("amq.topic",
+ dest.getAddressName(),"a.#", null));
- AMQDestination dest2 = new AMQAnyDestination("ADDR:my-queue2/hello; {create: sender, " +addr);
- MessageProducer prod = jmsSession.createProducer(dest2);
- checkQueueForBindings(jmsSession,dest2,headersBinding);
+ Address a = Address.parse(headersBinding);
+ assertTrue("Queue not bound as expected",(
+ (AMQSession_0_10)jmsSession).isQueueBound("amq.match",
+ dest.getAddressName(),null, a.getOptions()));
}
/**
@@ -567,6 +467,39 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
}
/**
+ * Test goal: Verifies that and address based destination can be used successfully
+ * as a reply to.
+ */
+ public void testAddressBasedReplyTo() throws Exception
+ {
+ Session jmsSession = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
+
+ String addr = "ADDR:amq.direct/x512; {create: receiver, " +
+ "link : {name : 'MY.RESP.QUEUE', " +
+ "x-declare : { auto-delete: true, exclusive: true, " +
+ "arguments : {'qpid.max_size': 1000, 'qpid.policy_type': ring }} } }";
+
+ Destination replyTo = new AMQAnyDestination(addr);
+ Destination dest =new AMQAnyDestination("ADDR:amq.direct/Hello");
+
+ MessageConsumer cons = jmsSession.createConsumer(dest);
+ MessageProducer prod = jmsSession.createProducer(dest);
+ Message m = jmsSession.createTextMessage("Hello");
+ m.setJMSReplyTo(replyTo);
+ prod.send(m);
+
+ Message msg = cons.receive(1000);
+ assertNotNull("consumer should have received the message",msg);
+
+ MessageConsumer replyToCons = jmsSession.createConsumer(replyTo);
+ MessageProducer replyToProd = jmsSession.createProducer(msg.getJMSReplyTo());
+ replyToProd.send(jmsSession.createTextMessage("reply"));
+
+ Message replyToMsg = replyToCons.receive(1000);
+ assertNotNull("The reply to consumer should have got the message",replyToMsg);
+ }
+
+ /**
* Test goal: Verifies that session.createQueue method
* works as expected both with the new and old addressing scheme.
*/
@@ -587,22 +520,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
cons.close();
// Using the ADDR method
- // default case
queue = ssn.createQueue("ADDR:my-queue2");
- try
- {
- prod = ssn.createProducer(queue);
- fail("The client should throw an exception, since there is no queue present in the broker");
- }
- catch(Exception e)
- {
- String s = "The name 'my-queue2' supplied in the address " +
- "doesn't resolve to an exchange or a queue";
- assertEquals(s,e.getCause().getCause().getMessage());
- }
-
- // explicit create case
- queue = ssn.createQueue("ADDR:my-queue2; {create: sender}");
prod = ssn.createProducer(queue);
cons = ssn.createConsumer(queue);
assertTrue("my-queue2 was not created as expected",(
@@ -629,25 +547,11 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
}
/**
- * Test goal: Verifies that session.creatTopic method works as expected
- * both with the new and old addressing scheme.
+ * Test goal: Verifies that session.creatTopic method
+ * works as expected both with the new and old addressing scheme.
*/
public void testSessionCreateTopic() throws Exception
{
- sessionCreateTopicImpl(false);
- }
-
- /**
- * Test goal: Verifies that session.creatTopic method works as expected
- * both with the new and old addressing scheme when adding exchange arguments.
- */
- public void testSessionCreateTopicWithExchangeArgs() throws Exception
- {
- sessionCreateTopicImpl(true);
- }
-
- private void sessionCreateTopicImpl(boolean withExchangeArgs) throws Exception
- {
Session ssn = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
// Using the BURL method
@@ -667,7 +571,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
prod.send(ssn.createTextMessage("test"));
assertNotNull("consumer should receive a message",cons.receive(1000));
cons.close();
-
+
String addr = "ADDR:vehicles/bus; " +
"{ " +
"create: always, " +
@@ -677,8 +581,11 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
"x-declare: " +
"{ " +
"type:direct, " +
- "auto-delete: true" +
- createExchangeArgsString(withExchangeArgs, false) +
+ "auto-delete: true, " +
+ "arguments: {" +
+ "'qpid.msg_sequence': 1, " +
+ "'qpid.ive': 1" +
+ "}" +
"}" +
"}, " +
"link: {name : my-topic, " +
@@ -790,7 +697,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);
@@ -889,297 +796,4 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
{
}
}
-
- public void testQueueReceiversAndTopicSubscriber() throws Exception
- {
- Queue queue = new AMQAnyDestination("ADDR:my-queue; {create: always}");
- Topic topic = new AMQAnyDestination("ADDR:amq.topic/test");
-
- QueueSession qSession = ((AMQConnection)_connection).createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
- QueueReceiver receiver = qSession.createReceiver(queue);
-
- TopicSession tSession = ((AMQConnection)_connection).createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
- TopicSubscriber sub = tSession.createSubscriber(topic);
-
- Session ssn = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer prod1 = ssn.createProducer(ssn.createQueue("ADDR:my-queue"));
- prod1.send(ssn.createTextMessage("test1"));
-
- MessageProducer prod2 = ssn.createProducer(ssn.createTopic("ADDR:amq.topic/test"));
- prod2.send(ssn.createTextMessage("test2"));
-
- Message msg1 = receiver.receive();
- assertNotNull(msg1);
- assertEquals("test1",((TextMessage)msg1).getText());
-
- Message msg2 = sub.receive();
- assertNotNull(msg2);
- assertEquals("test2",((TextMessage)msg2).getText());
- }
-
- public void testDurableSubscriber() throws Exception
- {
- Session ssn = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
-
- 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.address5", addrStr);
-
- Context ctx = new InitialContext(props);
-
- for (int i=1; i < 5; i++)
- {
- Topic topic = (Topic) ctx.lookup("address"+i);
- createDurableSubscriber(ctx,ssn,"address"+i,topic);
- }
-
- Topic topic = ssn.createTopic("ADDR:news.us");
- createDurableSubscriber(ctx,ssn,"my-dest",topic);
-
- Topic namedQueue = (Topic) ctx.lookup("address5");
- try
- {
- createDurableSubscriber(ctx,ssn,"my-queue",namedQueue);
- fail("Exception should be thrown. Durable subscribers cannot be created for Queues");
- }
- catch(JMSException e)
- {
- assertEquals("Durable subscribers can only be created for Topics",
- e.getMessage());
- }
- }
-
- private void createDurableSubscriber(Context ctx,Session ssn,String destName,Topic topic) throws Exception
- {
- MessageConsumer cons = ssn.createDurableSubscriber(topic, destName);
- MessageProducer prod = ssn.createProducer(topic);
-
- Message m = ssn.createTextMessage(destName);
- prod.send(m);
- Message msg = cons.receive(1000);
- assertNotNull(msg);
- assertEquals(destName,((TextMessage)msg).getText());
- ssn.unsubscribe(destName);
- }
-
- public void testDeleteOptions() throws Exception
- {
- Session jmsSession = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
- MessageConsumer cons;
-
- // default (create never, assert never) -------------------
- // create never --------------------------------------------
- String addr1 = "ADDR:testQueue1;{create: always, delete: always}";
- AMQDestination dest = new AMQAnyDestination(addr1);
- try
- {
- cons = jmsSession.createConsumer(dest);
- cons.close();
- }
- catch(JMSException e)
- {
- fail("Exception should not be thrown. Exception thrown is : " + e);
- }
-
- assertFalse("Queue not deleted as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
-
-
- String addr2 = "ADDR:testQueue2;{create: always, delete: receiver}";
- dest = new AMQAnyDestination(addr2);
- try
- {
- cons = jmsSession.createConsumer(dest);
- cons.close();
- }
- catch(JMSException e)
- {
- fail("Exception should not be thrown. Exception thrown is : " + e);
- }
-
- assertFalse("Queue not deleted as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
-
-
- String addr3 = "ADDR:testQueue3;{create: always, delete: sender}";
- dest = new AMQAnyDestination(addr3);
- try
- {
- cons = jmsSession.createConsumer(dest);
- MessageProducer prod = jmsSession.createProducer(dest);
- prod.close();
- }
- catch(JMSException e)
- {
- fail("Exception should not be thrown. Exception thrown is : " + e);
- }
-
- assertFalse("Queue not deleted as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
-
-
- }
-
- /**
- * Test Goals : 1. Test if the client sets the correct accept mode for unreliable
- * and at-least-once.
- * 2. Test default reliability modes for Queues and Topics.
- * 3. Test if an exception is thrown if exactly-once is used.
- * 4. Test if an exception is thrown if at-least-once is used with topics.
- *
- * Test Strategy: For goal #1 & #2
- * For unreliable and at-least-once the test tries to receives messages
- * in client_ack mode but does not ack the messages.
- * It will then close the session, recreate a new session
- * and will then try to verify the queue depth.
- * For unreliable the messages should have been taken off the queue.
- * For at-least-once the messages should be put back onto the queue.
- *
- */
-
- public void testReliabilityOptions() throws Exception
- {
- String addr1 = "ADDR:testQueue1;{create: always, delete : receiver, link : {reliability : unreliable}}";
- acceptModeTest(addr1,0);
-
- String addr2 = "ADDR:testQueue2;{create: always, delete : receiver, link : {reliability : at-least-once}}";
- acceptModeTest(addr2,2);
-
- // Default accept-mode for topics
- acceptModeTest("ADDR:amq.topic/test",0);
-
- // Default accept-mode for queues
- acceptModeTest("ADDR:testQueue1;{create: always}",2);
-
- String addr3 = "ADDR:testQueue2;{create: always, delete : receiver, link : {reliability : exactly-once}}";
- try
- {
- AMQAnyDestination dest = new AMQAnyDestination(addr3);
- fail("An exception should be thrown indicating it's an unsupported type");
- }
- catch(Exception e)
- {
- assertTrue(e.getCause().getMessage().contains("The reliability mode 'exactly-once' is not yet supported"));
- }
-
- String addr4 = "ADDR:amq.topic/test;{link : {reliability : at-least-once}}";
- try
- {
- AMQAnyDestination dest = new AMQAnyDestination(addr4);
- Session ssn = _connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
- MessageConsumer cons = ssn.createConsumer(dest);
- fail("An exception should be thrown indicating it's an unsupported combination");
- }
- catch(Exception e)
- {
- assertTrue(e.getCause().getMessage().contains("AT-LEAST-ONCE is not yet supported for Topics"));
- }
- }
-
- private void acceptModeTest(String address, int expectedQueueDepth) throws Exception
- {
- Session ssn = _connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
- MessageConsumer cons;
- MessageProducer prod;
-
- AMQDestination dest = new AMQAnyDestination(address);
- cons = ssn.createConsumer(dest);
- prod = ssn.createProducer(dest);
-
- for (int i=0; i < expectedQueueDepth; i++)
- {
- prod.send(ssn.createTextMessage("Msg" + i));
- }
-
- for (int i=0; i < expectedQueueDepth; i++)
- {
- Message msg = cons.receive(1000);
- assertNotNull(msg);
- assertEquals("Msg" + i,((TextMessage)msg).getText());
- }
-
- ssn.close();
- ssn = _connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
- long queueDepth = ((AMQSession) ssn).getQueueDepth(dest);
- assertEquals(expectedQueueDepth,queueDepth);
- cons.close();
- prod.close();
- }
-
- public void testDestinationOnSend() throws Exception
- {
- Session ssn = _connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
- MessageConsumer cons = ssn.createConsumer(ssn.createTopic("amq.topic/test"));
- MessageProducer prod = ssn.createProducer(null);
-
- Queue queue = ssn.createQueue("amq.topic/test");
- prod.send(queue,ssn.createTextMessage("A"));
-
- Message msg = cons.receive(1000);
- assertNotNull(msg);
- assertEquals("A",((TextMessage)msg).getText());
- prod.close();
- cons.close();
- }
-
- public void testReplyToWithNamelessExchange() throws Exception
- {
- System.setProperty("qpid.declare_exchanges","false");
- replyToTest("ADDR:my-queue;{create: always}");
- System.setProperty("qpid.declare_exchanges","true");
- }
-
- public void testReplyToWithCustomExchange() throws Exception
- {
- replyToTest("ADDR:hello;{create:always,node:{type:topic}}");
- }
-
- private void replyToTest(String replyTo) throws Exception
- {
- Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Destination replyToDest = AMQDestination.createDestination(replyTo);
- MessageConsumer replyToCons = session.createConsumer(replyToDest);
-
- Destination dest = session.createQueue("amq.direct/test");
-
- MessageConsumer cons = session.createConsumer(dest);
- MessageProducer prod = session.createProducer(dest);
- Message m = session.createTextMessage("test");
- m.setJMSReplyTo(replyToDest);
- prod.send(m);
-
- Message msg = cons.receive();
- MessageProducer prodR = session.createProducer(msg.getJMSReplyTo());
- prodR.send(session.createTextMessage("x"));
-
- Message m1 = replyToCons.receive();
- assertNotNull("The reply to consumer should have received the messsage",m1);
- }
-
- public void testAltExchangeInAddressString() throws Exception
- {
- String addr1 = "ADDR:my-exchange/test; {create: always, node:{type: topic,x-declare:{alternate-exchange:'amq.fanout'}}}";
- Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- String altQueueAddr = "ADDR:my-alt-queue;{create: always, delete: receiver,node:{x-bindings:[{exchange:'amq.fanout'}] }}";
- MessageConsumer cons = session.createConsumer(session.createQueue(altQueueAddr));
-
- MessageProducer prod = session.createProducer(session.createTopic(addr1));
- prod.send(session.createMessage());
- prod.close();
- assertNotNull("The consumer on the queue bound to the alt-exchange should receive the message",cons.receive(1000));
-
- String addr2 = "ADDR:test-queue;{create:sender, delete: sender,node:{type:queue,x-declare:{alternate-exchange:'amq.fanout'}}}";
- prod = session.createProducer(session.createTopic(addr2));
- prod.send(session.createMessage());
- prod.close();
- assertNotNull("The consumer on the queue bound to the alt-exchange should receive the message",cons.receive(1000));
- cons.close();
- }
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java
index b1c8b5682f..49a608190d 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java
@@ -23,7 +23,6 @@ package org.apache.qpid.test.client.message;
import java.util.concurrent.CountDownLatch;
import javax.jms.DeliveryMode;
-import javax.jms.Destination;
import javax.jms.InvalidSelectorException;
import javax.jms.JMSException;
import javax.jms.Message;
@@ -31,7 +30,6 @@ import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
-import javax.jms.TextMessage;
import junit.framework.Assert;
@@ -52,6 +50,7 @@ public class SelectorTest extends QpidBrokerTestCase implements MessageListener
private AMQConnection _connection;
private AMQDestination _destination;
private int count;
+ public String _connectionString = "vm://:1";
private static final String INVALID_SELECTOR = "Cost LIKE 5";
CountDownLatch _responseLatch = new CountDownLatch(1);
@@ -281,36 +280,31 @@ public class SelectorTest extends QpidBrokerTestCase implements MessageListener
Assert.assertNotNull("Msg5 should not be null", msg5);
}
- public void testSelectorWithJMSDeliveryMode() throws Exception
+ public static void main(String[] argv) throws Exception
{
- Session session = _connection.createSession(false, Session.SESSION_TRANSACTED);
+ SelectorTest test = new SelectorTest();
+ test._connectionString = (argv.length == 0) ? "localhost:3000" : argv[0];
- Destination dest1 = session.createTopic("test1");
- Destination dest2 = session.createTopic("test2");
-
- MessageProducer prod1 = session.createProducer(dest1);
- MessageProducer prod2 = session.createProducer(dest2);
- MessageConsumer consumer1 = session.createConsumer(dest1,"JMSDeliveryMode = 'PERSISTENT'");
- MessageConsumer consumer2 = session.createConsumer(dest2,"JMSDeliveryMode = 'NON_PERSISTENT'");
-
- Message msg1 = session.createTextMessage("Persistent");
- prod1.send(msg1);
- prod2.send(msg1);
-
- prod1.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
- prod2.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
-
- Message msg2 = session.createTextMessage("Non_Persistent");
- prod1.send(msg2);
- prod2.send(msg2);
-
- TextMessage m1 = (TextMessage)consumer1.receive(1000);
- assertEquals("Consumer1 should receive the persistent message","Persistent",m1.getText());
- assertNull("Consumer1 should not receiver another message",consumer1.receive(1000));
-
- TextMessage m2 = (TextMessage)consumer2.receive(1000);
- assertEquals("Consumer2 should receive the non persistent message","Non_Persistent",m2.getText());
- assertNull("Consumer2 should not receiver another message",consumer2.receive(1000));
+ try
+ {
+ while (true)
+ {
+ if (test._connectionString.contains("vm://:1"))
+ {
+ test.setUp();
+ }
+ test.testUsingOnMessage();
+
+ if (test._connectionString.contains("vm://:1"))
+ {
+ test.tearDown();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ System.err.println(e.getMessage());
+ e.printStackTrace();
+ }
}
-
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/AMQPFeatureDecorator.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/AMQPFeatureDecorator.java
new file mode 100644
index 0000000000..c11f75e742
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/AMQPFeatureDecorator.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.test.framework.qpid;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+import org.apache.qpid.test.framework.FrameworkBaseCase;
+import org.apache.qpid.test.framework.LocalAMQPCircuitFactory;
+
+import org.apache.qpid.junit.extensions.WrappedSuiteTestDecorator;
+
+/**
+ * AMQPFeatureDecorator applies decorations to {@link FrameworkBaseCase} tests, so that they may use Qpid/AMQP specific
+ * features, not available through JMS. For example, the immediate and mandatory flags. This decorator replaces the
+ * standard test circuit factory on the base class with one that allows these features to be used.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Substitute the circuit factory with an AMQP/Qpid specific one.
+ * </table>
+ *
+ * @todo This wrapper substitutes in a LocalAMQPCircuitFactory, which is fine for local tests. For distributed tests
+ * the Fanout or Interop factories are substituted in by their decorators instead. These actually use
+ * distributed circuit static create methods to build the circuits, which should actually be changed to a factory,
+ * so that static methods do not need to be used. The distributed circuit creater delegates the circuit
+ * construction to remote test nodes. This decorator should not be used with distributed tests, or should be made
+ * aware of them, in which case it might ensure that an AMQP feature (implied already by other properties) flag
+ * is passed out to the remote test nodes, and provide a mechansim for them to decorate their circuit creation
+ * with AMQP features too. Add factory substituion/decoration mechansim for test clients, here or in a seperate
+ * class.
+ */
+public class AMQPFeatureDecorator extends WrappedSuiteTestDecorator
+{
+ /** The test suite to run. */
+ private Test test;
+
+ /**
+ * Creates a wrapped test test decorator from another one.
+ *
+ * @param test The test test.
+ */
+ public AMQPFeatureDecorator(WrappedSuiteTestDecorator test)
+ {
+ super(test);
+ this.test = test;
+ }
+
+ /**
+ * Runs the tests with a LocalAMQPCircuitFactory. Only tests that extend FrameworkBaseCase are decorated.
+ *
+ * @param testResult The the results object to monitor the test results with.
+ */
+ public void run(TestResult testResult)
+ {
+ for (Test test : getAllUnderlyingTests())
+ {
+ if (test instanceof FrameworkBaseCase)
+ {
+ FrameworkBaseCase frameworkTest = (FrameworkBaseCase) test;
+ frameworkTest.setCircuitFactory(new LocalAMQPCircuitFactory());
+ }
+ }
+
+ // Run the test.
+ test.run(testResult);
+ }
+
+ /**
+ * Prints the name of the test for debugging purposes.
+ *
+ * @return The name of the test.
+ */
+ public String toString()
+ {
+ return "AMQPFeatureDecorator: [test = \"" + test + "\"]";
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureDecorator.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureDecorator.java
new file mode 100644
index 0000000000..2708253d86
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureDecorator.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.test.framework.qpid;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+import org.apache.qpid.test.framework.BrokerLifecycleAware;
+import org.apache.qpid.test.framework.CauseFailureUserPrompt;
+
+import org.apache.qpid.junit.extensions.WrappedSuiteTestDecorator;
+
+/**
+ * CauseFailureDecorator applies decorations to {@link BrokerLifecycleAware} tests, so that they may use different failure
+ * mechanisms. It is capable of detecting when a test case uses in-vm brokers, and setting up an automatic failure
+ * for those tests, so that the current live broker can be shut-down by test cases. For external brokers, automatic
+ * failure could be implemented, for example by having a kill script. At the moment this sets up the failure to prompt
+ * a user interactively to cause a failure, using {@link CauseFailureUserPrompt}.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Setup automatic failures for in-vm brokers. <td> {@link CauseFailureInVM}
+ * <tr><td> Setup user generated failures for external brokers. <td> {@link CauseFailureUserPrompt}.
+ * <tr><td>
+ * </table>
+ *
+ * @todo Slight problem in that CauseFailureInVM is Qpid specific, whereas CauseFailureUserPrompt is not. Would like the
+ * failure decorator to be non-qpid specific so that it can test failure of any JMS implementation too. Either pass
+ * in class name of failure mechanism, set it up in the in-vm decorator instead of here but with prompt user as the
+ * default for when the in-vm decorator is not used?
+ */
+public class CauseFailureDecorator extends WrappedSuiteTestDecorator
+{
+ /** The test suite to run. */
+ private Test test;
+
+ /**
+ * Creates a wrapped test test decorator from another one.
+ *
+ * @param test The test test.
+ */
+ public CauseFailureDecorator(WrappedSuiteTestDecorator test)
+ {
+ super(test);
+ this.test = test;
+ }
+
+ /**
+ * Runs the tests with a LocalAMQPCircuitFactory. Only tests that extend FrameworkBaseCase are decorated.
+ *
+ * @param testResult The the results object to monitor the test results with.
+ */
+ public void run(TestResult testResult)
+ {
+ for (Test test : getAllUnderlyingTests())
+ {
+ if (test instanceof BrokerLifecycleAware)
+ {
+ BrokerLifecycleAware failureTest = (BrokerLifecycleAware) test;
+ failureTest.setFailureMechanism(new CauseFailureUserPrompt());
+ }
+ }
+
+ // Run the test.
+ test.run(testResult);
+ }
+
+ /**
+ * Prints the name of the test for debugging purposes.
+ *
+ * @return The name of the test.
+ */
+ public String toString()
+ {
+ return "CauseFailureDecorator: [test = \"" + test + "\"]";
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureInVM.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureInVM.java
new file mode 100644
index 0000000000..3e03ad0872
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureInVM.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.test.framework.qpid;
+
+import org.apache.qpid.client.transport.TransportConnection;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.test.framework.CauseFailure;
+import org.apache.qpid.test.framework.BrokerLifecycleAware;
+
+/**
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Cause messaging broker failure on the active in-vm broker.
+ * <td> {@link TransportConnection}, {@link ApplicationRegistry}
+ * </table>
+ */
+public class CauseFailureInVM implements CauseFailure
+{
+ /** Holds the in-vm broker instrumented test case to create failures for. */
+ private BrokerLifecycleAware inVMTest;
+
+ /**
+ * Creates an automated failure mechanism for testing against in-vm brokers. The test to create the mechanism
+ * for is specified, and as this failure is for in-vm brokers, the test must be {@link org.apache.qpid.test.framework.BrokerLifecycleAware}. The test
+ * must also report that it is currently being run against an in-vm broker, and it is a runtime error if it is not,
+ * as the creator of this failure mechanism should already have checked that it is.
+ *
+ * @param inVMTest The test case to create an automated failure mechanism for.
+ */
+ public CauseFailureInVM(BrokerLifecycleAware inVMTest)
+ {
+ // Check that the test is really using in-vm brokers.
+ if (!inVMTest.usingInVmBroker())
+ {
+ throw new RuntimeException(
+ "Cannot create in-vm broker failure mechanism for a test that is not using in-vm brokers.");
+ }
+
+ this.inVMTest = inVMTest;
+ }
+
+ /**
+ * Causes the active message broker to fail.
+ */
+ public void causeFailure()
+ {
+ int liveBroker = inVMTest.getLiveBroker();
+
+ TransportConnection.killVMBroker(liveBroker);
+ ApplicationRegistry.remove(liveBroker);
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/InVMBrokerDecorator.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/InVMBrokerDecorator.java
new file mode 100644
index 0000000000..b92a72a654
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/InVMBrokerDecorator.java
@@ -0,0 +1,136 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.framework.qpid;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+import org.apache.qpid.client.transport.TransportConnection;
+import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.test.framework.BrokerLifecycleAware;
+import org.apache.qpid.test.framework.FrameworkBaseCase;
+
+import org.apache.qpid.junit.extensions.SetupTaskAware;
+import org.apache.qpid.junit.extensions.WrappedSuiteTestDecorator;
+
+/**
+ * InVMBrokerDecorator is a test decorator, that is activated when running tests against an in-vm broker only. Its
+ * purpose is to automatically create, and close and delete an in-vm broker, during the set-up and tear-down of
+ * each test case. This decorator may only be used in conjunction with tests that extend {@link FrameworkBaseCase}.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Create/Destroy an in-vm broker on every test run.
+ * </table>
+ *
+ * @todo May need to add a more fine grained injection point for the in-vm broker management, as this acts at the
+ * suite level, rather than the individual test level.
+ *
+ * @todo Management of in-vm brokers for failure testing. Failure test setups may need to set their connection url to
+ * use multiple broker (vm://:1;vm://:2), with fail-over between them. There is round-robin fail-over, but also
+ * retry? A test case using an in-vm broker needs to record which one it is using, so that it can be
+ * killed/restarted.
+ */
+public class InVMBrokerDecorator extends WrappedSuiteTestDecorator
+{
+ /** The test suite to run. */
+ private Test test;
+
+ /**
+ * Creates a wrapped test suite decorator from another one.
+ *
+ * @param test The test suite.
+ */
+ public InVMBrokerDecorator(WrappedSuiteTestDecorator test)
+ {
+ super(test);
+ this.test = test;
+ }
+
+ /**
+ * Runs the tests with in-vm broker creation and clean-up added to the tests task stack.
+ *
+ * @param testResult The the results object to monitor the test results with.
+ */
+ public void run(TestResult testResult)
+ {
+ for (Test test : getAllUnderlyingTests())
+ {
+ // Check that the test to have an in-vm broker setup/teardown task added to it, is actually a framework
+ // test that can handle setup tasks.
+ if ((test instanceof SetupTaskAware))
+ {
+ SetupTaskAware frameworkTest = (SetupTaskAware) test;
+
+ frameworkTest.chainSetupTask(new Runnable()
+ {
+ public void run()
+ {
+ // Ensure that the in-vm broker is created.
+ try
+ {
+ ApplicationRegistry.getInstance(1);
+ TransportConnection.createVMBroker(1);
+ }
+ catch (AMQVMBrokerCreationException e)
+ {
+ throw new RuntimeException("In-VM broker creation failed: " + e.getMessage(), e);
+ }
+ }
+ });
+
+ frameworkTest.chainTearDownTask(new Runnable()
+ {
+ public void run()
+ {
+ // Ensure that the in-vm broker is cleaned up so that the next test starts afresh.
+ TransportConnection.killVMBroker(1);
+ ApplicationRegistry.remove(1);
+ }
+ });
+
+ // Check if the test is aware whether or not it can control the broker life cycle, and if so provide
+ // additional instrumentation for it to control the in-vm broker through.
+ if (test instanceof BrokerLifecycleAware)
+ {
+ BrokerLifecycleAware inVMTest = (BrokerLifecycleAware) test;
+ inVMTest.setInVmBrokers();
+ inVMTest.setLiveBroker(1);
+ inVMTest.setFailureMechanism(new CauseFailureInVM(inVMTest));
+ }
+ }
+ }
+
+ // Run the test.
+ test.run(testResult);
+ }
+
+ /**
+ * Prints the name of the test for debugging purposes.
+ *
+ * @return The name of the test.
+ */
+ public String toString()
+ {
+ return "InVMBrokerDecorator: [test = " + test + "]";
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/Acknowledge2ConsumersTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/Acknowledge2ConsumersTest.java
index 23efb656d2..4b45a96c20 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/Acknowledge2ConsumersTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/Acknowledge2ConsumersTest.java
@@ -23,7 +23,7 @@ package org.apache.qpid.test.unit.ack;
import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.FailoverBaseCase;
import javax.jms.Connection;
import javax.jms.JMSException;
@@ -32,7 +32,7 @@ import javax.jms.MessageConsumer;
import javax.jms.Queue;
import javax.jms.Session;
-public class Acknowledge2ConsumersTest extends QpidBrokerTestCase
+public class Acknowledge2ConsumersTest extends FailoverBaseCase
{
protected static int NUM_MESSAGES = 100;
protected Connection _con;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/QuickAcking.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/QuickAcking.java
index 13c78c1e14..6c83136511 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/QuickAcking.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/QuickAcking.java
@@ -20,7 +20,7 @@
*/
package org.apache.qpid.test.unit.ack;
-import java.util.concurrent.CountDownLatch;
+import edu.emory.mathcs.backport.java.util.concurrent.CountDownLatch;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.jms.ConnectionListener;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java
index 87eae32cf8..3a5f676ca6 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java
@@ -23,6 +23,7 @@ import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.AMQTopic;
+import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java
index 481b144caf..292bcd6039 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.test.unit.client;
+import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
@@ -36,9 +37,11 @@ import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.QueueSession;
import javax.jms.Session;
+import javax.jms.TextMessage;
import javax.jms.TopicSession;
import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQConnectionDelegate_0_10;
import org.apache.qpid.client.AMQQueue;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.AMQTopic;
@@ -228,8 +231,7 @@ public class AMQConnectionTest extends QpidBrokerTestCase
}
MessageConsumer consumerB = null;
- // 0-8, 0-9, 0-9-1 prefetch is per session, not consumer.
- if (!isBroker010())
+ if (isBroker08())
{
Session consSessB = _connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
consumerB = consSessB.createConsumer(_queue);
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
index 8577fb5b6a..33575b58aa 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
@@ -20,8 +20,6 @@
*/
package org.apache.qpid.test.unit.client;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import javax.jms.Connection;
@@ -34,9 +32,11 @@ import javax.jms.Session;
*
* 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
{
setSystemProperty("qpid.declare_queues", "false");
@@ -53,8 +53,11 @@ public class DynamicQueueExchangeCreateTest extends QpidBrokerTestCase
fail("JMSException should be thrown as the queue does not exist");
}
catch (JMSException e)
- {
- checkExceptionErrorCode(e, AMQConstant.NOT_FOUND);
+ {
+ assertTrue("Exception should be that the queue does not exist :" +
+ e.getMessage(),
+ e.getMessage().contains("does not exist"));
+
}
}
@@ -76,15 +79,10 @@ public class DynamicQueueExchangeCreateTest extends QpidBrokerTestCase
}
catch (JMSException e)
{
- checkExceptionErrorCode(e, AMQConstant.NOT_FOUND);
+ assertTrue("Exception should be that the exchange does not exist :" +
+ e.getMessage(),
+ e.getMessage().contains("Exchange " + EXCHANGE_TYPE + " does not exist"));
}
}
- private void checkExceptionErrorCode(JMSException original, AMQConstant code)
- {
- Exception linked = original.getLinkedException();
- assertNotNull("Linked exception should have been set", linked);
- assertTrue("Linked exception should be an AMQException", linked instanceof AMQException);
- assertEquals("Error code should be " + code.getCode(), code, ((AMQException) linked).getErrorCode());
- }
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java
index aae8b1feb9..79e2ff8148 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java
@@ -24,6 +24,7 @@ import junit.textui.TestRunner;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.slf4j.Logger;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java
index 2e8a2d049d..f0794c9dab 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java
@@ -25,9 +25,11 @@ import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.failover.FailoverException;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
+import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.framing.*;
import org.apache.qpid.jms.ConnectionListener;
import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.url.URLSyntaxException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,67 +49,70 @@ public class ChannelCloseTest extends QpidBrokerTestCase implements ExceptionLis
private static final Logger _logger = LoggerFactory.getLogger(ChannelCloseTest.class);
Connection _connection;
+ private String _brokerlist = "vm://:1";
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 .
+ /*
+ close channel, use chanel with same id ensure error.
*/
public void testReusingChannelAfterFullClosure() throws Exception
{
- _connection=newConnection();
-
- // Create Producer
- try
+ // this is testing an inVM Connetion conneciton
+ if (isJavaBroker() && !isExternalBroker())
{
- _connection.start();
-
- createChannelAndTest(1);
+ _connection=newConnection();
- // Cause it to close
+ // Create Producer
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());
- }
+ _connection.start();
- // 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())
+ 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)
{
- _logger.info("Exception occured was:" + e.getErrorCode());
+ assertEquals("Exchange should not be found", AMQConstant.NOT_FOUND, e.getErrorCode());
}
- assertEquals("Connection should be closed", AMQConstant.CHANNEL_ERROR, 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());
+ }
- _connection=newConnection();
- }
+ assertEquals("Connection should be closed", AMQConstant.CHANNEL_ERROR, e.getErrorCode());
- checkSendingMessage();
+ _connection=newConnection();
+ }
- _session.close();
- _connection.close();
+ checkSendingMessage();
- }
- catch (JMSException e)
- {
- e.printStackTrace();
- fail(e.getMessage());
+ _session.close();
+ _connection.close();
+
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
}
}
@@ -301,19 +306,27 @@ public class ChannelCloseTest extends QpidBrokerTestCase implements ExceptionLis
private Connection newConnection()
{
- Connection connection = null;
+ AMQConnection connection = null;
try
{
- connection = getConnection();
+ connection = new AMQConnection("amqp://guest:guest@CCTTest/test?brokerlist='" + _brokerlist + "'");
- ((AMQConnection) connection).setConnectionListener(this);
+ connection.setConnectionListener(this);
_session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
connection.start();
}
- catch (Exception e)
+ catch (JMSException e)
+ {
+ fail("Creating new connection when:" + e.getMessage());
+ }
+ catch (AMQException e)
+ {
+ fail("Creating new connection when:" + e.getMessage());
+ }
+ catch (URLSyntaxException e)
{
fail("Creating new connection when:" + e.getMessage());
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java
index 124e756fad..04fc611cd1 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java
@@ -20,30 +20,32 @@
*/
package org.apache.qpid.test.unit.client.connection;
-import javax.jms.Connection;
-import javax.jms.QueueSession;
-import javax.jms.TopicSession;
-
import org.apache.qpid.AMQConnectionFailureException;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQUnresolvedAddressException;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.client.AMQAuthenticationException;
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.client.AMQTopic;
+import org.apache.qpid.client.AMQConnectionURL;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.jms.BrokerDetails;
-import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.jms.Session;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.jms.BrokerDetails;
+
+import javax.jms.Connection;
+import javax.jms.QueueSession;
+import javax.jms.TopicSession;
+import javax.naming.NamingException;
public class ConnectionTest extends QpidBrokerTestCase
{
- String _broker_NotRunning = "tcp://localhost:" + findFreePort();
-
+ String _broker_NotRunning = "vm://:2";
String _broker_BadDNS = "tcp://hg3sgaaw4lgihjs";
public void testSimpleConnection() throws Exception
@@ -85,17 +87,17 @@ public class ConnectionTest extends QpidBrokerTestCase
AMQSession sess = (AMQSession) conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- sess.declareExchange(new AMQShortString("test.direct"),
+
+ sess.declareExchange(new AMQShortString("test.direct"),
ExchangeDefaults.DIRECT_EXCHANGE_CLASS, false);
- sess.declareExchange(new AMQShortString("tmp.direct"),
+ sess.declareExchange(new AMQShortString("tmp.direct"),
ExchangeDefaults.DIRECT_EXCHANGE_CLASS, false);
- sess.declareExchange(new AMQShortString("tmp.topic"),
+ sess.declareExchange(new AMQShortString("tmp.topic"),
ExchangeDefaults.TOPIC_EXCHANGE_CLASS, false);
- sess.declareExchange(new AMQShortString("test.topic"),
+ sess.declareExchange(new AMQShortString("test.topic"),
ExchangeDefaults.TOPIC_EXCHANGE_CLASS, false);
QueueSession queueSession = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
@@ -111,7 +113,7 @@ public class ConnectionTest extends QpidBrokerTestCase
queueSession.close();
TopicSession topicSession = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
-
+
AMQTopic topic = (AMQTopic) topicSession.createTopic("silly.topic");
assertEquals(topic.getExchangeName().toString(), "test.topic");
@@ -269,7 +271,7 @@ public class ConnectionTest extends QpidBrokerTestCase
}
connection.close();
}
-
+
public void testUnsupportedSASLMechanism() throws Exception
{
BrokerDetails broker = getBroker();
@@ -287,37 +289,11 @@ public class ConnectionTest extends QpidBrokerTestCase
{
assertTrue("Incorrect exception thrown",
e.getMessage().contains("The following SASL mechanisms " +
- "[MY_MECH]" +
+ "[MY_MECH]" +
" specified by the client are not supported by the broker"));
}
}
- public void testClientIDVerification() throws Exception
- {
- System.setProperty("qpid.verify_client_id", "true");
- BrokerDetails broker = getBroker();
- try
- {
- Connection con = new AMQConnection(broker.toString(), "guest", "guest",
- "client_id", "test");
-
- Connection con2 = new AMQConnection(broker.toString(), "guest", "guest",
- "client_id", "test");
-
- fail("The client should throw a ConnectionException stating the" +
- " client ID is not unique");
- }
- catch (Exception e)
- {
- assertTrue("Incorrect exception thrown",
- e.getMessage().contains("ClientID must be unique"));
- }
- finally
- {
- System.setProperty("qpid.verify_client_id", "false");
- }
- }
-
public static junit.framework.Test suite()
{
return new junit.framework.TestSuite(ConnectionTest.class);
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java
index 5701b5a1fd..278b9e9c04 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java
@@ -31,21 +31,21 @@ import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.client.protocol.AMQProtocolSession;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
-import org.apache.qpid.transport.TestNetworkConnection;
+import org.apache.qpid.transport.TestNetworkDriver;
public class AMQProtocolSessionTest extends QpidBrokerTestCase
{
- private static class TestProtocolSession extends AMQProtocolSession
+ private static class AMQProtSession extends AMQProtocolSession
{
- public TestProtocolSession(AMQProtocolHandler protocolHandler, AMQConnection connection)
+ public AMQProtSession(AMQProtocolHandler protocolHandler, AMQConnection connection)
{
super(protocolHandler,connection);
}
- public TestNetworkConnection getNetworkConnection()
+ public TestNetworkDriver getNetworkDriver()
{
- return (TestNetworkConnection) _protocolHandler.getNetworkConnection();
+ return (TestNetworkDriver) _protocolHandler.getNetworkDriver();
}
public AMQShortString genQueueName()
@@ -54,7 +54,7 @@ public class AMQProtocolSessionTest extends QpidBrokerTestCase
}
}
- private TestProtocolSession _testSession;
+ private AMQProtSession _testSession;
protected void setUp() throws Exception
{
@@ -62,10 +62,10 @@ public class AMQProtocolSessionTest extends QpidBrokerTestCase
AMQConnection con = (AMQConnection) getConnection("guest", "guest");
AMQProtocolHandler protocolHandler = new AMQProtocolHandler(con);
- protocolHandler.setNetworkConnection(new TestNetworkConnection());
-
+ protocolHandler.setNetworkDriver(new TestNetworkDriver());
+
//don't care about the values set here apart from the dummy IoSession
- _testSession = new TestProtocolSession(protocolHandler , con);
+ _testSession = new AMQProtSession(protocolHandler , con);
}
public void testTemporaryQueueWildcard() throws UnknownHostException
@@ -93,9 +93,14 @@ public class AMQProtocolSessionTest extends QpidBrokerTestCase
checkTempQueueName(new InetSocketAddress(InetAddress.getByName("1080:0:0:0:8:800:200C:417A"), 1234), "tmp_1080_0_0_0_8_800_200c_417a_1234_1");
}
+ public void testTemporaryQueuePipe() throws UnknownHostException
+ {
+ checkTempQueueName(new VmPipeAddress(1), "tmp_vm_1_1");
+ }
+
private void checkTempQueueName(SocketAddress address, String queueName)
{
- _testSession.getNetworkConnection().setLocalAddress(address);
+ _testSession.getNetworkDriver().setLocalAddress(address);
assertEquals("Wrong queue name", queueName, _testSession.genQueueName().asString());
}
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java
index f5e0ed75d2..de092fc893 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java
@@ -50,6 +50,7 @@ public class MessageRequeueTest extends QpidBrokerTestCase
protected final String queue = "direct://amq.direct//message-requeue-test-queue";
protected String payload = "Message:";
+ //protected final String BROKER = "vm://:1";
protected final String BROKER = "tcp://127.0.0.1:5672";
private boolean testReception = true;
@@ -154,8 +155,8 @@ public class MessageRequeueTest extends QpidBrokerTestCase
_logger.info("consumed: " + messagesReceived);
assertEquals("number of consumed messages does not match initial data", (int) numTestMessages, messagesReceived);
- // with 0_10 we can have a delivery tag of 0
- if (!conn.isBroker010())
+ // wit 0_10 we can have a delivery tag of 0
+ if (conn.isBroker08())
{
for (long b : messageLog)
{
@@ -223,7 +224,7 @@ public class MessageRequeueTest extends QpidBrokerTestCase
StringBuilder list = new StringBuilder();
list.append("Failed to receive:");
int failed = 0;
- if (!conn.isBroker010())
+ if (conn.isBroker08())
{
for (long b : receieved)
{
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ct/DurableSubscriberTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ct/DurableSubscriberTest.java
index 80422cf3e9..989ac98747 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ct/DurableSubscriberTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ct/DurableSubscriberTest.java
@@ -52,7 +52,7 @@ public class DurableSubscriberTest extends QpidBrokerTestCase
*/
public void testDurSubRestoredAfterNonPersistentMessageSent() throws Exception
{
- if (isBrokerStorePersistent())
+ if (isBrokerStorePersistent() || !isBroker08())
{
TopicConnectionFactory factory = getConnectionFactory();
Topic topic = (Topic) getInitialContext().lookup(_topicName);
@@ -116,7 +116,7 @@ public class DurableSubscriberTest extends QpidBrokerTestCase
*/
public void testDurSubRestoresMessageSelector() throws Exception
{
- if (isBrokerStorePersistent())
+ if (isBrokerStorePersistent() || !isBroker08())
{
TopicConnectionFactory factory = getConnectionFactory();
Topic topic = (Topic) getInitialContext().lookup(_topicName);
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java
index 97452ad1c8..830421a01f 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java
@@ -25,14 +25,12 @@ import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQQueue;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.message.NonQpidObjectMessage;
-import org.apache.qpid.client.message.QpidMessageProperties;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageConsumer;
@@ -41,11 +39,7 @@ import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.Session;
-import javax.jms.Topic;
-
import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
/**
* @author Apache Software Foundation
@@ -169,39 +163,4 @@ public class JMSPropertiesTest extends QpidBrokerTestCase
con.close();
}
- /**
- * Test Goal : Test if custom message properties can be set and retrieved properly with out an error.
- * Also test if unsupported properties are filtered out. See QPID-2930.
- */
- public void testQpidExtensionProperties() throws Exception
- {
- Connection con = getConnection("guest", "guest");
- Session ssn = (AMQSession) con.createSession(false, Session.CLIENT_ACKNOWLEDGE);
- con.start();
-
- Topic topic = ssn.createTopic("test");
- MessageConsumer consumer = ssn.createConsumer(topic);
- MessageProducer prod = ssn.createProducer(topic);
- Message m = ssn.createMessage();
- m.setObjectProperty("foo-bar", "foobar".getBytes());
- m.setObjectProperty(QpidMessageProperties.AMQP_0_10_APP_ID, "my-app-id");
- prod.send(m);
-
- Message msg = consumer.receive(1000);
- assertNotNull(msg);
-
- Enumeration<String> enu = msg.getPropertyNames();
- Map<String,String> map = new HashMap<String,String>();
- while (enu.hasMoreElements())
- {
- String name = enu.nextElement();
- String value = msg.getStringProperty(name);
- map.put(name, value);
- }
-
- assertFalse("Property 'foo-bar' should have been filtered out",map.containsKey("foo-bar"));
- assertEquals("Property "+ QpidMessageProperties.AMQP_0_10_APP_ID + " should be present","my-app-id",msg.getStringProperty(QpidMessageProperties.AMQP_0_10_APP_ID));
- assertEquals("Property "+ QpidMessageProperties.AMQP_0_10_ROUTING_KEY + " should be present","test",msg.getStringProperty(QpidMessageProperties.AMQP_0_10_ROUTING_KEY));
-
- }
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutConfigurationTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutConfigurationTest.java
deleted file mode 100644
index 36bac3b715..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutConfigurationTest.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.test.unit.transacted;
-
-/**
- * This verifies that changing the {@code transactionTimeout} configuration will alter
- * the behaviour of the transaction open and idle logging, and that when the connection
- * will be closed.
- */
-public class TransactionTimeoutConfigurationTest extends TransactionTimeoutTestCase
-{
- @Override
- protected void configure() throws Exception
- {
- // Setup housekeeping every second
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.expiredMessageCheckPeriod", "100");
-
- // Set transaction timout properties.
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "200");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "1000");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "100");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "500");
- }
-
- public void testProducerIdleCommit() throws Exception
- {
- try
- {
- send(5, 0);
-
- sleep(2.0f);
-
- _psession.commit();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- monitor(5, 0);
-
- check(IDLE);
- }
-
- public void testProducerOpenCommit() throws Exception
- {
- try
- {
- send(5, 0.3f);
-
- _psession.commit();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- monitor(6, 3);
-
- check(OPEN);
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java
deleted file mode 100644
index 71b89bf911..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java
+++ /dev/null
@@ -1,72 +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.transacted;
-
-/**
- * This verifies that the default behaviour is not to time out transactions.
- */
-public class TransactionTimeoutDisabledTest extends TransactionTimeoutTestCase
-{
- @Override
- protected void configure() throws Exception
- {
- // Setup housekeeping every second
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.expiredMessageCheckPeriod", "100");
- }
-
- public void testProducerIdleCommit() throws Exception
- {
- try
- {
- send(5, 0);
-
- sleep(2.0f);
-
- _psession.commit();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-
- public void testProducerOpenCommit() throws Exception
- {
- try
- {
- send(5, 0.3f);
-
- _psession.commit();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java
deleted file mode 100644
index c912d6a323..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java
+++ /dev/null
@@ -1,335 +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.transacted;
-
-/**
- * This tests the behaviour of transactional sessions when the {@code transactionTimeout} configuration
- * is set for a virtual host.
- *
- * A producer that is idle for too long or open for too long will have its connection closed and
- * any further operations will fail with a 408 resource timeout exception. Consumers will not
- * be affected by the transaction timeout configuration.
- */
-public class TransactionTimeoutTest extends TransactionTimeoutTestCase
-{
- public void testProducerIdle() throws Exception
- {
- try
- {
- sleep(2.0f);
-
- _psession.commit();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-
- public void testProducerIdleCommit() throws Exception
- {
- try
- {
- send(5, 0);
-
- sleep(2.0f);
-
- _psession.commit();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- monitor(5, 0);
-
- check(IDLE);
- }
-
- public void testProducerOpenCommit() throws Exception
- {
- try
- {
- send(6, 0.5f);
-
- _psession.commit();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- monitor(0, 10);
-
- check(OPEN);
- }
-
- public void testProducerIdleCommitTwice() throws Exception
- {
- try
- {
- send(5, 0);
-
- sleep(1.0f);
-
- _psession.commit();
-
- send(5, 0);
-
- sleep(2.0f);
-
- _psession.commit();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- monitor(10, 0);
-
- check(IDLE);
- }
-
- public void testProducerOpenCommitTwice() throws Exception
- {
- try
- {
- send(5, 0);
-
- sleep(1.0f);
-
- _psession.commit();
-
- send(6, 0.5f);
-
- _psession.commit();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- // the presistent store generates more idle messages?
- monitor(isBrokerStorePersistent() ? 10 : 5, 10);
-
- check(OPEN);
- }
-
- public void testProducerIdleRollback() throws Exception
- {
- try
- {
- send(5, 0);
-
- sleep(2.0f);
-
- _psession.rollback();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- monitor(5, 0);
-
- check(IDLE);
- }
-
- public void testProducerIdleRollbackTwice() throws Exception
- {
- try
- {
- send(5, 0);
-
- sleep(1.0f);
-
- _psession.rollback();
-
- send(5, 0);
-
- sleep(2.0f);
-
- _psession.rollback();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- monitor(10, 0);
-
- check(IDLE);
- }
-
- public void testConsumerCommitClose() throws Exception
- {
- try
- {
- send(1, 0);
-
- _psession.commit();
-
- expect(1, 0);
-
- _csession.commit();
-
- sleep(3.0f);
-
- _csession.close();
- }
- catch (Exception e)
- {
- fail("should have succeeded: " + e.getMessage());
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-
- public void testConsumerIdleReceiveCommit() throws Exception
- {
- try
- {
- send(1, 0);
-
- _psession.commit();
-
- sleep(2.0f);
-
- expect(1, 0);
-
- sleep(2.0f);
-
- _csession.commit();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-
- public void testConsumerIdleCommit() throws Exception
- {
- try
- {
- send(1, 0);
-
- _psession.commit();
-
- expect(1, 0);
-
- sleep(2.0f);
-
- _csession.commit();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-
- public void testConsumerIdleRollback() throws Exception
- {
- try
- {
- send(1, 0);
-
- _psession.commit();
-
- expect(1, 0);
-
- sleep(2.0f);
-
- _csession.rollback();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-
- public void testConsumerOpenCommit() throws Exception
- {
- try
- {
- send(1, 0);
-
- _psession.commit();
-
- sleep(3.0f);
-
- _csession.commit();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-
- public void testConsumerOpenRollback() throws Exception
- {
- try
- {
- send(1, 0);
-
- _psession.commit();
-
- sleep(3.0f);
-
- _csession.rollback();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java
deleted file mode 100644
index 786fc2adb0..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java
+++ /dev/null
@@ -1,253 +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.transacted;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.jms.DeliveryMode;
-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.TextMessage;
-
-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.framing.AMQShortString;
-import org.apache.qpid.jms.ConnectionURL;
-import org.apache.qpid.jms.Session;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-import org.apache.qpid.util.LogMonitor;
-
-/**
- * The {@link TestCase} for transaction timeout testing.
- */
-public class TransactionTimeoutTestCase extends QpidBrokerTestCase implements ExceptionListener
-{
- public static final String VIRTUALHOST = "test";
- public static final String TEXT = "0123456789abcdefghiforgettherest";
- public static final String CHN_OPEN_TXN = "CHN-1007";
- public static final String CHN_IDLE_TXN = "CHN-1008";
- public static final String IDLE = "Idle";
- public static final String OPEN = "Open";
-
- protected LogMonitor _monitor;
- protected AMQConnection _con;
- protected Session _psession, _csession;
- protected Queue _queue;
- protected MessageConsumer _consumer;
- protected MessageProducer _producer;
- protected CountDownLatch _caught = new CountDownLatch(1);
- protected String _message;
- protected Exception _exception;
- protected AMQConstant _code;
-
- protected void configure() throws Exception
- {
- // Setup housekeeping every second
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.expiredMessageCheckPeriod", "100");
-
- /*
- * Set transaction timout properties. The XML in the virtualhosts configuration is as follows:
- *
- * <transactionTimeout>
- * <openWarn>1000</openWarn>
- * <openClose>2000</openClose>
- * <idleWarn>500</idleWarn>
- * <idleClose>1500</idleClose>
- * </transactionTimeout>
- */
- 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");
- }
-
- protected void setUp() throws Exception
- {
- // Configure timeouts
- configure();
-
- // Monitor log file
- _monitor = new LogMonitor(_outputFile);
-
- // Start broker
- 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);
- _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);
- qsession.close();
-
- // Create producer and consumer
- producer();
- consumer();
- }
-
- protected void tearDown() throws Exception
- {
- try
- {
- _con.close();
- }
- finally
- {
- super.tearDown();
- }
- }
-
- /**
- * Create a transacted persistent message producer session.
- */
- protected void producer() throws Exception
- {
- _psession = _con.createSession(true, Session.SESSION_TRANSACTED);
- _producer = _psession.createProducer(_queue);
- _producer.setDeliveryMode(DeliveryMode.PERSISTENT);
- }
-
- /**
- * Create a transacted message consumer session.
- */
- protected void consumer() throws Exception
- {
- _csession = _con.createSession(true, Session.SESSION_TRANSACTED);
- _consumer = _csession.createConsumer(_queue);
- }
-
- /**
- * Send a number of messages to the queue, optionally pausing after each.
- */
- protected void send(int count, float delay) throws Exception
- {
- for (int i = 0; i < count; i++)
- {
- sleep(delay);
- Message msg = _psession.createTextMessage(TEXT);
- msg.setIntProperty("i", i);
- _producer.send(msg);
- }
- }
-
- /**
- * Sleep for a number of seconds.
- */
- protected void sleep(float seconds) throws Exception
- {
- try
- {
- Thread.sleep((long) (seconds * 1000.0f));
- }
- catch (InterruptedException ie)
- {
- throw new RuntimeException("Interrupted");
- }
- }
-
- /**
- * Check for idle and open messages.
- *
- * Either exactly zero messages, or +-2 error accepted around the specified number.
- */
- protected void monitor(int idle, int open) throws Exception
- {
- List<String> idleMsgs = _monitor.findMatches(CHN_IDLE_TXN);
- List<String> openMsgs = _monitor.findMatches(CHN_OPEN_TXN);
-
- String idleErr = "Expected " + idle + " but found " + idleMsgs.size() + " txn idle messages";
- String openErr = "Expected " + open + " but found " + openMsgs.size() + " txn open messages";
-
- if (idle == 0)
- {
- assertTrue(idleErr, idleMsgs.isEmpty());
- }
- else
- {
- assertTrue(idleErr, idleMsgs.size() >= idle - 2 && idleMsgs.size() <= idle + 2);
- }
-
- if (open == 0)
- {
- assertTrue(openErr, openMsgs.isEmpty());
- }
- else
- {
- assertTrue(openErr, openMsgs.size() >= open - 2 && openMsgs.size() <= open + 2);
- }
- }
-
- /**
- * Receive a number of messages, optionally pausing after each.
- */
- protected void expect(int count, float delay) throws Exception
- {
- for (int i = 0; i < count; i++)
- {
- sleep(delay);
- Message msg = _consumer.receive(1000);
- assertNotNull("Message should not be null", msg);
- assertTrue("Message should be a text message", msg instanceof TextMessage);
- assertEquals("Message content does not match expected", TEXT, ((TextMessage) msg).getText());
- assertEquals("Message order is incorrect", i, msg.getIntProperty("i"));
- }
- }
-
- /**
- * Checks that the correct exception was thrown and was received
- * by the listener with a 506 error code.
- */
- protected void check(String reason)throws InterruptedException
- {
- assertTrue("Should have caught exception in listener", _caught.await(1, TimeUnit.SECONDS));
- assertNotNull("Should have thrown exception to client", _exception);
- assertTrue("Exception message should contain '" + reason + "': " + _message, _message.contains(reason + " transaction timed out"));
- assertNotNull("Exception should have an error code", _code);
- assertEquals("Error code should be 506", AMQConstant.RESOURCE_ERROR, _code);
- }
-
- /** @see javax.jms.ExceptionListener#onException(javax.jms.JMSException) */
- public void onException(JMSException jmse)
- {
- _caught.countDown();
- _message = jmse.getLinkedException().getMessage();
- if (jmse.getLinkedException() instanceof AMQException)
- {
- _code = ((AMQException) jmse.getLinkedException()).getErrorCode();
- }
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java
index 10217585c1..d3b429e315 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java
@@ -34,10 +34,24 @@ public class FailoverBaseCase extends QpidBrokerTestCase
{
protected static final Logger _logger = LoggerFactory.getLogger(FailoverBaseCase.class);
+ public static int FAILING_VM_PORT = 2;
+ public static int FAILING_PORT = Integer.parseInt(System.getProperty("test.port.alt"));
public static final long DEFAULT_FAILOVER_TIME = 10000L;
protected int failingPort;
+ protected int getFailingPort()
+ {
+ if (_broker.equals(VM))
+ {
+ return FAILING_VM_PORT;
+ }
+ else
+ {
+ return FAILING_PORT;
+ }
+ }
+
protected void setUp() throws java.lang.Exception
{
super.setUp();
@@ -68,14 +82,6 @@ public class FailoverBaseCase extends QpidBrokerTestCase
return _connectionFactory;
}
- @Override
- public void stopBroker(int port) throws Exception
- {
- if (isBrokerPresent(port))
- {
- super.stopBroker(port);
- }
- }
public void tearDown() throws Exception
{
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java
index 1fde6c7c73..ff80c91fac 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java
@@ -21,8 +21,6 @@
package org.apache.qpid.test.utils;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Set;
import javax.management.JMException;
@@ -33,17 +31,14 @@ import javax.management.ObjectName;
import javax.management.MalformedObjectNameException;
import javax.management.remote.JMXConnector;
-import junit.framework.TestCase;
-
import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.commands.objects.AllObjects;
import org.apache.qpid.management.common.JMXConnnectionFactory;
import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
import org.apache.qpid.management.common.mbeans.ManagedExchange;
import org.apache.qpid.management.common.mbeans.LoggingManagement;
import org.apache.qpid.management.common.mbeans.ConfigurationManagement;
import org.apache.qpid.management.common.mbeans.ManagedQueue;
-import org.apache.qpid.management.common.mbeans.ServerInformation;
import org.apache.qpid.management.common.mbeans.UserManagement;
/**
@@ -236,10 +231,10 @@ public class JMXTestUtils
public ObjectName getVirtualHostManagerObjectName(String vhostName)
{
// Get the name of the test manager
- String query = "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost="
- + ObjectName.quote(vhostName) + ",*";
+ AllObjects allObject = new AllObjects(_mbsc);
+ allObject.querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=" + vhostName + ",*";
- Set<ObjectName> objectNames = queryObjects(query);
+ Set<ObjectName> objectNames = allObject.returnObjects();
_test.assertNotNull("Null ObjectName Set returned", objectNames);
_test.assertEquals("Incorrect number test vhosts returned", 1, objectNames.size());
@@ -263,14 +258,14 @@ 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) + ",*";
+ AllObjects allObject = new AllObjects(_mbsc);
+ allObject.querystring = "org.apache.qpid:type=VirtualHost.Queue,VirtualHost=" + virtualHostName + ",name=" + queue + ",*";
- Set<ObjectName> objectNames = queryObjects(query);
+ Set<ObjectName> objectNames = allObject.returnObjects();
_test.assertNotNull("Null ObjectName Set returned", objectNames);
- _test.assertEquals("Incorrect number of queues with name '" + queue + "' returned", 1, objectNames.size());
+ _test.assertEquals("Incorrect number of queues with name '" + allObject.querystring +
+ "' returned", 1, objectNames.size());
// We have verified we have only one value in objectNames so return it
ObjectName objectName = objectNames.iterator().next();
@@ -291,11 +286,10 @@ public class JMXTestUtils
public ObjectName getExchangeObjectName(String virtualHostName, String exchange)
{
// Get the name of the test manager
- String query = "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost="
- + ObjectName.quote(virtualHostName) + ",name="
- + ObjectName.quote(exchange) + ",*";
+ AllObjects allObject = new AllObjects(_mbsc);
+ allObject.querystring = "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=" + virtualHostName + ",name=" + exchange + ",*";
- Set<ObjectName> objectNames = queryObjects(query);
+ Set<ObjectName> objectNames = allObject.returnObjects();
_test.assertNotNull("Null ObjectName Set returned", objectNames);
_test.assertEquals("Incorrect number of exchange with name '" + exchange + "' returned", 1, objectNames.size());
@@ -307,9 +301,12 @@ public class JMXTestUtils
}
@SuppressWarnings("static-access")
- public <T> T getManagedObject(Class<T> managedClass, String query)
+ public <T> T getManagedObject(Class<T> managedClass, String queryString)
{
- Set<ObjectName> objectNames = queryObjects(query);
+ AllObjects allObject = new AllObjects(_mbsc);
+ allObject.querystring = queryString;
+
+ Set<ObjectName> objectNames = allObject.returnObjects();
_test.assertNotNull("Null ObjectName Set returned", objectNames);
_test.assertEquals("More than one " + managedClass + " returned", 1, objectNames.size());
@@ -324,16 +321,6 @@ public class JMXTestUtils
return MBeanServerInvocationHandler.newProxyInstance(_mbsc, objectName, managedClass, false);
}
- public <T> List<T> getManagedObjectList(Class<T> managedClass, Set<ObjectName> objectNames)
- {
- List<T> objects = new ArrayList<T>();
- for (ObjectName name : objectNames)
- {
- objects.add(getManagedObject(managedClass, name));
- }
- return objects;
- }
-
public ManagedBroker getManagedBroker(String virtualHost)
{
return getManagedObject(ManagedBroker.class, getVirtualHostManagerObjectName(virtualHost));
@@ -368,68 +355,4 @@ public class JMXTestUtils
ObjectName objectName = new ObjectName("org.apache.qpid:type=UserManagement,name=UserManagement");
return getManagedObject(UserManagement.class, objectName);
}
-
- /**
- * Retrive {@link ServerInformation} JMX MBean.
- */
- public ServerInformation getServerInformation()
- {
- // Get the name of the test manager
- String query = "org.apache.qpid:type=ServerInformation,name=ServerInformation,*";
-
- Set<ObjectName> objectNames = queryObjects(query);
-
- TestCase.assertNotNull("Null ObjectName Set returned", objectNames);
- TestCase.assertEquals("Incorrect number of objects returned", 1, objectNames.size());
-
- // We have verified we have only one value in objectNames so return it
- return getManagedObject(ServerInformation.class, objectNames.iterator().next());
- }
-
- /**
- * Retrive all {@link ManagedConnection} objects.
- */
- public List<ManagedConnection> getAllManagedConnections()
- {
- // Get the name of the test manager
- String query = "org.apache.qpid:type=VirtualHost.Connection,VirtualHost=*,name=*";
-
- Set<ObjectName> objectNames = queryObjects(query);
-
- TestCase.assertNotNull("Null ObjectName Set returned", objectNames);
-
- return getManagedObjectList(ManagedConnection.class, objectNames);
- }
-
- /**
- * Retrive all {@link ManagedConnection} objects for a particular virtual host.
- */
- public List<ManagedConnection> getManagedConnections(String vhost)
- {
- // Get the name of the test manager
- String query = "org.apache.qpid:type=VirtualHost.Connection,VirtualHost=" + ObjectName.quote(vhost) + ",name=*";
-
- Set<ObjectName> objectNames = queryObjects(query);
-
- TestCase.assertNotNull("Null ObjectName Set returned", objectNames);
-
- return getManagedObjectList(ManagedConnection.class, objectNames);
- }
-
- /**
- * Returns the Set of ObjectNames returned by the broker for the given query,
- * or null if there is problem while performing the query.
- */
- private Set<ObjectName> queryObjects(String query)
- {
- try
- {
- return _mbsc.queryNames(new ObjectName(query), null);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- return null;
- }
- }
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java
index c8ccdf91bb..ae38a75e7a 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java
@@ -25,7 +25,6 @@ import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.PrintStream;
import java.net.MalformedURLException;
-import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -55,20 +54,19 @@ import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
+import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQConnectionFactory;
import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.transport.TransportConnection;
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.configuration.ServerConfiguration;
-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.store.DerbyMessageStore;
import org.apache.qpid.url.URLSyntaxException;
-import org.apache.qpid.util.FileUtils;
import org.apache.qpid.util.LogMonitor;
/**
@@ -76,13 +74,6 @@ import org.apache.qpid.util.LogMonitor;
*/
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 */,
- SPAWNED /** Test case spawns a new broker as a separate process */
- }
protected final String QpidHome = System.getProperty("QPID_HOME");
protected File _configFile = new File(System.getProperty("broker.config"));
@@ -91,6 +82,7 @@ public class QpidBrokerTestCase extends QpidTestCase
protected long RECEIVE_TIMEOUT = 1000l;
+ private Map<String, String> _propertiesSetForTestOnly = new HashMap<String, String>();
private Map<String, String> _propertiesSetForBroker = new HashMap<String, String>();
private Map<Logger, Level> _loggerLevelSetForTest = new HashMap<Logger, Level>();
@@ -114,11 +106,9 @@ public class QpidBrokerTestCase extends QpidTestCase
// system properties
private static final String BROKER_LANGUAGE = "broker.language";
- private static final String BROKER_TYPE = "broker.type";
- private static final String BROKER_COMMAND = "broker.command";
+ private static final String BROKER = "broker";
private static final String BROKER_CLEAN = "broker.clean";
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";
@@ -126,30 +116,29 @@ 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";
- private static final String BROKER_PROTOCOL_EXCLUDES = "broker.protocol.excludes";
-
// values
protected static final String JAVA = "java";
protected static final String CPP = "cpp";
+ protected static final String VM = "vm";
+ protected static final String EXTERNAL = "external";
+ private static final String VERSION_08 = "0-8";
+ private static final String VERSION_010 = "0-10";
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 FAILING_PORT = Integer.parseInt(System.getProperty("test.port.alt"));
public static final int DEFAULT_MANAGEMENT_PORT = Integer.getInteger("test.mport", ServerConfiguration.DEFAULT_JMXPORT);
public static final int DEFAULT_SSL_PORT = Integer.getInteger("test.sslport", ServerConfiguration.DEFAULT_SSL_PORT);
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 String _broker = System.getProperty(BROKER, VM);
private String _brokerClean = System.getProperty(BROKER_CLEAN, null);
private Boolean _brokerCleanBetweenTests = Boolean.getBoolean(BROKER_CLEAN_BETWEEN_TESTS);
- private final AmqpProtocolVersion _brokerVersion = AmqpProtocolVersion.valueOf(System.getProperty(BROKER_VERSION, ""));
+ private String _brokerVersion = System.getProperty(BROKER_VERSION, VERSION_08);
protected String _output = System.getProperty(TEST_OUTPUT);
protected Boolean _brokerPersistent = Boolean.getBoolean(BROKER_PERSITENT);
- private String _brokerProtocolExcludes = System.getProperty(BROKER_PROTOCOL_EXCLUDES);
protected static String _brokerLogPrefix = System.getProperty(BROKER_LOG_PREFIX,"BROKER: ");
protected static boolean _interleaveBrokerLog = Boolean.getBoolean(BROKER_LOG_INTERLEAVE);
@@ -158,7 +147,7 @@ public class QpidBrokerTestCase extends QpidTestCase
protected PrintStream _brokerOutputStream;
- protected Map<Integer, BrokerHolder> _brokers = new HashMap<Integer, BrokerHolder>();
+ protected Map<Integer, Process> _brokers = new HashMap<Integer, Process>();
protected InitialContext _initialContext;
protected AMQConnectionFactory _connectionFactory;
@@ -294,16 +283,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(""))
- {
- cleanBroker();
-
- File existing = new File(existingQpidWorkPath);
- File qpidWork = new File(getQpidWork(_brokerType, getPort()));
- FileUtils.copyRecursive(existing, qpidWork);
- }
-
startBroker();
}
@@ -404,8 +383,13 @@ public class QpidBrokerTestCase extends QpidTestCase
}
}
+ public void startBroker() throws Exception
+ {
+ startBroker(0);
+ }
+
/**
- * Return the management port in use by the broker on this main port
+ * Return the management portin use by the broker on this main port
*
* @param mainPort the broker's main port.
*
@@ -413,7 +397,7 @@ public class QpidBrokerTestCase extends QpidTestCase
*/
protected int getManagementPort(int mainPort)
{
- return mainPort + (DEFAULT_MANAGEMENT_PORT - DEFAULT_PORT);
+ return mainPort + (DEFAULT_MANAGEMENT_PORT - (_broker.equals(VM) ? DEFAULT_VM_PORT : DEFAULT_PORT));
}
/**
@@ -428,7 +412,11 @@ public class QpidBrokerTestCase extends QpidTestCase
protected int getPort(int port)
{
- if (!_brokerType.equals(BrokerType.EXTERNAL))
+ if (_broker.equals(VM))
+ {
+ return port == 0 ? DEFAULT_VM_PORT : port;
+ }
+ else if (!_broker.equals(EXTERNAL))
{
return port == 0 ? DEFAULT_PORT : port;
}
@@ -440,18 +428,11 @@ public class QpidBrokerTestCase extends QpidTestCase
protected String getBrokerCommand(int port) throws MalformedURLException
{
- final String protocolExcludesList = _brokerProtocolExcludes.replace("@PORT", "" + port);
- return _brokerCommand
+ return _broker
.replace("@PORT", "" + port)
.replace("@SSL_PORT", "" + (port - 1))
.replace("@MPORT", "" + getManagementPort(port))
- .replace("@CONFIG_FILE", _configFile.toString())
- .replace("@EXCLUDES", protocolExcludesList);
- }
-
- public void startBroker() throws Exception
- {
- startBroker(0);
+ .replace("@CONFIG_FILE", _configFile.toString());
}
public void startBroker(int port) throws Exception
@@ -462,38 +443,38 @@ public class QpidBrokerTestCase extends QpidTestCase
saveTestConfiguration();
saveTestVirtualhosts();
- if(_brokers.get(port) != null)
- {
- throw new IllegalStateException("There is already an existing broker running on port " + port);
- }
-
- if (_brokerType.equals(BrokerType.INTERNAL) && !existingInternalBroker())
+ Process process = null;
+ if (_broker.equals(VM))
{
+ setConfigurationProperty("management.jmxport", String.valueOf(getManagementPort(port)));
setConfigurationProperty(ServerConfiguration.MGMT_CUSTOM_REGISTRY_SOCKET, String.valueOf(false));
saveTestConfiguration();
-
- BrokerOptions options = new BrokerOptions();
- options.setConfigFile(_configFile.getAbsolutePath());
- options.addPort(port);
-
- addExcludedPorts(port, options);
-
- options.setJmxPort(getManagementPort(port));
-
- //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(new URL(System.getProperty("log4j.configuration")).getFile());
-
- Broker broker = new Broker();
- _logger.info("starting internal broker (same JVM)");
- broker.startup(options);
-
- _brokers.put(port, new InternalBrokerHolder(broker));
+
+ // create an in_VM broker
+ final ConfigurationFileApplicationRegistry registry = new ConfigurationFileApplicationRegistry(_configFile);
+ try
+ {
+ ApplicationRegistry.initialise(registry, port);
+ }
+ catch (Exception e)
+ {
+ _logger.error("Broker initialise failed due to:",e);
+ try
+ {
+ registry.close();
+ }
+ catch (Throwable closeE)
+ {
+ closeE.printStackTrace();
+ }
+ throw e;
+ }
+ TransportConnection.createVMBroker(port);
}
- else if (!_brokerType.equals(BrokerType.EXTERNAL))
+ else if (!_broker.equals(EXTERNAL))
{
String cmd = getBrokerCommand(port);
- _logger.info("starting external broker: " + cmd);
+ _logger.info("starting broker: " + cmd);
ProcessBuilder pb = new ProcessBuilder(cmd.split("\\s+"));
pb.redirectErrorStream(true);
@@ -509,7 +490,7 @@ public class QpidBrokerTestCase extends QpidTestCase
// DON'T change PNAME, qpid.stop needs this value.
env.put("QPID_PNAME", "-DPNAME=QPBRKR -DTNAME=\"" + _testName + "\"");
// Add the port to QPID_WORK to ensure unique working dirs for multi broker tests
- env.put("QPID_WORK", getQpidWork(_brokerType, port));
+ env.put("QPID_WORK", System.getProperty("QPID_WORK")+ "/" + port);
// Use the environment variable to set amqj.logging.level for the broker
@@ -561,7 +542,8 @@ public class QpidBrokerTestCase extends QpidTestCase
env.put("QPID_OPTS", QPID_OPTS);
}
}
- Process process = pb.start();;
+
+ process = pb.start();
Piper p = new Piper(process.getInputStream(),
_brokerOutputStream,
@@ -582,7 +564,6 @@ public class QpidBrokerTestCase extends QpidTestCase
try
{
- //test that the broker is still running and hasn't exited unexpectedly
int exit = process.exitValue();
_logger.info("broker aborted: " + exit);
cleanBroker();
@@ -590,58 +571,11 @@ public class QpidBrokerTestCase extends QpidTestCase
}
catch (IllegalThreadStateException e)
{
- // this is expect if the broker started successfully
+ // this is expect if the broker started succesfully
}
-
- _brokers.put(port, new SpawnedBrokerHolder(process));
}
- }
- private void addExcludedPorts(int port, BrokerOptions options)
- {
- final String protocolExcludesList = _brokerProtocolExcludes.replace("@PORT", "" + port);
-
- 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);
- }
- }
-
- private boolean existingInternalBroker()
- {
- for(BrokerHolder holder : _brokers.values())
- {
- if(holder instanceof InternalBrokerHolder)
- {
- return true;
- }
- }
-
- return false;
- }
-
- private String getQpidWork(BrokerType broker, int port)
- {
- if (!broker.equals(BrokerType.EXTERNAL))
- {
- return System.getProperty("QPID_WORK")+ "/" + port;
- }
-
- return System.getProperty("QPID_WORK");
+ _brokers.put(port, process);
}
public String getTestConfigFile()
@@ -722,17 +656,20 @@ public class QpidBrokerTestCase extends QpidTestCase
port = getPort(port);
_logger.info("stopping broker: " + getBrokerCommand(port));
- BrokerHolder broker = _brokers.remove(port);
- broker.shutdown();
+ Process process = _brokers.remove(port);
+ if (process != null)
+ {
+ process.destroy();
+ process.waitFor();
+ _logger.info("broker exited: " + process.exitValue());
+ }
+ else if (_broker.equals(VM))
+ {
+ TransportConnection.killVMBroker(port);
+ ApplicationRegistry.remove(port);
+ }
}
- public boolean isBrokerPresent(int port) throws Exception
- {
- port = getPort(port);
-
- return _brokers.containsKey(port);
- }
-
/**
* Attempt to set the Java Broker to use the BDBMessageStore for persistence
* Falling back to the DerbyMessageStore if
@@ -874,14 +811,20 @@ public class QpidBrokerTestCase extends QpidTestCase
}
/**
- * Set a System property for the client (and broker if using the same vm) of this test.
+ * Set a System (-D) property for the external Broker of this test.
*
* @param property The property to set
* @param value the value to set it to.
*/
protected void setTestClientSystemProperty(String property, String value)
{
- setTestSystemProperty(property, value);
+ if (!_propertiesSetForTestOnly.containsKey(property))
+ {
+ // Record the current value so we can revert it later.
+ _propertiesSetForTestOnly.put(property, System.getProperty(property));
+ }
+
+ System.setProperty(property, value);
}
/**
@@ -889,7 +832,20 @@ public class QpidBrokerTestCase extends QpidTestCase
*/
protected void revertSystemProperties()
{
- revertTestSystemProperties();
+ for (String key : _propertiesSetForTestOnly.keySet())
+ {
+ String value = _propertiesSetForTestOnly.get(key);
+ if (value != null)
+ {
+ System.setProperty(key, value);
+ }
+ else
+ {
+ System.clearProperty(key);
+ }
+ }
+
+ _propertiesSetForTestOnly.clear();
// We don't change the current VMs settings for Broker only properties
// so we can just clear this map
@@ -948,17 +904,17 @@ public class QpidBrokerTestCase extends QpidTestCase
*/
public boolean isBroker08()
{
- return _brokerVersion.equals(AmqpProtocolVersion.v0_8);
+ return _brokerVersion.equals(VERSION_08);
}
public boolean isBroker010()
{
- return _brokerVersion.equals(AmqpProtocolVersion.v0_10);
+ return _brokerVersion.equals(VERSION_010);
}
protected boolean isJavaBroker()
{
- return _brokerLanguage.equals("java") || _brokerType.equals("vm");
+ return _brokerLanguage.equals("java") || _broker.equals("vm");
}
protected boolean isCppBroker()
@@ -968,14 +924,9 @@ public class QpidBrokerTestCase extends QpidTestCase
protected boolean isExternalBroker()
{
- return !_brokerType.equals("vm"); //TODO
+ return !_broker.equals("vm");
}
-
- protected boolean isInternalBroker()
- {
- return _brokerType.equals(BrokerType.INTERNAL);
- }
-
+
protected boolean isBrokerStorePersistent()
{
return _brokerPersistent;
@@ -1047,6 +998,11 @@ public class QpidBrokerTestCase extends QpidTestCase
*/
public AMQConnectionFactory getConnectionFactory(String factoryName) throws NamingException
{
+ if (_broker.equals(VM))
+ {
+ factoryName += ".vm";
+ }
+
return (AMQConnectionFactory) getInitialContext().lookup(factoryName);
}
@@ -1087,7 +1043,15 @@ public class QpidBrokerTestCase extends QpidTestCase
public Connection getClientConnection(String username, String password, String id) throws JMSException, URLSyntaxException, AMQException, NamingException
{
_logger.info("get Connection");
- Connection con = getConnectionFactory().createConnection(username, password, id);
+ Connection con;
+ if (_broker.equals(VM))
+ {
+ con = new AMQConnection("vm://:1", username, password, id, "test");
+ }
+ else
+ {
+ con = getConnectionFactory().createConnection(username, password, id);
+ }
//add the connection in the lis of connections
_connections.add(con);
return con;
@@ -1125,8 +1089,7 @@ public class QpidBrokerTestCase extends QpidTestCase
c.close();
}
}
- finally
- {
+ finally{
// Ensure any problems with close does not interfer with property resets
revertSystemProperties();
revertLoggingLevels();
@@ -1227,8 +1190,7 @@ public class QpidBrokerTestCase extends QpidTestCase
MessageProducer producer = session.createProducer(destination);
- int i = offset;
- for (; i < (count + offset); i++)
+ for (int i = offset; i < (count + offset); i++)
{
Message next = createNextMessage(session, i);
@@ -1251,7 +1213,7 @@ public class QpidBrokerTestCase extends QpidTestCase
// we have no batchSize or
// our count is not divible by batchSize.
if (session.getTransacted() &&
- ( batchSize == 0 || (i-1) % batchSize != 0))
+ ( batchSize == 0 || count % batchSize != 0))
{
session.commit();
}
@@ -1346,26 +1308,29 @@ public class QpidBrokerTestCase extends QpidTestCase
*/
public void reloadBrokerSecurityConfig() throws Exception
{
- JMXTestUtils jmxu = new JMXTestUtils(this, "admin" , "admin");
- jmxu.open();
-
- try
+ if (_broker.equals(VM))
{
- ConfigurationManagement configMBean = jmxu.getConfigurationManagement();
- configMBean.reloadSecurityConfiguration();
+ ApplicationRegistry.getInstance().getConfiguration().reparseConfigFileSecuritySections();
}
- finally
+ else
{
- 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));
- }
+ JMXTestUtils jmxu = new JMXTestUtils(this, "admin" , "admin");
+ 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;
+ }
}
}
diff --git a/qpid/java/test-profiles/JavaPre010Excludes b/qpid/java/test-profiles/08StandaloneExcludes
index 5d0c82c5d7..b482a14c6d 100644
--- a/qpid/java/test-profiles/JavaPre010Excludes
+++ b/qpid/java/test-profiles/08StandaloneExcludes
@@ -18,10 +18,10 @@
//
//======================================================================
-//Exclude the following from brokers using the 0-8/0-9/0-9-1 protocols
+//Exclude the following from brokers defaulting to the 0-8 protocol
//======================================================================
-// This test requires a broker capable of 0-8/0-9/0-9-1 and 0-10 concurrently
+// This test requires a broker capable of 0-8/9 and 0-10
org.apache.qpid.test.client.message.JMSDestinationTest#testReceiveResend
// QPID-2478 test fails when run against broker using 0-8/9
@@ -31,12 +31,9 @@ org.apache.qpid.test.client.message.JMSDestinationTest#testGetDestinationWithCus
org.apache.qpid.test.client.destination.AddressBasedDestinationTest#*
org.apache.qpid.test.client.queue.QueuePolicyTest#testRingPolicy
org.apache.qpid.test.client.queue.QueuePolicyTest#testRejectPolicy
-org.apache.qpid.test.unit.message.JMSPropertiesTest#testApplicationProperties
// Those tests are written against the 0.10 path
org.apache.qpid.test.unit.message.UTF8Test#*
org.apache.qpid.client.MessageListenerTest#testSynchronousReceiveNoWait
org.apache.qpid.test.unit.client.connection.ConnectionTest#testUnsupportedSASLMechanism
-
-org.apache.qpid.test.unit.message.JMSPropertiesTest#testQpidExtensionProperties
diff --git a/qpid/java/test-profiles/CPPExcludes b/qpid/java/test-profiles/CPPExcludes
index 89cdd792de..e89b09cca2 100755
--- a/qpid/java/test-profiles/CPPExcludes
+++ b/qpid/java/test-profiles/CPPExcludes
@@ -17,9 +17,6 @@
// under the License.
//
-// QPID-3391: the C++ broker does not currently validate the exchange creation arguments
-org.apache.qpid.test.client.destination.AddressBasedDestinationTest#testCreateExchangeWithNonsenseArgs
-
org.apache.qpid.test.unit.client.channelclose.ChannelCloseTest#*
org.apache.qpid.client.ResetMessageListenerTest#*
@@ -168,14 +165,6 @@ org.apache.qpid.server.security.firewall.FirewallConfigTest#*
org.apache.qpid.server.security.firewall.FirewallConfigurationTest#*
org.apache.qpid.server.plugins.PluginTest#*
-// Transacion timeouts not implemented in CPP broker
-org.apache.qpid.test.unit.transacted.TransactionTimeoutDisabledTest#*
-org.apache.qpid.test.unit.transacted.TransactionTimeoutConfigurationTest#*
-org.apache.qpid.test.unit.transacted.TransactionTimeoutTest#*
-
// Java broker only
org.apache.qpid.server.logging.management.LoggingManagementMBeanTest#*
org.apache.qpid.server.management.AMQUserManagementMBeanTest#*
-
-// QPID-3133: On 0-10, the exception listener is currently not invoked when reconnection fails to occurs.
-org.apache.qpid.server.failover.FailoverMethodTest#*
diff --git a/qpid/java/test-profiles/Excludes b/qpid/java/test-profiles/Excludes
index 7e096d3ac8..ff6993fa0b 100644
--- a/qpid/java/test-profiles/Excludes
+++ b/qpid/java/test-profiles/Excludes
@@ -17,6 +17,7 @@
// under the License.
//
+org.apache.qpid.client.MultipleJCAProviderRegistrationTest#test
// QPID-1715, QPID-1715 : Client Error Handling on close is still broken
org.apache.qpid.server.queue.QueueCreateTest#testCreatePriorityString
org.apache.qpid.server.queue.QueueCreateTest#testCreateFlowToDiskValidNoSize
@@ -49,3 +50,4 @@ org.apache.qpid.test.unit.ack.AcknowledgeAfterFailoverTest#*
// QPID-2418 : The queue backing the dur sub is not currently deleted at subscription change, so the test will fail.
org.apache.qpid.test.unit.ct.DurableSubscriberTest#testResubscribeWithChangedSelectorAndRestart
+
diff --git a/qpid/java/test-profiles/Java010Excludes b/qpid/java/test-profiles/Java010Excludes
index f8210e2b06..3486d5c70c 100755
--- a/qpid/java/test-profiles/Java010Excludes
+++ b/qpid/java/test-profiles/Java010Excludes
@@ -47,7 +47,6 @@ org.apache.qpid.server.logging.SubscriptionLoggingTest#testSubscriptionSuspend
// 0-10 Broker does not have a JMX connection MBean
org.apache.qpid.management.jmx.ManagementActorLoggingTest#testConnectionCloseViaManagement
-org.apache.qpid.management.jmx.MessageConnectionStatisticsTest#*
// 0-10 has different ideas about clientid and ownership of queues
org.apache.qpid.server.queue.ModelTest#*
@@ -55,6 +54,9 @@ org.apache.qpid.server.queue.ModelTest#*
// 0-10 is not supported by the MethodRegistry
org.apache.qpid.test.unit.close.JavaServerCloseRaceConditionTest#*
+// QPID-2084 : this test needs more work for 0-10
+org.apache.qpid.test.unit.client.DynamicQueueExchangeCreateTest#*
+
//QPID-942 : Implemented Channel.Flow based Producer Side flow control to the Java Broker (not in CPP Broker)
org.apache.qpid.server.queue.ProducerFlowControlTest#*
@@ -72,16 +74,8 @@ org.apache.qpid.test.unit.publish.DirtyTransactedPublishTest#*
org.apache.qpid.test.client.RollbackOrderTest#testOrderingAfterRollbackOnMessage
org.apache.qpid.test.unit.ack.RecoverTest#testRecoverInAutoAckListener
-// This test uses 0-8 channel frames
-org.apache.qpid.test.unit.client.channelclose.ChannelCloseTest#*
-
//Temporarily adding the following until the issues are sorted out.
//Should probably raise JIRAs for them.
+org.apache.qpid.transport.network.mina.MINANetworkDriverTest#*
+org.apache.qpid.test.client.destination.AddressBasedDestinationTest#testCreateExchange
org.apache.qpid.test.client.destination.AddressBasedDestinationTest#testBrowseMode
-
-// QPID-3133: On 0-10, the exception listener is currently not invoked when reconnection fails to occurs.
-org.apache.qpid.server.failover.FailoverMethodTest#*
-
-// QPID-3092: the Java broker does not yet implement exchange creation arguments
-org.apache.qpid.test.client.destination.AddressBasedDestinationTest#testCreateExchangeWithArgs
-org.apache.qpid.test.client.destination.AddressBasedDestinationTest#testSessionCreateTopicWithExchangeArgs
diff --git a/qpid/java/test-profiles/JavaExcludes b/qpid/java/test-profiles/JavaExcludes
index 4be228c7da..c38a250abc 100644
--- a/qpid/java/test-profiles/JavaExcludes
+++ b/qpid/java/test-profiles/JavaExcludes
@@ -19,6 +19,13 @@
// Those tests are not finished
org.apache.qpid.test.testcases.TTLTest#*
+org.apache.qpid.test.testcases.FailoverTest#*
+
+// This is a long running test so should exclude from normal runs
+org.apache.qpid.test.client.failover.FailoverTest#test4MinuteFailover
+
+//QPID-1818 : Client code path does not correctly restore a transacted session after failover.
+org.apache.qpid.server.persistent.NoLocalAfterRecoveryTest#*
// QPID-1823: this takes ages to run
org.apache.qpid.client.SessionCreateTest#*
@@ -45,46 +52,3 @@ org.apache.qpid.transport.ConnectionTest#testResumeNonemptyReplayBuffer
//QPID-2845: The queue policy types used by the C++ broker are not currently supported by the Java broker
org.apache.qpid.test.client.queue.QueuePolicyTest#testRingPolicy
org.apache.qpid.test.client.queue.QueuePolicyTest#testRejectPolicy
-
-///////////////////////////////////////////////////////
-//Moved from JavaStandaloneExcludes when it was removed
-///////////////////////////////////////////////////////
-
-// This is a long running test so should exclude from normal runs
-org.apache.qpid.test.client.failover.FailoverTest#test4MinuteFailover
-
-// Those tests require failover support
-org.apache.qpid.test.client.QueueBrowserAutoAckTest#testFailoverAsQueueBrowserCreated
-org.apache.qpid.test.client.QueueBrowserAutoAckTest#testFailoverWithQueueBrowser
-org.apache.qpid.test.client.QueueBrowserClientAckTest#testFailoverAsQueueBrowserCreated
-org.apache.qpid.test.client.QueueBrowserClientAckTest#testFailoverWithQueueBrowser
-org.apache.qpid.test.client.QueueBrowserDupsOkTest#testFailoverAsQueueBrowserCreated
-org.apache.qpid.test.client.QueueBrowserDupsOkTest#testFailoverWithQueueBrowser
-org.apache.qpid.test.client.QueueBrowserNoAckTest#testFailoverAsQueueBrowserCreated
-org.apache.qpid.test.client.QueueBrowserNoAckTest#testFailoverWithQueueBrowser
-org.apache.qpid.test.client.QueueBrowserPreAckTest#testFailoverAsQueueBrowserCreated
-org.apache.qpid.test.client.QueueBrowserPreAckTest#testFailoverWithQueueBrowser
-org.apache.qpid.test.client.QueueBrowserTransactedTest#testFailoverAsQueueBrowserCreated
-org.apache.qpid.test.client.QueueBrowserTransactedTest#testFailoverWithQueueBrowser
-org.apache.qpid.test.testcases.FailoverTest#*
-org.apache.qpid.test.client.failover.FailoverTest#*
-
-// InVM Broker tests awaiting resolution of QPID-1103
-org.apache.qpid.test.client.timeouts.SyncWaitDelayTest#*
-org.apache.qpid.test.client.timeouts.SyncWaitTimeoutDelayTest#*
-
-// This test currently does not pick up the runtime location of the nonVm queueBacking store.
-org.apache.qpid.test.unit.close.FlowToDiskBackingQueueDeleteTest#*
-
-// This test may use QpidTestCase but it is not using the getConnection and is hardwired to InVM
-org.apache.qpid.test.unit.client.connection.CloseAfterConnectionFailureTest#*
-
-//QPID-1818 : Client code path does not correctly restore a transacted session after failover.
-org.apache.qpid.server.persistent.NoLocalAfterRecoveryTest#*
-
-// This test requires the standard configuration file for validation.
-// Excluding here does not reduce test coverage.
-org.apache.qpid.server.configuration.ServerConfigurationFileTest#*
-
-org.apache.qpid.test.unit.client.connection.ConnectionTest#testClientIDVerification
-org.apache.qpid.jms.xa.XAResourceTest#*
diff --git a/qpid/java/test-profiles/JavaInVMExcludes b/qpid/java/test-profiles/JavaInVMExcludes
new file mode 100644
index 0000000000..7e7da4302e
--- /dev/null
+++ b/qpid/java/test-profiles/JavaInVMExcludes
@@ -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.
+//
+
+//======================================================================
+//Exclude the following tests when running the InVM default test profile
+//======================================================================
+
+// The FirewallPlugin only operates for TCP connections, the tests NO-OP when run InVM
+org.apache.qpid.server.security.firewall.FirewallConfigTest#*
+
+// This test requires a broker capable of 0-8/9 and 0-10
+org.apache.qpid.test.client.message.JMSDestinationTest#testReceiveResend
+
+// QPID-2478 test fails when run against broker using 0-8/9
+org.apache.qpid.test.client.message.JMSDestinationTest#testGetDestinationWithCustomExchange
+
+// related to QPID-2471. Temporarily disabling these tests until I figure out why they are failing with the Java broker.
+org.apache.qpid.test.unit.ack.RecoverTest#testRecoverResendsMsgs
+org.apache.qpid.test.unit.ack.RecoverTest#testRecoverResendsMsgsAckOnEarlier
+org.apache.qpid.test.unit.ack.RecoverTest#testAcknowledgePerConsumer
+
+// related to QPID-2471. These are new test cases and fail with the Java broker.
+org.apache.qpid.test.unit.ack.RecoverTest#testOderingWithAsyncConsumer
+org.apache.qpid.test.unit.ack.RecoverTest#testOderingWithSyncConsumer
+
+//The VM broker does not export the logging management JMX MBean
+org.apache.qpid.server.security.acl.ExternalAdminACLTest#*
diff --git a/qpid/java/test-profiles/JavaStandaloneExcludes b/qpid/java/test-profiles/JavaStandaloneExcludes
new file mode 100644
index 0000000000..d208a20d15
--- /dev/null
+++ b/qpid/java/test-profiles/JavaStandaloneExcludes
@@ -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.
+//
+
+// This is a long running test so should exclude from normal runs
+org.apache.qpid.test.client.failover.FailoverTest#test4MinuteFailover
+
+// Those tests require failover support
+org.apache.qpid.test.client.QueueBrowserAutoAckTest#testFailoverAsQueueBrowserCreated
+org.apache.qpid.test.client.QueueBrowserAutoAckTest#testFailoverWithQueueBrowser
+org.apache.qpid.test.client.QueueBrowserClientAckTest#testFailoverAsQueueBrowserCreated
+org.apache.qpid.test.client.QueueBrowserClientAckTest#testFailoverWithQueueBrowser
+org.apache.qpid.test.client.QueueBrowserDupsOkTest#testFailoverAsQueueBrowserCreated
+org.apache.qpid.test.client.QueueBrowserDupsOkTest#testFailoverWithQueueBrowser
+org.apache.qpid.test.client.QueueBrowserNoAckTest#testFailoverAsQueueBrowserCreated
+org.apache.qpid.test.client.QueueBrowserNoAckTest#testFailoverWithQueueBrowser
+org.apache.qpid.test.client.QueueBrowserPreAckTest#testFailoverAsQueueBrowserCreated
+org.apache.qpid.test.client.QueueBrowserPreAckTest#testFailoverWithQueueBrowser
+org.apache.qpid.test.client.QueueBrowserTransactedTest#testFailoverAsQueueBrowserCreated
+org.apache.qpid.test.client.QueueBrowserTransactedTest#testFailoverWithQueueBrowser
+org.apache.qpid.test.testcases.FailoverTest#*
+org.apache.qpid.test.client.failover.FailoverTest#*
+
+// InVM Broker tests awaiting resolution of QPID-1103
+org.apache.qpid.test.client.timeouts.SyncWaitDelayTest#*
+org.apache.qpid.test.client.timeouts.SyncWaitTimeoutDelayTest#*
+
+// This test currently does not pick up the runtime location of the nonVm queueBacking store.
+org.apache.qpid.test.unit.close.FlowToDiskBackingQueueDeleteTest#*
+
+// This test may use QpidTestCase but it is not using the getConnection and is hardwired to InVM
+org.apache.qpid.test.unit.client.connection.CloseAfterConnectionFailureTest#*
+
+//QPID-1818 : Client code path does not correctly restore a transacted session after failover.
+org.apache.qpid.server.persistent.NoLocalAfterRecoveryTest#*
+
+// This test requires the standard configuration file for validation.
+// Excluding here does not reduce test coverage.
+org.apache.qpid.server.configuration.ServerConfigurationFileTest#*
+
diff --git a/qpid/java/test-profiles/cpp.async.testprofile b/qpid/java/test-profiles/cpp.async.testprofile
index 5357e87687..c3d47f0ce6 100644
--- a/qpid/java/test-profiles/cpp.async.testprofile
+++ b/qpid/java/test-profiles/cpp.async.testprofile
@@ -19,5 +19,3 @@
include=cpp
profile.excludes=CPPPrefetchExcludes
broker.modules=--load-module ${broker.module.store}
-broker.persistent=true
-
diff --git a/qpid/java/test-profiles/cpp.testprofile b/qpid/java/test-profiles/cpp.testprofile
index a2114f82ba..694e22f48c 100644
--- a/qpid/java/test-profiles/cpp.testprofile
+++ b/qpid/java/test-profiles/cpp.testprofile
@@ -16,7 +16,7 @@
# specific language governing permissions and limitations
# under the License.
#
-broker.version=v0_10
+broker.version=0-10
broker.language=cpp
broker.dir=${project.root}/../cpp/src
@@ -32,8 +32,7 @@ broker.stopped=Exception constructed
broker.modules=
broker.args=
-broker.type=spawned
-broker.command=${broker.executable} -p @PORT --data-dir ${build.data}/@PORT -t --auth no --no-module-dir ${broker.modules} ${broker.args}
+broker=${broker.executable} -p @PORT --data-dir ${build.data}/@PORT -t --auth no --no-module-dir ${broker.modules} ${broker.args}
profile.excludes=CPPPrefetchExcludes CPPTransientExcludes
test.excludes=Excludes CPPExcludes ${profile}.excludes ${profile.excludes} cpp.excludes
diff --git a/qpid/java/test-profiles/testprofile.defaults b/qpid/java/test-profiles/default.testprofile
index 35429d3fed..df8148f787 100644
--- a/qpid/java/test-profiles/testprofile.defaults
+++ b/qpid/java/test-profiles/default.testprofile
@@ -19,12 +19,14 @@
java.naming.factory.initial=org.apache.qpid.jndi.PropertiesFileInitialContextFactory
java.naming.provider.url=${test.profiles}/test-provider.properties
+broker.version=0-8
+broker=vm
broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
broker.ready=Listening on TCP port
+broker.start=${test.profiles}/start-broker
+broker.kill=${test.profiles}/kill-broker
broker.config=${project.root}/build/etc/config-systests.xml
messagestore.class.name=org.apache.qpid.server.store.MemoryMessageStore
-broker.protocol.excludes=
-broker.persistent=false
max_prefetch=1000
qpid.dest_syntax=BURL
@@ -47,8 +49,9 @@ test.port.alt=25672
test.port.alt.ssl=25671
test.exclude=true
-profile.excludes=
+profile.excludes=JavaTransientExcludes JavaInVMExcludes 08StandaloneExcludes
test.excludes=Excludes XAExcludes JavaExcludes ${profile}.excludes ${profile.excludes}
+test.fork=no
test.mem=512M
test=*Test
haltonfailure=no
@@ -56,5 +59,3 @@ haltonerror=no
exclude.modules=none
profile.clustered=false
-
-
diff --git a/qpid/java/test-profiles/java-dby.0-10.testprofile b/qpid/java/test-profiles/java-dby.0-10.testprofile
deleted file mode 100644
index 5a7b9b5cdc..0000000000
--- a/qpid/java/test-profiles/java-dby.0-10.testprofile
+++ /dev/null
@@ -1,30 +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.
-#
-broker.language=java
-broker.version=v0_10
-broker.type=internal
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
-broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
-broker.ready=BRK-1004
-broker.stopped=Exception
-broker.config=${project.root}/build/etc/config-systests-derby.xml
-messagestore.class.name=org.apache.qpid.server.store.DerbyMessageStore
-profile.excludes=JavaPersistentExcludes Java010Excludes
-broker.clean.between.tests=true
-broker.persistent=true
diff --git a/qpid/java/test-profiles/java-dby.0-9-1.testprofile b/qpid/java/test-profiles/java-dby.0-9-1.testprofile
deleted file mode 100644
index f9700da82d..0000000000
--- a/qpid/java/test-profiles/java-dby.0-9-1.testprofile
+++ /dev/null
@@ -1,36 +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.
-#
-broker.version=v0_9_1
-broker.language=java
-broker.type=internal
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
-broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
-broker.ready=BRK-1004
-broker.stopped=Exception
-broker.config=${project.root}/build/etc/config-systests-derby.xml
-broker.protocol.excludes=--exclude-0-10 @PORT
-messagestore.class.name=org.apache.qpid.server.store.DerbyMessageStore
-profile.excludes=JavaPersistentExcludes JavaPre010Excludes
-broker.clean.between.tests=true
-broker.persistent=true
-#
-# Do not enable. Allow client to attempt 0-10 and negotiate downwards
-#
-#qpid.amqp.version=0-91
-
diff --git a/qpid/java/test-profiles/java-dby-spawn.0-10.testprofile b/qpid/java/test-profiles/java-derby.0.10.testprofile
index f51f5a26ac..ca9115d30d 100644
--- a/qpid/java/test-profiles/java-dby-spawn.0-10.testprofile
+++ b/qpid/java/test-profiles/java-derby.0.10.testprofile
@@ -17,14 +17,13 @@
# under the License.
#
broker.language=java
-broker.version=v0_10
-broker.type=spawned
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
+broker.version=0-10
+broker=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
broker.ready=BRK-1004
broker.stopped=Exception
broker.config=${project.root}/build/etc/config-systests-derby.xml
messagestore.class.name=org.apache.qpid.server.store.DerbyMessageStore
-profile.excludes=JavaPersistentExcludes Java010Excludes
+profile.excludes=JavaStandaloneExcludes JavaPersistentExcludes Java010Excludes
broker.clean.between.tests=true
broker.persistent=true
diff --git a/qpid/java/test-profiles/java-dby-spawn.0-9-1.testprofile b/qpid/java/test-profiles/java-derby.testprofile
index f79e1f3aad..d22e35f07e 100644
--- a/qpid/java/test-profiles/java-dby-spawn.0-9-1.testprofile
+++ b/qpid/java/test-profiles/java-derby.testprofile
@@ -16,17 +16,14 @@
# specific language governing permissions and limitations
# under the License.
#
-broker.version=v0_9_1
broker.language=java
-broker.type=spawned
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
+broker=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT --exclude-0-10 @PORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
broker.ready=BRK-1004
broker.stopped=Exception
broker.config=${project.root}/build/etc/config-systests-derby.xml
-broker.protocol.excludes=--exclude-0-10 @PORT
messagestore.class.name=org.apache.qpid.server.store.DerbyMessageStore
-profile.excludes=JavaPersistentExcludes JavaPre010Excludes
+profile.excludes=JavaStandaloneExcludes JavaPersistentExcludes 08StandaloneExcludes
broker.clean.between.tests=true
broker.persistent=true
#
diff --git a/qpid/java/test-profiles/java-mms-spawn.0-9-1.testprofile b/qpid/java/test-profiles/java-mms-spawn.0-9-1.testprofile
deleted file mode 100644
index f94b93c793..0000000000
--- a/qpid/java/test-profiles/java-mms-spawn.0-9-1.testprofile
+++ /dev/null
@@ -1,31 +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.
-#
-broker.version=v0_9_1
-broker.language=java
-broker.type=spawned
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
-broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
-broker.ready=BRK-1004
-broker.stopped=Exception
-broker.protocol.excludes=--exclude-0-10 @PORT
-#
-# Do not enable. Allow client to attempt 0-10 and negotiate downwards
-#
-#qpid.amqp.version=0-91
-profile.excludes=JavaTransientExcludes JavaPre010Excludes
diff --git a/qpid/java/test-profiles/java-mms.0-9-1.testprofile b/qpid/java/test-profiles/java-mms.0-9-1.testprofile
deleted file mode 100644
index 45e2fc7162..0000000000
--- a/qpid/java/test-profiles/java-mms.0-9-1.testprofile
+++ /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.
-#
-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=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
-broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
-broker.ready=BRK-1004
-broker.stopped=Exception
-broker.protocol.excludes=--exclude-0-10 @PORT
-#
-# Do not enable. Allow client to attempt 0-10 and negotiate downwards
-#
-#qpid.amqp.version=0-91
-profile.excludes=JavaTransientExcludes JavaPre010Excludes
diff --git a/qpid/java/test-profiles/java-mms.0-10.testprofile b/qpid/java/test-profiles/java.0.10.testprofile
index 3ccc6dfd3b..fa87b22e92 100644
--- a/qpid/java/test-profiles/java-mms.0-10.testprofile
+++ b/qpid/java/test-profiles/java.0.10.testprofile
@@ -17,11 +17,10 @@
# under the License.
#
broker.language=java
-broker.version=v0_10
-broker.type=internal
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
+broker.version=0-10
+broker=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
broker.ready=BRK-1004
broker.stopped=Exception
-profile.excludes=JavaTransientExcludes Java010Excludes
+profile.excludes=JavaTransientExcludes JavaStandaloneExcludes Java010Excludes
diff --git a/qpid/java/test-profiles/java-mms-spawn.0-10.testprofile b/qpid/java/test-profiles/java.testprofile
index 4fdac783cc..c8c776d3e1 100644
--- a/qpid/java/test-profiles/java-mms-spawn.0-10.testprofile
+++ b/qpid/java/test-profiles/java.testprofile
@@ -16,15 +16,13 @@
# specific language governing permissions and limitations
# under the License.
#
-broker.version=v0_10
broker.language=java
-broker.type=spawned
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
+broker=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT --exclude-0-10 @PORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
broker.ready=BRK-1004
broker.stopped=Exception
#
# Do not enable. Allow client to attempt 0-10 and negotiate downwards
#
-#qpid.amqp.version=0-10
-profile.excludes=JavaTransientExcludes Java010Excludes
+#qpid.amqp.version=0-91
+profile.excludes=JavaTransientExcludes JavaStandaloneExcludes 08StandaloneExcludes
diff --git a/qpid/java/test-profiles/test-provider.properties b/qpid/java/test-profiles/test-provider.properties
index fe27cfcfaf..8cea012c1d 100644
--- a/qpid/java/test-profiles/test-provider.properties
+++ b/qpid/java/test-profiles/test-provider.properties
@@ -30,12 +30,16 @@ test.port.alt.ssl=25671
connectionfactory.default = amqp://username:password@clientid/test?brokerlist='tcp://localhost:${test.port}'
connectionfactory.default.ssl = amqp://username:password@clientid/test?brokerlist='tcp://localhost:${test.port.ssl}?ssl='true''
+connectionfactory.default.vm = amqp://username:password@clientid/test?brokerlist='vm://:1'
connectionfactory.failover = amqp://username:password@clientid/test?brokerlist='tcp://localhost:${test.port.alt};tcp://localhost:${test.port}'&sync_ack='true'&sync_publish='all'&failover='roundrobin?cyclecount='20''
connectionfactory.failover.ssl = amqp://username:password@clientid/test?brokerlist='tcp://localhost:${test.port.alt.ssl}?ssl='true';tcp://localhost:${test.port.ssl}?ssl='true''&sync_ack='true'&sync_publish='all'&failover='roundrobin?cyclecount='20''
+connectionfactory.failover.vm = amqp://username:password@clientid/test?brokerlist='vm://:2;vm://:1'&failover='roundrobin?cyclecount='20''
connectionfactory.connection1 = amqp://username:password@clientid/test?brokerlist='tcp://localhost:${test.port}'
connectionfactory.connection2 = amqp://username:password@clientid/test?brokerlist='tcp://localhost:${test.port.alt}'
+connectionfactory.connection1.vm = amqp://username:password@clientid/test?brokerlist='vm://:1'
+connectionfactory.connection2.vm = amqp://username:password@clientid/test?brokerlist='vm://:2'
queue.MyQueue = example.MyQueue
diff --git a/qpid/java/tools/bin/Profile-run-from-source b/qpid/java/tools/bin/Profile-run-from-source
deleted file mode 100755
index f8ec45ccff..0000000000
--- a/qpid/java/tools/bin/Profile-run-from-source
+++ /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.
-#
-
-# Sets the environment for running the scripts from a source checkout.
-txtbld=$(tput bold) # Bold
-txtrst=$(tput sgr0) # Reset
-txtred=$(tput setaf 1) # red
-txtgreen=$(tput setaf 2) # green
-
-echo "${txtbld}Setting the environment to run qpid java tools from a source checkout${txtrst}"
-
-abs_path()
-{
- D=`dirname "$1"`
- echo "`cd \"$D\" 2>/dev/null && pwd`"
-}
-
-export QPID_CHECKOUT=`abs_path "../../../../"`
-echo "${txtgreen}Using source checkout at $QPID_CHECKOUT${txtrst}"
-
-export PATH=$QPID_CHECKOUT/java/tools/bin:$PATH
-
-if [ "$JAVA" = "" ] ; then
- export JAVA=$(which java)
-fi
-
-#------------- Required for perf_report, qpid-bench & qpid-python-testkit ----------------
-
-export VENDOR_LIB=$QPID_CHECKOUT/java/build/lib
-export CLASSPATH=`find $VENDOR_LIB -name '*.jar' | tr '\n' ':'`
-export LOG_CONFIG="-Dlog4j.configuration=file:///$QPID_CHECKOUT/java/tools/etc/test.log4j"
-
-
-#------------- Required for qpid-python-testkit -----------------------------------------
-
-PYTHONPATH=$QPID_CHECKOUT/python/qpid:$QPID_CHECKOUT/cpp/src/test/brokertest.py:$PYTHONPATH
-export PATH=$QPID_CHECKOUT/python:$PATH
-
-if [ -x $QPID_CHECKOUT/cpp/src/qpidd ]; then
- QPIDD_EXEC=$QPID_CHECKOUT/cpp/src/qpidd
-else
- echo "${txtred}WARNING: Qpid CPP broker executable not found. You will not be able to run qpid-python-testkit${txtrst}"
-fi
-
-if [ -x $QPID_CHECKOUT/cpp/src/.libs/cluster.so ]; then
- CLUSTER_LIB=$QPID_CHECKOUT/cpp/src/.libs/cluster.so
-else
- echo "${txtred}WARNING: Qpid cluster.so not found.You will not be able to run qpid-python-testkit${txtrst}"
-fi
-
-if [ "$STORE_LIB" = "" ] ; then
- echo "${txtred}WARNING: Please point the STORE_LIB variable to the message store module. If not persistence tests will not write messages to disk.${txtrst}"
-fi
-
-export PYTHONPATH QPIDD_EXEC CLUSTER_LIB
diff --git a/qpid/java/tools/bin/controller b/qpid/java/tools/bin/controller
deleted file mode 100644
index fab8614039..0000000000
--- a/qpid/java/tools/bin/controller
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/bin/sh
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-# This starts the controller for coordinating perf tests/
-
-. check-qpid-java-env
-
-PROGRAM_NAME=controller
-CONSUMER_COUNT=1
-PRODUCER_COUNT=1
-DURATION=-1
-TEST_NAME="TEST_NAME"
-EXTRA_JVM_ARGS=""
-
-TEMP=$(getopt -n $PROGRAM_NAME -o c:p:d:n:a:h --long consumers:,producers:,jvm-args:help -- "$@")
-
-usage()
-{
- printf "\n%s\n" "Usage: controller [option].."
-
- printf "\n%31s\n%52s\n" "-c, --consumer-count=count" "No of consumers participating in the test"
-
- printf "\n%31s\n%52s\n" "-p, --producer-count=count" "No of producers participating in the test"
-
- printf "\n%24s\n%94s\n" "-d, --duration=mins" "The duration of the test in mins. If not specified, it will just run one iteration."
-
- printf "\n%27s\n%32s\n" "-n, --name=<test-name>" "The name of the test."
-
- printf "\n%19s\n%50s\n" "-a, --jvm-args" "Extra jvm arguments you want to specify"
-}
-
-eval set -- "$TEMP"
-while true; do
- case $1 in
- -c|--consumer-count)
- CONSUMER_COUNT="$2"; shift; shift; continue
- ;;
- -p|--producer-count)
- PRODUCER_COUNT="$2"; shift; shift; continue
- ;;
- -d|--duration)
- DURATION="$2"; shift; shift; continue
- ;;
- -n|--name)
- TEST_NAME="$2"; shift; shift; continue
- ;;
- -h|--help)
- usage
- exit 0
- ;;
- -a|--jvm-args)
- EXTRA_JVM_ARGS="$2"; shift; shift; continue
- ;;
- --)
- # no more arguments to parse
- break
- ;;
- *)
- # no more arguments to parse
- break
- ;;
- esac
-done
-
-CONTROLLER_ARGS="-server -Durl=amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5672' -Dprecision=mili -Dprod_count=$PRODUCER_COUNT -Dcons_count=$CONSUMER_COUNT -Dprint_std_dev=true -Dduration=${DURATION}"
-
-
-waitfor() { until grep -a -l "$2" $1 >/dev/null 2>&1 ; do sleep 1 ; done ; }
-cleanup()
-{
- pids=`ps aux | grep java | grep PerfTestController | awk '{print $2}'`
- if [ "$pids" != "" ]; then
- kill -3 $pids
- kill -9 $pids >/dev/null 2>&1
- fi
-}
-
-run_controller()
-{
- TEST_ARGS="$LOG_CONFIG $JAVA_MEM $CONTROLLER_ARGS $EXTRA_JVM_ARGS"
- echo "Running controller with : $TEST_ARGS" > test.out
- $JAVA -cp $CLASSPATH $TEST_ARGS org.apache.qpid.tools.PerfTestController >> test.out &
- waitfor test.out "Controller: Completed the test"
- sleep 2 #give a grace period to shutdown
- print_result $TEST_NAME
-}
-
-print_result()
-{
- prod_rate=`cat test.out | grep "Avg Producer rate" | awk '{print $5}'`
- sys_rate=`cat test.out | grep "System Throughput" | awk '{print $4}'`
- cons_rate=`cat test.out | grep "Avg Consumer rate" | awk '{print $5}'`
- avg_latency=`cat test.out | grep "Avg System Latency" | awk '{print $5}'`
- min_latency=`cat test.out | grep "Min System Latency" | awk '{print $5}'`
- max_latency=`cat test.out | grep "Max System Latency" | awk '{print $5}'`
- std_dev=`cat test.out | grep "Avg System Std Dev" | awk '{print $6}'`
-
- printf "|%-15s|%15.2f|%13.2f|%13.2f|%11.2f|%11.2f|%11.2f|%7.2f|\n" $1 $sys_rate $prod_rate $cons_rate $avg_latency $min_latency $max_latency $std_dev
- echo "--------------------------------------------------------------------------------------------------------"
-}
-
-trap cleanup EXIT
-
-rm -rf *.out
-
-if [ "$DURATION" = -1 ]; then
- echo "Test report on " `date +%F`
- echo "========================================================================================================"
- echo "|Test |System throuput|Producer rate|Consumer Rate|Avg Latency|Min Latency|Max Latency|Std Dev|"
- echo "--------------------------------------------------------------------------------------------------------"
-else
- echo "Test in progress....Tail stats-csv.log to see results being printed for each iteration."
-fi
-
-run_controller
diff --git a/qpid/java/tools/bin/perf-report b/qpid/java/tools/bin/perf_report.sh
index 7de3f2b602..e6b4c987e5 100755
--- a/qpid/java/tools/bin/perf-report
+++ b/qpid/java/tools/bin/perf_report.sh
@@ -18,19 +18,23 @@
# under the License.
#
-# This will run the following test cases defined below and produce
-# a report in tabular format.
+# This will run the 8 use cases defined below and produce
+# a report in tabular format. Refer to the documentation
+# for more details.
+SUB_MEM=-Xmx1024M
+PUB_MEM=-Xmx1024M
+LOG_CONFIG="-Damqj.logging.level=WARN"
QUEUE="queue;{create:always,node:{x-declare:{auto-delete:true}}}"
DURA_QUEUE="dqueue;{create:always,node:{durable:true,x-declare:{auto-delete:true}}}"
TOPIC="amq.topic/test"
DURA_TOPIC="amq.topic/test;{create:always,link:{durable:true}}"
-COMMON_CONFIG="-server -Durl=amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5672'"
+. setenv.sh
waitfor() { until grep -a -l "$2" $1 >/dev/null 2>&1 ; do sleep 1 ; done ; }
cleanup()
-{
+{
pids=`ps aux | grep java | grep Perf | awk '{print $2}'`
if [ "$pids" != "" ]; then
kill -3 $pids
@@ -42,31 +46,30 @@ cleanup()
# $2 consumer options
# $3 producer options
run_testcase()
-{
- sh run-sub $COMMON_CONFIG $2 > sub.out &
- sh run-pub $COMMON_CONFIG $3 > pub.out &
- waitfor pub.out "Controller: Completed the test"
+{
+ sh run_sub.sh $LOG_CONFIG $SUB_MEM $2 > sub.out &
+ waitfor sub.out "Warming up"
+ sh run_pub.sh $LOG_CONFIG $PUB_MEM $3 > pub.out &
+ waitfor sub.out "Completed the test"
+ waitfor pub.out "Consumer has completed the test"
sleep 2 #give a grace period to shutdown
- print_result $1
- mv pub.out $1.pub.out
- mv sub.out $1.sub.out
+ print_result $1
}
print_result()
{
- prod_rate=`cat pub.out | grep "Avg Producer rate" | awk '{print $5}'`
- sys_rate=`cat pub.out | grep "System Throughput" | awk '{print $4}'`
- cons_rate=`cat pub.out | grep "Avg Consumer rate" | awk '{print $5}'`
- avg_latency=`cat pub.out | grep "Avg System Latency" | awk '{print $5}'`
- min_latency=`cat pub.out | grep "Min System Latency" | awk '{print $5}'`
- max_latency=`cat pub.out | grep "Max System Latency" | awk '{print $5}'`
-
- printf "|%-15s|%15.2f|%13.2f|%13.2f|%11.2f|%11.2f|%11.2f|\n" $1 $sys_rate $prod_rate $cons_rate $avg_latency $min_latency $max_latency
+ prod_rate=`cat pub.out | grep "Producer rate" | awk '{print $3}'`
+ sys_rate=`cat sub.out | grep "System Throughput" | awk '{print $4}'`
+ cons_rate=`cat sub.out | grep "Consumer rate" | awk '{print $4}'`
+ avg_latency=`cat sub.out | grep "Avg Latency" | awk '{print $4}'`
+ min_latency=`cat sub.out | grep "Min Latency" | awk '{print $4}'`
+ max_latency=`cat sub.out | grep "Max Latency" | awk '{print $4}'`
+
+ printf "|%-15s|%15.2f|%13.2f|%13.2f|%11.2f|%11d|%11d|\n" $1 $sys_rate $prod_rate $cons_rate $avg_latency $min_latency $max_latency
echo "------------------------------------------------------------------------------------------------"
}
trap cleanup EXIT
-rm -rf *.out #cleanup old files.
echo "Test report on " `date +%F`
echo "================================================================================================"
@@ -79,7 +82,7 @@ echo "--------------------------------------------------------------------------
# setting very low values to start with and experiment while increasing them slowly.
# Test 1 Trans Queue
-run_testcase "Trans_Queue" "-Daddress=$QUEUE" "-Daddress=$QUEUE -Dwarmup_count=1 -Dmsg_count=10"
+#run_testcase "Trans_Queue" "-Daddress=$QUEUE" "-Daddress=$QUEUE -Dwarmup_count=1 -Dmsg_count=10"
# Test 2 Dura Queue
run_testcase "Dura_Queue" "-Daddress=$DURA_QUEUE -Ddurable=true" "-Daddress=$DURA_QUEUE -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10"
diff --git a/qpid/java/tools/bin/qpid-bench b/qpid/java/tools/bin/qpid-bench
index cd894b607f..c982e64efd 100755..100644
--- a/qpid/java/tools/bin/qpid-bench
+++ b/qpid/java/tools/bin/qpid-bench
@@ -18,6 +18,18 @@
# under the License.
#
-. check-qpid-java-env
+if [ -z "$QPID_HOME" ]; then
+ export QPID_HOME=$(dirname $(dirname $(readlink -f $0)))
+ export PATH=${PATH}:${QPID_HOME}/bin
+fi
-$JAVA -cp $CLASSPATH -server $JAVA_MEM $LOG_CONFIG org.apache.qpid.tools.QpidBench "$@"
+# Set classpath to include Qpid jar with all required jars in manifest
+QPID_LIBS=$QPID_HOME/lib/qpid-all.jar
+
+# Set other variables used by the qpid-run script before calling
+export JAVA=java \
+ JAVA_VM=-server \
+ JAVA_MEM=-Xmx1024m \
+ QPID_CLASSPATH=$QPID_LIBS
+
+. qpid-run org.apache.qpid.tools.QpidBench "$@"
diff --git a/qpid/java/tools/bin/qpid-python-testkit b/qpid/java/tools/bin/qpid-python-testkit
index 7233d0d075..cbe7972421 100755
--- a/qpid/java/tools/bin/qpid-python-testkit
+++ b/qpid/java/tools/bin/qpid-python-testkit
@@ -22,12 +22,9 @@
# via the python test runner. The defaults are set for a running
# from an svn checkout
-. check-qpid-java-env
+. ./set-testkit-env.sh
export PYTHONPATH=./:$PYTHONPATH
-echo $PYTHONPATH
-if [ "$OUTDIR" = "" ] ; then
- OUTDIR=$PWD
-fi
-testdir=$OUTDIR/testkit-out-`date +%F-%H-%M-%S`
-qpid-python-test -m testkit -DOUTDIR=$testdir"$@"
+rm -rf $OUTDIR
+qpid-python-test -DOUTDIR=$OUTDIR -m testkit "$@"
+
diff --git a/qpid/java/tools/bin/run-sub b/qpid/java/tools/bin/run_pub.sh
index 8449563f7f..91b9287dea 100755..100644
--- a/qpid/java/tools/bin/run-sub
+++ b/qpid/java/tools/bin/run_pub.sh
@@ -18,15 +18,7 @@
# under the License.
#
-. check-qpid-java-env
-
-echo "All args $@"
-
-JVM_ARGS="$1"
-PROGRAM_ARGS="$2"
-
-echo "JVM ARGS : $JAVA_MEM $JVM_ARGS"
-echo "PROGRAM ARGS : $PROGRAM_ARGS"
-
-$JAVA -cp $CLASSPATH $LOG_CONFIG $JAVA_MEM $JVM_ARGS org.apache.qpid.tools.PerfConsumer $PROGRAM_ARGS
+. $QPID_TEST_HOME/bin/setenv.sh
+echo "$@"
+$JAVA_HOME/bin/java -cp $CLASSPATH $@ org.apache.qpid.tools.PerfProducer
diff --git a/qpid/java/tools/bin/run-pub b/qpid/java/tools/bin/run_sub.sh
index 9efe58c4b8..c9ad2fed74 100755..100644
--- a/qpid/java/tools/bin/run-pub
+++ b/qpid/java/tools/bin/run_sub.sh
@@ -18,11 +18,8 @@
# under the License.
#
-. check-qpid-java-env
+. $QPID_TEST_HOME/bin/setenv.sh
-JVM_ARGS="$1"
-PROGRAM_ARGS="$2"
+echo "$@"
+$JAVA_HOME/bin/java -cp $CLASSPATH $@ org.apache.qpid.tools.PerfConsumer
-echo "JVM ARGS : $JAVA_MEM $JVM_ARGS"
-echo "PROGRAM ARGS : $PROGRAM_ARGS"
-$JAVA -cp $CLASSPATH $LOG_CONFIG $JAVA_MEM $JVM_ARGS org.apache.qpid.tools.PerfProducer $PROGRAM_ARGS
diff --git a/qpid/java/tools/bin/set-testkit-env.sh b/qpid/java/tools/bin/set-testkit-env.sh
new file mode 100644
index 0000000000..051dad8179
--- /dev/null
+++ b/qpid/java/tools/bin/set-testkit-env.sh
@@ -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.
+#
+
+# If QPIDD_EXEC ..etc is not set, it will first check to see
+# if this is run from a qpid svn check out, if not it will look
+# for installed rpms.
+
+abs_path()
+{
+ D=`dirname "$1"`
+ B=`basename "$1"`
+ echo "`cd \"$D\" 2>/dev/null && pwd || echo \"$D\"`/$B"
+}
+
+# Environment for python tests
+
+if [ -d ../../../python ] ; then
+ PYTHON_DIR=../../../python
+ PYTHONPATH=$PYTHON_DIR:$PYTHON_DIR/qpid
+elif [ -z `echo $PYTHONPATH | awk '$0 ~ /qpid/'` ]; then
+ echo "WARNING: skipping test, no qpid python scripts found ."; exit 0;
+fi
+
+
+if [ "$QPIDD_EXEC" = "" ] ; then
+ if [ -x ../../../cpp/src/qpidd ]; then
+ QPIDD_EXEC=`abs_path "../../../cpp/src/qpidd"`
+ elif [ -n "$(which qpidd)" ] ; then
+ QPIDD_EXEC=$(which qpidd)
+ else
+ echo "WARNING: skipping test, QPIDD_EXEC not set and qpidd not found."; exit 0;
+ fi
+fi
+
+if [ "$CLUSTER_LIB" = "" ] ; then
+ if [ -x ../../../cpp/src/.libs/cluster.so ]; then
+ CLUSTER_LIB=`abs_path "../../../cpp/src/.libs/cluster.so"`
+ elif [ -e /usr/lib64/qpid/daemon/cluster.so ] ; then
+ CLUSTER_LIB="/usr/lib64/qpid/daemon/cluster.so"
+ elif [ -e /usr/lib/qpid/daemon/cluster.so ] ; then
+ CLUSTER_LIB="/usr/lib/qpid/daemon/cluster.so"
+ else
+ echo "WARNING: skipping test, CLUSTER_LIB not set and cluster.so not found."; exit 0;
+ fi
+fi
+
+if [ "$STORE_LIB" = "" ] ; then
+ if [ -e /usr/lib64/qpid/daemon/msgstore.so ] ; then
+ STORE_LIB="/usr/lib64/qpid/daemon/msgstore.so"
+ elif [ -e /usr/lib/qpid/daemon/msgstore.so ] ; then
+ STORE_LIB="/usr/lib/qpid/daemon/msgstore.so"
+ #else
+ # echo "WARNING: skipping test, STORE_LIB not set and msgstore.so not found."; exit 0;
+ fi
+fi
+
+if [ "$QP_CP" = "" ] ; then
+ if [ -d ../../build/lib/ ]; then
+ QP_JAR_PATH=`abs_path "../../build/lib/"`
+ elif [ -d /usr/share/java/qpid-deps ]; then
+ QP_JAR_PATH=`abs_path "/usr/share/java"`
+ else
+ "WARNING: skipping test, QP_CP not set and the Qpid jars are not present."; exit 0;
+ fi
+ QP_CP=`find $QP_JAR_PATH -name '*.jar' | tr '\n' ':'`
+fi
+
+if [ "$OUTDIR" = "" ] ; then
+ OUTDIR=`abs_path "./output"`
+fi
+
+export PYTHONPATH PYTHON_DIR QPIDD_EXEC CLUSTER_LIB QP_CP OUTDIR
diff --git a/qpid/java/tools/bin/setenv.sh b/qpid/java/tools/bin/setenv.sh
new file mode 100644
index 0000000000..24135e711b
--- /dev/null
+++ b/qpid/java/tools/bin/setenv.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# Compiles the test classes and sets the CLASSPATH
+
+# check for QPID_TEST_HOME
+if [ "$QPID_TEST_HOME" = "" ] ; then
+ echo "ERROR: Please set QPID_TEST_HOME ...."
+ exit 1
+fi
+
+# check for JAVA_HOME
+if [ "$JAVA_HOME" = "" ] ; then
+ echo "ERROR: Please set JAVA_HOME ...."
+ exit 1
+fi
+
+# VENDOR_LIB path needs to be set
+# for Qpid set this to {qpid_checkout}/java/build/lib
+if [ "$VENDOR_LIB" = "" ] ; then
+ echo "ERROR: Please set VENDOR_LIB path in the script ...."
+ exit 1
+fi
+
+
+[ -d $QPID_TEST_HOME/classes ] || mkdir $QPID_TEST_HOME/classes
+
+CLASSPATH=`find $VENDOR_LIB -name *.jar* | tr '\n' ":"`
+$JAVA_HOME/bin/javac -cp $CLASSPATH -d $QPID_TEST_HOME/classes -sourcepath $QPID_TEST_HOME/src `find $QPID_TEST_HOME/src -name '*.java'`
+
+export CLASSPATH=$QPID_TEST_HOME/classes:$CLASSPATH
+
diff --git a/qpid/java/tools/bin/start-consumers b/qpid/java/tools/bin/start-consumers
deleted file mode 100644
index c71fc0c21f..0000000000
--- a/qpid/java/tools/bin/start-consumers
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/bin/sh
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-# This starts the controller for coordinating perf tests/
-
-. check-qpid-java-env
-
-PROGRAM_NAME="start-consumers"
-PROCESS_COUNT=1
-CON_COUNT=1
-MSG_COUNT=10000
-ADDRESS="queue;{create:always}"
-UNIQUE_DEST="false"
-
-EXTRA_JVM_ARGS=" -Dmax_prefetch=500 "
-
-TEST_ID=`echo ${HOSTNAME} | awk -F . '{print $1}'`
-
-TEMP=$(getopt -n $PROGRAM_NAME -o C:P:uc:p:a:s:t:w:h\
- --long connection-count:,process-count:,create-unique-queues-topics,\
-jvm-args:,queue:,topic:,address:,\
-msg-count:,help -- "$@")
-
-usage()
-{
- printf "\n%s\n" "Usage: start-producers [option].."
-
- printf "\n%32s\n%51s\n" "-C, --connection-count=count" "No of consumers participating in the test"
-
- printf "\n%29s\n%51s\n" "-P, --process-count=count" "No of producers participating in the test"
-
- printf "\n%37s\n%105s\n" "-u, --create-unique-queues-topics" "This will create unique queue names and topics based on what you specify for --queue or --topic"
-
- printf "\n%11s\n%55s\n" "--queue" "The Queue you want to publish to. Ex my-queue"
-
- printf "\n%11s\n%84s\n" "--topic" "The Topic you want to publish to in amq.topic exchange. Ex amq.topic/topic"
-
- printf "\n%13s\n%44s\n" "--address" "The address you want to publish to"
-
- printf "\n%25s\n%50s\n" "-c, --msg-count=count" "message count per test (default 500,000)"
-
- printf "\n%18s\n%49s\n" "-a, --jvm-args" "Extra jvm arguments you want to specify"
-}
-
-eval set -- "$TEMP"
-while true; do
- case $1 in
- -C|--connection-count)
- CON_COUNT="$2"; shift; shift; continue
- ;;
- -P|--process-count)
- PROCESS_COUNT="$2"; shift; shift; continue
- ;;
- -u|--create-unique-queues-topics)
- UNIQUE_DEST="true"; shift; continue
- ;;
- --queue)
- ADDRESS="$2;{create: always}"; shift; shift; continue
- ;;
- --topic)
- ADDRESS="amq.topic/$2"; shift; shift; continue
- ;;
- --address)
- ADDRESS="$2"; shift; shift; continue
- ;;
- -h|--help)
- usage
- exit 0
- ;;
- -a|--jvm-args)
- EXTRA_JVM_ARGS="$2"; shift; shift; continue
- ;;
- -c|--msg-count)
- MSG_COUNT="$2"; shift; shift; continue
- ;;
- --)
- # no more arguments to parse
- break
- ;;
- *)
- # no more arguments to parse
- break
- ;;
- esac
-done
-
-CONSUMER_ARGS="-server -Durl=amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5672' -Dprecision=mili -Dcon_count=$CON_COUNT -Dprint_std_dev=true"
-
-start_consumers()
-{
- for ((i=0; i<$PROCESS_COUNT; i++))
- do
- if [ "$UNIQUE_DEST" = "true" ]; then
- sh run-sub "$CONSUMER_ARGS $@" "${TEST_ID}_$i" > ${TEST_ID}_$i.sub.out 2>&1 &
- else
- sh run-sub "$CONSUMER_ARGS $@" > ${TEST_ID}_$i.sub.out 2>&1 &
- fi
- done
-}
-
-start_consumers "-Daddress=$ADDRESS -Duse_unique_dest=$UNIQUE_DEST -Dmsg_count=$MSG_COUNT -Dcon_count=$CON_COUNT $EXTRA_JVM_ARGS"
-
diff --git a/qpid/java/tools/bin/start-producers b/qpid/java/tools/bin/start-producers
deleted file mode 100644
index 7ba0286f7c..0000000000
--- a/qpid/java/tools/bin/start-producers
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/bin/sh
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-# This starts the controller for coordinating perf tests/
-
-. check-qpid-java-env
-
-PROGRAM_NAME="start-producers"
-PROCESS_COUNT=1
-CON_COUNT=1
-MSG_TYPE="bytes"
-WARMUP_MSG_COUNT=1000
-MSG_COUNT=10000
-MSG_SIZE=1024
-ADDRESS="queue;{create:always}"
-UNIQUE_DEST="false"
-
-EXTRA_JVM_ARGS=""
-TEST_ID=`echo ${HOSTNAME} | awk -F . '{print $1}'`
-
-TEMP=$(getopt -n $PROGRAM_NAME -o C:P:uc:p:a:s:t:w:h\
- --long connection-count:,process-count:,create-unique-queues-topics,\
-jvm-args:,queue:,topic:,address:,\
-msg-count:,msg-size:msg-type:,warmup-msg-count,help -- "$@")
-
-usage()
-{
- printf "\n%s\n" "Usage: start-producers [option].."
-
- printf "\n%32s\n%51s\n" "-C, --connection-count=count" "No of consumers participating in the test"
-
- printf "\n%29s\n%51s\n" "-P, --process-count=count" "No of producers participating in the test"
-
- printf "\n%37s\n%105s\n" "-u, --create-unique-queues-topics" "This will create unique queue names and topics based on what you specify for --queue or --topic"
-
- printf "\n%11s\n%55s\n" "--queue" "The Queue you want to publish to. Ex my-queue"
-
- printf "\n%11s\n%84s\n" "--topic" "The Topic you want to publish to in amq.topic exchange. Ex amq.topic/topic"
-
- printf "\n%13s\n%44s\n" "--address" "The address you want to publish to"
-
- printf "\n%23s\n%37s\n" "-s, --msg-size=size" "message size (default 1024)"
-
- printf "\n%25s\n%50s\n" "-c, --msg-count=count" "message count per test (default 500,000)"
-
- printf "\n%18s\n%38s\n" "-t, --msg-type" "{bytes|text} (default bytes)"
-
- printf "\n%26s\n%49s\n" "-w, --warmup-msg-count" "warm up message count (default 100,000)"
-
- printf "\n%18s\n%49s\n" "-a, --jvm-args" "Extra jvm arguments you want to specify"
-}
-
-eval set -- "$TEMP"
-while true; do
- case $1 in
- -C|--connection-count)
- CON_COUNT="$2"; shift; shift; continue
- ;;
- -P|--process-count)
- PROCESS_COUNT="$2"; shift; shift; continue
- ;;
- -u|--create-unique-queues-topics)
- UNIQUE_DEST="true"; shift; continue
- ;;
- --queue)
- ADDRESS="$2;{create: always}"; shift; shift; continue
- ;;
- --topic)
- ADDRESS="amq.topic/$2"; shift; shift; continue
- ;;
- --address)
- ADDRESS="$2"; shift; shift; continue
- ;;
- -h|--help)
- usage
- exit 0
- ;;
- -a|--jvm-args)
- EXTRA_JVM_ARGS="$2"; shift; shift; continue
- ;;
- -s|--msg-size)
- MSG_SIZE="$2"; shift; shift; continue
- ;;
- -c|--msg-count)
- MSG_COUNT="$2"; shift; shift; continue
- ;;
- -t|--msg_type)
- MSG_TYPE="$2"; shift; shift; continue
- ;;
- -w|--warmup-msg-count)
- WARMUP_MSG_COUNT="$2"; shift; shift; continue
- ;;
- --)
- # no more arguments to parse
- break
- ;;
- *)
- # no more arguments to parse
- break
- ;;
- esac
-done
-
-PRODUCER_ARGS="-server -Durl=amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5672' -Dext_controller=true -Dprecision=mili -Dcon_count=$CON_COUNT"
-
-start_producers()
-{
- for ((i=0; i<$PROCESS_COUNT; i++))
- do
- if [ "$UNIQUE_DEST" = "true" ]; then
- sh run-pub "$PRODUCER_ARGS $@" "${TEST_ID}_$i" > ${TEST_ID}_$i.pub.out 2>&1 &
- else
- sh run-pub "$PRODUCER_ARGS $@" > ${TEST_ID}_$i.pub.out 2>&1 &
- fi
- done
-}
-
-start_producers "-Daddress=$ADDRESS -Duse_unique_dest=$UNIQUE_DEST -Dmsg_count=$MSG_COUNT -Dmsg_size=$MSG_SIZE -Dwarmup_count=$WARMUP_MSG_COUNT -Dmsg_type=$MSG_TYPE -Dcon_count=$CON_COUNT $EXTRA_JVM_ARGS"
-
diff --git a/qpid/java/tools/etc/perf-report.gnu b/qpid/java/tools/etc/perf-report.gnu
deleted file mode 100644
index 6d5020efb5..0000000000
--- a/qpid/java/tools/etc/perf-report.gnu
+++ /dev/null
@@ -1,42 +0,0 @@
-set terminal png
-set datafile separator ","
-
-set title "Variation of avg latency between iterations"
-set yrange [10:20]
-set xlabel "Iterations"
-set ylabel "Latency (ms)"
-set output "avg_latency.png"
-plot "stats-csv.log" using 9 title "avg latency" with lines, 14 title "target latency" with lines
-
-
-set title "Variation of max latency between iterations"
-set yrange [0:1000]
-set xlabel "Iterations"
-set ylabel "Latency (ms)"
-set output "max_latency.png"
-plot "stats-csv.log" using 11 title "max latency" with lines,14 title "target latency" with lines,100 title "100 ms" with lines
-
-
-set title "Variation of standard deviation of latency between iterations"
-set yrange [0:20]
-set xlabel "Iterations"
-set ylabel "Standard Deviation"
-set output "std_dev_latency.png"
-plot "stats-csv.log" using 12 title "standard deviation" with lines
-
-
-set title "Variation of system throughput between iterations"
-set yrange [400000:450000]
-set xlabel "Iterations"
-set ylabel "System Throuhgput (msg/sec)"
-set output "system_rate.png"
-plot "stats-csv.log" using 2 title "system throughput" with lines
-
-
-set title "Variation of avg producer & consumer rates between iterations"
-set yrange [6500:7500]
-set xlabel "Iterations"
-set ylabel "Avg Rates (msg/sec)"
-set output "prod_cons_rate.png"
-plot "stats-csv.log" using 6 title "producer rate" with lines,"stats-csv.log" using 3 title "consumer rate" with lines
-
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/Clock.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/Clock.java
deleted file mode 100644
index 37369959a8..0000000000
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/Clock.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package org.apache.qpid.tools;
-
-/**
- * In the future this will be replaced by a Clock abstraction
- * that can utilize a realtime clock when running in RT Java.
- */
-
-public class Clock
-{
- private static Precision precision;
- private static long offset = -1; // in nano secs
-
- public enum Precision
- {
- NANO_SECS, MILI_SECS;
-
- static Precision getPrecision(String str)
- {
- if ("mili".equalsIgnoreCase(str))
- {
- return MILI_SECS;
- }
- else
- {
- return NANO_SECS;
- }
- }
- };
-
- static
- {
- precision = Precision.getPrecision(System.getProperty("precision","mili"));
- //offset = Long.getLong("offset",-1);
-
- System.out.println("Using precision : " + precision + " and offset " + offset);
- }
-
- public static Precision getPrecision()
- {
- return precision;
- }
-
- public static long getTime()
- {
- if (precision == Precision.NANO_SECS)
- {
- if (offset == -1)
- {
- return System.nanoTime();
- }
- else
- {
- return System.nanoTime() + offset;
- }
- }
- else
- {
- if (offset == -1)
- {
- return System.currentTimeMillis();
- }
- else
- {
- return System.currentTimeMillis() + offset/convertToMiliSecs();
- }
- }
- }
-
- public static long convertToSecs()
- {
- if (precision == Precision.NANO_SECS)
- {
- return 1000000000;
- }
- else
- {
- return 1000;
- }
- }
-
- public static long convertToMiliSecs()
- {
- if (precision == Precision.NANO_SECS)
- {
- return 1000000;
- }
- else
- {
- return 1;
- }
- }
-}
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/LatencyTest.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/LatencyTest.java
index 90ee7e28ae..b88b242e6d 100644
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/LatencyTest.java
+++ b/qpid/java/tools/src/main/java/org/apache/qpid/tools/LatencyTest.java
@@ -77,7 +77,7 @@ public class LatencyTest extends PerfBase implements MessageListener
public LatencyTest()
{
- super("");
+ super();
warmedUp = lock.newCondition();
testCompleted = lock.newCondition();
// Storing the following two for efficiency
@@ -314,7 +314,7 @@ public class LatencyTest extends PerfBase implements MessageListener
public static void main(String[] args)
{
- final LatencyTest latencyTest = new LatencyTest();
+ final LatencyTest latencyTest = new LatencyTest();
Runnable r = new Runnable()
{
public void run()
@@ -334,16 +334,16 @@ public class LatencyTest extends PerfBase implements MessageListener
}
}
};
-
+
Thread t;
try
{
- t = Threading.getThreadFactory().createThread(r);
+ t = Threading.getThreadFactory().createThread(r);
}
catch(Exception e)
{
throw new Error("Error creating latency test thread",e);
}
- t.start();
+ t.start();
}
-}
+} \ No newline at end of file
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfBase.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfBase.java
index 121e94cea1..ac597d17de 100644
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfBase.java
+++ b/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfBase.java
@@ -20,113 +20,36 @@
*/
package org.apache.qpid.tools;
-import java.net.InetAddress;
import java.text.DecimalFormat;
-import java.util.UUID;
+import java.util.Hashtable;
import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
import javax.jms.Destination;
-import javax.jms.MapMessage;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
import javax.jms.Session;
+import javax.naming.Context;
+import javax.naming.InitialContext;
import org.apache.qpid.client.AMQAnyDestination;
import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQDestination;
-import org.apache.qpid.client.AMQSession_0_10;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.messaging.Address;
public class PerfBase
{
- public final static String CODE = "CODE";
- public final static String ID = "ID";
- public final static String REPLY_ADDR = "REPLY_ADDR";
- public final static String MAX_LATENCY = "MAX_LATENCY";
- public final static String MIN_LATENCY = "MIN_LATENCY";
- public final static String AVG_LATENCY = "AVG_LATENCY";
- public final static String STD_DEV = "STD_DEV";
- public final static String CONS_RATE = "CONS_RATE";
- public final static String PROD_RATE = "PROD_RATE";
- public final static String MSG_COUNT = "MSG_COUNT";
- public final static String TIMESTAMP = "Timestamp";
-
- String CONTROLLER_ADDR = System.getProperty("CONT_ADDR","CONTROLLER;{create: always, node:{x-declare:{auto-delete:true}}}");
-
TestParams params;
Connection con;
Session session;
- Session controllerSession;
Destination dest;
- Destination myControlQueue;
- Destination controllerQueue;
+ Destination feedbackDest;
DecimalFormat df = new DecimalFormat("###.##");
- String id;
- String myControlQueueAddr;
-
- MessageProducer sendToController;
- MessageConsumer receiveFromController;
- String prefix = "";
- enum OPCode {
- REGISTER_CONSUMER, REGISTER_PRODUCER,
- PRODUCER_STARTWARMUP, CONSUMER_STARTWARMUP,
- CONSUMER_READY, PRODUCER_READY,
- PRODUCER_START,
- RECEIVED_END_MSG, CONSUMER_STOP,
- RECEIVED_PRODUCER_STATS, RECEIVED_CONSUMER_STATS,
- CONTINUE_TEST, STOP_TEST
- };
-
- enum MessageType {
- BYTES, TEXT, MAP, OBJECT;
-
- public static MessageType getType(String s) throws Exception
- {
- if ("text".equalsIgnoreCase(s))
- {
- return TEXT;
- }
- else if ("bytes".equalsIgnoreCase(s))
- {
- return BYTES;
- }
- /*else if ("map".equalsIgnoreCase(s))
- {
- return MAP;
- }
- else if ("object".equalsIgnoreCase(s))
- {
- return OBJECT;
- }*/
- else
- {
- throw new Exception("Unsupported message type");
- }
- }
- };
-
- MessageType msgType = MessageType.BYTES;
-
- public PerfBase(String prefix)
+ public PerfBase()
{
params = new TestParams();
- String host = "";
- try
- {
- host = InetAddress.getLocalHost().getHostName();
- }
- catch (Exception e)
- {
- }
- id = host + "-" + UUID.randomUUID().toString();
- this.prefix = prefix;
- this.myControlQueueAddr = id + ";{create: always}";
}
public void setUp() throws Exception
- {
+ {
+
if (params.getHost().equals("") || params.getPort() == -1)
{
con = new AMQConnection(params.getUrl());
@@ -139,78 +62,7 @@ public class PerfBase
session = con.createSession(params.isTransacted(),
params.isTransacted()? Session.SESSION_TRANSACTED:params.getAckMode());
- controllerSession = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- dest = createDestination();
- controllerQueue = new AMQAnyDestination(CONTROLLER_ADDR);
- myControlQueue = session.createQueue(myControlQueueAddr);
- msgType = MessageType.getType(params.getMessageType());
- System.out.println("Using " + msgType + " messages");
-
- sendToController = controllerSession.createProducer(controllerQueue);
- receiveFromController = controllerSession.createConsumer(myControlQueue);
- }
-
- private Destination createDestination() throws Exception
- {
- if (params.isUseUniqueDests())
- {
- System.out.println("Prefix : " + prefix);
- Address addr = Address.parse(params.getAddress());
- AMQAnyDestination temp = new AMQAnyDestination(params.getAddress());
- int type = ((AMQSession_0_10)session).resolveAddressType(temp);
-
- if ( type == AMQDestination.TOPIC_TYPE)
- {
- addr = new Address(addr.getName(),addr.getSubject() + "." + prefix,addr.getOptions());
- System.out.println("Setting subject : " + addr);
- }
- else
- {
- addr = new Address(addr.getName() + "_" + prefix,addr.getSubject(),addr.getOptions());
- System.out.println("Setting name : " + addr);
- }
-
- return new AMQAnyDestination(addr);
- }
- else
- {
- return new AMQAnyDestination(params.getAddress());
- }
- }
-
- public synchronized void sendMessageToController(MapMessage m) throws Exception
- {
- m.setString(ID, id);
- m.setString(REPLY_ADDR,myControlQueueAddr);
- sendToController.send(m);
- }
-
- public void receiveFromController(OPCode expected) throws Exception
- {
- MapMessage m = (MapMessage)receiveFromController.receive();
- OPCode code = OPCode.values()[m.getInt(CODE)];
- System.out.println("Received Code : " + code);
- if (expected != code)
- {
- throw new Exception("Expected OPCode : " + expected + " but received : " + code);
- }
-
- }
-
- public boolean continueTest() throws Exception
- {
- MapMessage m = (MapMessage)receiveFromController.receive();
- OPCode code = OPCode.values()[m.getInt(CODE)];
- System.out.println("Received Code : " + code);
- return (code == OPCode.CONTINUE_TEST);
- }
-
- public void tearDown() throws Exception
- {
- session.close();
- controllerSession.close();
- con.close();
+ dest = new AMQAnyDestination(params.getAddress());
}
public void handleError(Exception e,String msg)
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfConsumer.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfConsumer.java
index b63892bb51..0ef0455a64 100644
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfConsumer.java
+++ b/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfConsumer.java
@@ -20,17 +20,13 @@
*/
package org.apache.qpid.tools;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-import javax.jms.MapMessage;
+import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
import javax.jms.TextMessage;
-import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.thread.Threading;
/**
@@ -51,7 +47,7 @@ import org.apache.qpid.thread.Threading;
* b) They are on separate machines that have their time synced via a Time Server
*
* In order to calculate latency the producer inserts a timestamp
- * when the message is sent. The consumer will note the current time the message is
+ * hen the message is sent. The consumer will note the current time the message is
* received and will calculate the latency as follows
* latency = rcvdTime - msg.getJMSTimestamp()
*
@@ -59,9 +55,13 @@ import org.apache.qpid.thread.Threading;
* variance in latencies.
*
* Avg latency is measured by adding all latencies and dividing by the total msgs.
+ * You can also compute this by (rcvdTime - testStartTime)/rcvdMsgCount
*
* Throughput
* ===========
+ * System throughput is calculated as follows
+ * rcvdMsgCount/(rcvdTime - testStartTime)
+ *
* Consumer rate is calculated as
* rcvdMsgCount/(rcvdTime - startTime)
*
@@ -81,160 +81,130 @@ public class PerfConsumer extends PerfBase implements MessageListener
long minLatency = Long.MAX_VALUE;
long totalLatency = 0; // to calculate avg latency.
int rcvdMsgCount = 0;
+ long testStartTime = 0; // to measure system throughput
long startTime = 0; // to measure consumer throughput
long rcvdTime = 0;
boolean transacted = false;
int transSize = 0;
- boolean printStdDev = false;
- List<Long> sample;
-
final Object lock = new Object();
- public PerfConsumer(String prefix)
+ public PerfConsumer()
{
- super(prefix);
- System.out.println("Consumer ID : " + id);
+ super();
}
public void setUp() throws Exception
{
super.setUp();
consumer = session.createConsumer(dest);
- System.out.println("Consumer: " + id + " Receiving messages from : " + ((AMQDestination)dest).getQueueName() + "\n");
// Storing the following two for efficiency
transacted = params.isTransacted();
transSize = params.getTransactionSize();
- printStdDev = params.isPrintStdDev();
- MapMessage m = controllerSession.createMapMessage();
- m.setInt(CODE, OPCode.REGISTER_CONSUMER.ordinal());
- sendMessageToController(m);
}
public void warmup()throws Exception
{
- receiveFromController(OPCode.CONSUMER_STARTWARMUP);
- Message msg = consumer.receive();
- // This is to ensure we drain the queue before we start the actual test.
- while ( msg != null)
+ System.out.println("Warming up......");
+
+ boolean start = false;
+ while (!start)
{
- if (msg.getBooleanProperty("End") == true)
+ Message msg = consumer.receive();
+ if (msg instanceof TextMessage)
{
- // It's more realistic for the consumer to signal this.
- MapMessage m = controllerSession.createMapMessage();
- m.setInt(CODE, OPCode.PRODUCER_READY.ordinal());
- sendMessageToController(m);
+ if (((TextMessage)msg).getText().equals("End"))
+ {
+ start = true;
+ MessageProducer temp = session.createProducer(msg.getJMSReplyTo());
+ temp.send(session.createMessage());
+ if (params.isTransacted())
+ {
+ session.commit();
+ }
+ temp.close();
+ }
}
- msg = consumer.receive(1000);
- }
-
- if (params.isTransacted())
- {
- session.commit();
}
-
- MapMessage m = controllerSession.createMapMessage();
- m.setInt(CODE, OPCode.CONSUMER_READY.ordinal());
- sendMessageToController(m);
- consumer.setMessageListener(this);
}
public void startTest() throws Exception
{
- System.out.println("Consumer: " + id + " Starting test......" + "\n");
- resetCounters();
+ System.out.println("Starting test......");
+ consumer.setMessageListener(this);
}
- public void resetCounters()
+ public void printResults() throws Exception
{
- rcvdMsgCount = 0;
- maxLatency = 0;
- minLatency = Long.MAX_VALUE;
- totalLatency = 0;
- if (printStdDev)
+ synchronized (lock)
{
- sample = null;
- sample = new ArrayList<Long>(params.getMsgCount());
+ lock.wait();
}
- }
-
- public void sendResults() throws Exception
- {
- receiveFromController(OPCode.CONSUMER_STOP);
double avgLatency = (double)totalLatency/(double)rcvdMsgCount;
- double consRate = (double)rcvdMsgCount*Clock.convertToSecs()/(double)(rcvdTime - startTime);
- double stdDev = 0.0;
- if (printStdDev)
- {
- stdDev = calculateStdDev(avgLatency);
- }
- MapMessage m = controllerSession.createMapMessage();
- m.setInt(CODE, OPCode.RECEIVED_CONSUMER_STATS.ordinal());
- m.setDouble(AVG_LATENCY, avgLatency/Clock.convertToMiliSecs());
- m.setDouble(MIN_LATENCY,minLatency/Clock.convertToMiliSecs());
- m.setDouble(MAX_LATENCY,maxLatency/Clock.convertToMiliSecs());
- m.setDouble(STD_DEV, stdDev/Clock.convertToMiliSecs());
- m.setDouble(CONS_RATE, consRate);
- m.setLong(MSG_COUNT, rcvdMsgCount);
- sendMessageToController(m);
-
+ double throughput = ((double)rcvdMsgCount/(double)(rcvdTime - testStartTime))*1000;
+ double consRate = ((double)rcvdMsgCount/(double)(rcvdTime - startTime))*1000;
System.out.println(new StringBuilder("Total Msgs Received : ").append(rcvdMsgCount).toString());
System.out.println(new StringBuilder("Consumer rate : ").
append(df.format(consRate)).
append(" msg/sec").toString());
+ System.out.println(new StringBuilder("System Throughput : ").
+ append(df.format(throughput)).
+ append(" msg/sec").toString());
System.out.println(new StringBuilder("Avg Latency : ").
- append(df.format(avgLatency/Clock.convertToMiliSecs())).
+ append(df.format(avgLatency)).
append(" ms").toString());
System.out.println(new StringBuilder("Min Latency : ").
- append(df.format(minLatency/Clock.convertToMiliSecs())).
+ append(minLatency).
append(" ms").toString());
System.out.println(new StringBuilder("Max Latency : ").
- append(df.format(maxLatency/Clock.convertToMiliSecs())).
+ append(maxLatency).
append(" ms").toString());
- if (printStdDev)
- {
- System.out.println(new StringBuilder("Std Dev : ").
- append(stdDev/Clock.convertToMiliSecs()).toString());
- }
+ System.out.println("Completed the test......\n");
}
- public double calculateStdDev(double mean)
+ public void notifyCompletion(Destination replyTo) throws Exception
{
- double v = 0;
- for (double latency: sample)
+ MessageProducer tmp = session.createProducer(replyTo);
+ Message endMsg = session.createMessage();
+ tmp.send(endMsg);
+ if (params.isTransacted())
{
- v = v + Math.pow((latency-mean), 2);
+ session.commit();
}
- v = v/sample.size();
- return Math.round(Math.sqrt(v));
+ tmp.close();
+ }
+
+ public void tearDown() throws Exception
+ {
+ consumer.close();
+ session.close();
+ con.close();
}
public void onMessage(Message msg)
{
try
{
- // To figure out the decoding overhead of text
- if (msgType == MessageType.TEXT)
+ if (msg instanceof TextMessage && ((TextMessage)msg).getText().equals("End"))
{
- ((TextMessage)msg).getText();
- }
+ notifyCompletion(msg.getJMSReplyTo());
- if (msg.getBooleanProperty("End"))
- {
- MapMessage m = controllerSession.createMapMessage();
- m.setInt(CODE, OPCode.RECEIVED_END_MSG.ordinal());
- sendMessageToController(m);
+ synchronized (lock)
+ {
+ lock.notifyAll();
+ }
}
else
{
- rcvdTime = Clock.getTime();
+ rcvdTime = System.currentTimeMillis();
rcvdMsgCount ++;
if (rcvdMsgCount == 1)
{
startTime = rcvdTime;
+ testStartTime = msg.getJMSTimestamp();
}
if (transacted && (rcvdMsgCount % transSize == 0))
@@ -242,14 +212,10 @@ public class PerfConsumer extends PerfBase implements MessageListener
session.commit();
}
- long latency = rcvdTime - msg.getLongProperty(TIMESTAMP);
+ long latency = rcvdTime - msg.getJMSTimestamp();
maxLatency = Math.max(maxLatency, latency);
minLatency = Math.min(minLatency, latency);
totalLatency = totalLatency + latency;
- if (printStdDev)
- {
- sample.add(latency);
- }
}
}
@@ -260,21 +226,14 @@ public class PerfConsumer extends PerfBase implements MessageListener
}
- public void run()
+ public void test()
{
try
{
setUp();
warmup();
- boolean nextIteration = true;
- while (nextIteration)
- {
- System.out.println("=========================================================\n");
- System.out.println("Consumer: " + id + " starting a new iteration ......\n");
- startTest();
- sendResults();
- nextIteration = continueTest();
- }
+ startTest();
+ printResults();
tearDown();
}
catch(Exception e)
@@ -283,43 +242,26 @@ public class PerfConsumer extends PerfBase implements MessageListener
}
}
- @Override
- public void tearDown() throws Exception
- {
- super.tearDown();
- }
-
- public static void main(String[] args) throws InterruptedException
+ public static void main(String[] args)
{
- String scriptId = (args.length == 1) ? args[0] : "";
- int conCount = Integer.getInteger("con_count",1);
- final CountDownLatch testCompleted = new CountDownLatch(conCount);
- for (int i=0; i < conCount; i++)
+ final PerfConsumer cons = new PerfConsumer();
+ Runnable r = new Runnable()
{
-
- final PerfConsumer cons = new PerfConsumer(scriptId + i);
- Runnable r = new Runnable()
- {
- public void run()
- {
- cons.run();
- testCompleted.countDown();
- }
- };
-
- Thread t;
- try
- {
- t = Threading.getThreadFactory().createThread(r);
- }
- catch(Exception e)
+ public void run()
{
- throw new Error("Error creating consumer thread",e);
+ cons.test();
}
- t.start();
-
+ };
+
+ Thread t;
+ try
+ {
+ t = Threading.getThreadFactory().createThread(r);
+ }
+ catch(Exception e)
+ {
+ throw new Error("Error creating consumer thread",e);
}
- testCompleted.await();
- System.out.println("Consumers have completed the test......\n");
+ t.start();
}
} \ No newline at end of file
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfProducer.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfProducer.java
index ac6129ab68..015d1e6205 100644
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfProducer.java
+++ b/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfProducer.java
@@ -23,15 +23,13 @@ package org.apache.qpid.tools;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
-import java.util.concurrent.CountDownLatch;
import javax.jms.BytesMessage;
import javax.jms.DeliveryMode;
-import javax.jms.MapMessage;
import javax.jms.Message;
+import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
-import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.thread.Threading;
/**
@@ -53,52 +51,38 @@ import org.apache.qpid.thread.Threading;
* System throughput and latencies calculated by the PerfConsumer are more realistic
* numbers.
*
- * Answer by rajith : I agree about in memory buffering affecting rates. But Based on test runs
- * I have done so far, it seems quite useful to compute the producer rate as it gives an
- * indication of how the system behaves. For ex if there is a gap between producer and consumer rates
- * you could clearly see the higher latencies and when producer and consumer rates are very close,
- * latency is good.
- *
*/
public class PerfProducer extends PerfBase
{
- private static long SEC = 60000;
-
MessageProducer producer;
Message msg;
- Object payload;
- List<Object> payloads;
+ byte[] payload;
+ List<byte[]> payloads;
boolean cacheMsg = false;
boolean randomMsgSize = false;
boolean durable = false;
Random random;
int msgSizeRange = 1024;
- boolean rateLimitProducer = false;
- double rateFactor = 0.4;
- double rate = 0.0;
-
- public PerfProducer(String prefix)
+
+ public PerfProducer()
{
- super(prefix);
- System.out.println("Producer ID : " + id);
+ super();
}
public void setUp() throws Exception
{
super.setUp();
- durable = params.isDurable();
- rateLimitProducer = params.getRate() > 0 ? true : false;
- if (rateLimitProducer)
- {
- System.out.println("The test will attempt to limit the producer to " + params.getRate() + " msg/sec");
- }
+ feedbackDest = session.createTemporaryQueue();
+ durable = params.isDurable();
+
// if message caching is enabled we pre create the message
// else we pre create the payload
if (params.isCacheMessage())
{
cacheMsg = true;
- msg = createMessage(createPayload(params.getMsgSize()));
+
+ msg = MessageFactory.createBytesMessage(session, params.getMsgSize());
msg.setJMSDeliveryMode(durable?
DeliveryMode.PERSISTENT :
DeliveryMode.NON_PERSISTENT
@@ -109,52 +93,21 @@ public class PerfProducer extends PerfBase
random = new Random(20080921);
randomMsgSize = true;
msgSizeRange = params.getMsgSize();
- payloads = new ArrayList<Object>(msgSizeRange);
-
+ payloads = new ArrayList<byte[]>(msgSizeRange);
+
for (int i=0; i < msgSizeRange; i++)
{
- payloads.add(createPayload(i));
+ payloads.add(MessageFactory.createMessagePayload(i).getBytes());
}
- }
+ }
else
{
- payload = createPayload(params.getMsgSize());
+ payload = MessageFactory.createMessagePayload(params.getMsgSize()).getBytes();
}
producer = session.createProducer(dest);
- System.out.println("Producer: " + id + " Sending messages to: " + ((AMQDestination)dest).getQueueName());
producer.setDisableMessageID(params.isDisableMessageID());
producer.setDisableMessageTimestamp(params.isDisableTimestamp());
-
- MapMessage m = controllerSession.createMapMessage();
- m.setInt(CODE, OPCode.REGISTER_PRODUCER.ordinal());
- sendMessageToController(m);
- }
-
- Object createPayload(int size)
- {
- if (msgType == MessageType.TEXT)
- {
- return MessageFactory.createMessagePayload(size);
- }
- else
- {
- return MessageFactory.createMessagePayload(size).getBytes();
- }
- }
-
- Message createMessage(Object payload) throws Exception
- {
- if (msgType == MessageType.TEXT)
- {
- return session.createTextMessage((String)payload);
- }
- else
- {
- BytesMessage m = session.createBytesMessage();
- m.writeBytes((byte[])payload);
- return m;
- }
}
protected Message getNextMessage() throws Exception
@@ -164,130 +117,117 @@ public class PerfProducer extends PerfBase
return msg;
}
else
- {
- Message m;
-
+ {
+ msg = session.createBytesMessage();
+
if (!randomMsgSize)
{
- m = createMessage(payload);
+ ((BytesMessage)msg).writeBytes(payload);
}
else
{
- m = createMessage(payloads.get(random.nextInt(msgSizeRange)));
+ ((BytesMessage)msg).writeBytes(payloads.get(random.nextInt(msgSizeRange)));
}
- m.setJMSDeliveryMode(durable?
+ msg.setJMSDeliveryMode(durable?
DeliveryMode.PERSISTENT :
DeliveryMode.NON_PERSISTENT
);
- return m;
+ return msg;
}
}
public void warmup()throws Exception
{
- receiveFromController(OPCode.PRODUCER_STARTWARMUP);
- System.out.println("Producer: " + id + " Warming up......");
+ System.out.println("Warming up......");
+ MessageConsumer tmp = session.createConsumer(feedbackDest);
for (int i=0; i < params.getWarmupCount() -1; i++)
{
producer.send(getNextMessage());
}
- sendEndMessage();
+ Message msg = session.createTextMessage("End");
+ msg.setJMSReplyTo(feedbackDest);
+ producer.send(msg);
+
+ if (params.isTransacted())
+ {
+ session.commit();
+ }
+
+ tmp.receive();
if (params.isTransacted())
{
session.commit();
}
+
+ tmp.close();
}
public void startTest() throws Exception
{
- resetCounters();
- receiveFromController(OPCode.PRODUCER_START);
+ System.out.println("Starting test......");
int count = params.getMsgCount();
boolean transacted = params.isTransacted();
int tranSize = params.getTransactionSize();
- long limit = (long)(params.getRate() * rateFactor); // in msecs
- long timeLimit = (long)(SEC * rateFactor); // in msecs
-
- long start = Clock.getTime(); // defaults to nano secs
- long interval = start;
+ long start = System.currentTimeMillis();
for(int i=0; i < count; i++ )
{
Message msg = getNextMessage();
- msg.setLongProperty(TIMESTAMP, Clock.getTime());
+ msg.setJMSTimestamp(System.currentTimeMillis());
producer.send(msg);
if ( transacted && ((i+1) % tranSize == 0))
{
session.commit();
}
-
- if (rateLimitProducer && i%limit == 0)
- {
- long elapsed = (Clock.getTime() - interval)*Clock.convertToMiliSecs(); // in msecs
- if (elapsed < timeLimit)
- {
- Thread.sleep(elapsed);
- }
- interval = Clock.getTime();
-
- }
- }
- sendEndMessage();
- if ( transacted)
- {
- session.commit();
}
- long time = Clock.getTime() - start;
- rate = (double)count*Clock.convertToSecs()/(double)time;
+ long time = System.currentTimeMillis() - start;
+ double rate = ((double)count/(double)time)*1000;
System.out.println(new StringBuilder("Producer rate: ").
append(df.format(rate)).
append(" msg/sec").
toString());
}
- public void resetCounters()
+ public void waitForCompletion() throws Exception
{
+ MessageConsumer tmp = session.createConsumer(feedbackDest);
+ Message msg = session.createTextMessage("End");
+ msg.setJMSReplyTo(feedbackDest);
+ producer.send(msg);
- }
+ if (params.isTransacted())
+ {
+ session.commit();
+ }
- public void sendEndMessage() throws Exception
- {
- Message msg = session.createMessage();
- msg.setBooleanProperty("End", true);
- producer.send(msg);
- }
+ tmp.receive();
- public void sendResults() throws Exception
- {
- MapMessage msg = controllerSession.createMapMessage();
- msg.setInt(CODE, OPCode.RECEIVED_PRODUCER_STATS.ordinal());
- msg.setDouble(PROD_RATE, rate);
- sendMessageToController(msg);
+ if (params.isTransacted())
+ {
+ session.commit();
+ }
+
+ tmp.close();
+ System.out.println("Consumer has completed the test......");
}
- @Override
public void tearDown() throws Exception
{
- super.tearDown();
+ producer.close();
+ session.close();
+ con.close();
}
- public void run()
+ public void test()
{
try
{
setUp();
warmup();
- boolean nextIteration = true;
- while (nextIteration)
- {
- System.out.println("=========================================================\n");
- System.out.println("Producer: " + id + " starting a new iteration ......\n");
- startTest();
- sendResults();
- nextIteration = continueTest();
- }
+ startTest();
+ waitForCompletion();
tearDown();
}
catch(Exception e)
@@ -296,63 +236,27 @@ public class PerfProducer extends PerfBase
}
}
- public void startControllerIfNeeded()
+
+ public static void main(String[] args)
{
- if (!params.isExternalController())
+ final PerfProducer prod = new PerfProducer();
+ Runnable r = new Runnable()
{
- final PerfTestController controller = new PerfTestController();
- Runnable r = new Runnable()
- {
- public void run()
- {
- controller.run();
- }
- };
-
- Thread t;
- try
+ public void run()
{
- t = Threading.getThreadFactory().createThread(r);
+ prod.test();
}
- catch(Exception e)
- {
- throw new Error("Error creating controller thread",e);
- }
- t.start();
+ };
+
+ Thread t;
+ try
+ {
+ t = Threading.getThreadFactory().createThread(r);
}
- }
-
-
- public static void main(String[] args) throws InterruptedException
- {
- String scriptId = (args.length == 1) ? args[0] : "";
- int conCount = Integer.getInteger("con_count",1);
- final CountDownLatch testCompleted = new CountDownLatch(conCount);
- for (int i=0; i < conCount; i++)
+ catch(Exception e)
{
- final PerfProducer prod = new PerfProducer(scriptId + i);
- prod.startControllerIfNeeded();
- Runnable r = new Runnable()
- {
- public void run()
- {
- prod.run();
- testCompleted.countDown();
- }
- };
-
- Thread t;
- try
- {
- t = Threading.getThreadFactory().createThread(r);
- }
- catch(Exception e)
- {
- throw new Error("Error creating producer thread",e);
- }
- t.start();
+ throw new Error("Error creating producer thread",e);
}
- testCompleted.await();
- System.out.println("Producers have completed the test......");
+ t.start();
}
} \ No newline at end of file
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfTestController.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfTestController.java
deleted file mode 100644
index 5c98c645f4..0000000000
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfTestController.java
+++ /dev/null
@@ -1,422 +0,0 @@
-package org.apache.qpid.tools;
-
-import java.io.FileWriter;
-import java.util.Collection;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-
-import javax.jms.MapMessage;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageListener;
-import javax.jms.MessageProducer;
-
-import org.apache.qpid.client.message.AMQPEncodedMapMessage;
-
-/**
- * The Controller coordinates a test run between a number
- * of producers and consumers, configured via -Dprod_count and -Dcons_count.
- *
- * It waits till all the producers and consumers have registered and then
- * conducts a warmup run. Once all consumers and producers have completed
- * the warmup run and is ready, it will conduct the actual test run and
- * collect all stats from the participants and calculates the system
- * throughput, the avg/min/max for producer rates, consumer rates and latency.
- *
- * These stats are then printed to std out.
- * The Controller also prints events to std out to give a running account
- * of the test run in progress. Ex registering of participants, starting warmup ..etc.
- * This allows a scripting tool to monitor the progress.
- *
- * The Controller can be run in two modes.
- * 1. A single test run (default) where it just runs until the message count specified
- * for the producers via -Dmsg_count is sent and received.
- *
- * 2. Time based, configured via -Dduration=x, where x is in mins.
- * In this mode, the Controller repeatedly cycles through the tests (after an initial
- * warmup run) until the desired time is reached. If a test run is in progress
- * and the time is up, it will allow the run the complete.
- *
- * After each iteration, the stats will be printed out in csv format to a separate log file.
- * System throughput is calculated as follows
- * totalMsgCount/(totalTestTime)
- */
-public class PerfTestController extends PerfBase implements MessageListener
-{
- enum TestMode { SINGLE_RUN, TIME_BASED };
-
- TestMode testMode = TestMode.SINGLE_RUN;
-
- long totalTestTime;
-
- private double avgSystemLatency = 0.0;
- private double minSystemLatency = Double.MAX_VALUE;
- private double maxSystemLatency = 0;
- private double avgSystemLatencyStdDev = 0.0;
-
- private double avgSystemConsRate = 0.0;
- private double maxSystemConsRate = 0.0;
- private double minSystemConsRate = Double.MAX_VALUE;
-
- private double avgSystemProdRate = 0.0;
- private double maxSystemProdRate = 0.0;
- private double minSystemProdRate = Double.MAX_VALUE;
-
- private long totalMsgCount = 0;
- private double totalSystemThroughput = 0.0;
-
- private int consumerCount = Integer.getInteger("cons_count", 1);
- private int producerCount = Integer.getInteger("prod_count", 1);
- private int duration = Integer.getInteger("duration", -1); // in mins
- private Map<String,MapMessage> consumers;
- private Map<String,MapMessage> producers;
-
- private CountDownLatch consRegistered;
- private CountDownLatch prodRegistered;
- private CountDownLatch consReady;
- private CountDownLatch prodReady;
- private CountDownLatch receivedEndMsg;
- private CountDownLatch receivedConsStats;
- private CountDownLatch receivedProdStats;
-
- private MessageConsumer consumer;
- private boolean printStdDev = false;
- FileWriter writer;
-
- public PerfTestController()
- {
- super("");
- consumers = new ConcurrentHashMap<String,MapMessage>(consumerCount);
- producers = new ConcurrentHashMap<String,MapMessage>(producerCount);
-
- consRegistered = new CountDownLatch(consumerCount);
- prodRegistered = new CountDownLatch(producerCount);
- consReady = new CountDownLatch(consumerCount);
- prodReady = new CountDownLatch(producerCount);
- printStdDev = params.isPrintStdDev();
- testMode = (duration == -1) ? TestMode.SINGLE_RUN : TestMode.TIME_BASED;
- }
-
- public void setUp() throws Exception
- {
- super.setUp();
- if (testMode == TestMode.TIME_BASED)
- {
- writer = new FileWriter("stats-csv.log");
- }
- consumer = controllerSession.createConsumer(controllerQueue);
- System.out.println("\nController: " + producerCount + " producers are expected");
- System.out.println("Controller: " + consumerCount + " consumers are expected \n");
- consumer.setMessageListener(this);
- consRegistered.await();
- prodRegistered.await();
- System.out.println("\nController: All producers and consumers have registered......\n");
- }
-
- public void warmup() throws Exception
- {
- System.out.println("Controller initiating warm up sequence......");
- sendMessageToNodes(OPCode.CONSUMER_STARTWARMUP,consumers.values());
- sendMessageToNodes(OPCode.PRODUCER_STARTWARMUP,producers.values());
- prodReady.await();
- consReady.await();
- System.out.println("\nController : All producers and consumers are ready to start the test......\n");
- }
-
- public void startTest() throws Exception
- {
- resetCounters();
- System.out.println("\nController Starting test......");
- long start = Clock.getTime();
- sendMessageToNodes(OPCode.PRODUCER_START,producers.values());
- receivedEndMsg.await();
- totalTestTime = Clock.getTime() - start;
- sendMessageToNodes(OPCode.CONSUMER_STOP,consumers.values());
- receivedProdStats.await();
- receivedConsStats.await();
- }
-
- public void resetCounters()
- {
- minSystemLatency = Double.MAX_VALUE;
- maxSystemLatency = 0;
- maxSystemConsRate = 0.0;
- minSystemConsRate = Double.MAX_VALUE;
- maxSystemProdRate = 0.0;
- minSystemProdRate = Double.MAX_VALUE;
-
- totalMsgCount = 0;
-
- receivedConsStats = new CountDownLatch(consumerCount);
- receivedProdStats = new CountDownLatch(producerCount);
- receivedEndMsg = new CountDownLatch(producerCount);
- }
-
- public void calcStats() throws Exception
- {
- double totLatency = 0.0;
- double totStdDev = 0.0;
- double totalConsRate = 0.0;
- double totalProdRate = 0.0;
-
- MapMessage conStat = null; // for error handling
- try
- {
- for (MapMessage m: consumers.values())
- {
- conStat = m;
- minSystemLatency = Math.min(minSystemLatency,m.getDouble(MIN_LATENCY));
- maxSystemLatency = Math.max(maxSystemLatency,m.getDouble(MAX_LATENCY));
- totLatency = totLatency + m.getDouble(AVG_LATENCY);
- totStdDev = totStdDev + m.getDouble(STD_DEV);
-
- minSystemConsRate = Math.min(minSystemConsRate,m.getDouble(CONS_RATE));
- maxSystemConsRate = Math.max(maxSystemConsRate,m.getDouble(CONS_RATE));
- totalConsRate = totalConsRate + m.getDouble(CONS_RATE);
-
- totalMsgCount = totalMsgCount + m.getLong(MSG_COUNT);
- }
- }
- catch(Exception e)
- {
- System.out.println("Error calculating stats from Consumer : " + conStat);
- }
-
-
- MapMessage prodStat = null; // for error handling
- try
- {
- for (MapMessage m: producers.values())
- {
- prodStat = m;
- minSystemProdRate = Math.min(minSystemProdRate,m.getDouble(PROD_RATE));
- maxSystemProdRate = Math.max(maxSystemProdRate,m.getDouble(PROD_RATE));
- totalProdRate = totalProdRate + m.getDouble(PROD_RATE);
- }
- }
- catch(Exception e)
- {
- System.out.println("Error calculating stats from Producer : " + conStat);
- }
-
- avgSystemLatency = totLatency/consumers.size();
- avgSystemLatencyStdDev = totStdDev/consumers.size();
- avgSystemConsRate = totalConsRate/consumers.size();
- avgSystemProdRate = totalProdRate/producers.size();
-
- System.out.println("Total test time : " + totalTestTime + " in " + Clock.getPrecision());
-
- totalSystemThroughput = (totalMsgCount*Clock.convertToSecs()/totalTestTime);
- }
-
- public void printResults() throws Exception
- {
- System.out.println(new StringBuilder("Total Msgs Received : ").append(totalMsgCount).toString());
- System.out.println(new StringBuilder("System Throughput : ").
- append(df.format(totalSystemThroughput)).
- append(" msg/sec").toString());
- System.out.println(new StringBuilder("Avg Consumer rate : ").
- append(df.format(avgSystemConsRate)).
- append(" msg/sec").toString());
- System.out.println(new StringBuilder("Min Consumer rate : ").
- append(df.format(minSystemConsRate)).
- append(" msg/sec").toString());
- System.out.println(new StringBuilder("Max Consumer rate : ").
- append(df.format(maxSystemConsRate)).
- append(" msg/sec").toString());
-
- System.out.println(new StringBuilder("Avg Producer rate : ").
- append(df.format(avgSystemProdRate)).
- append(" msg/sec").toString());
- System.out.println(new StringBuilder("Min Producer rate : ").
- append(df.format(minSystemProdRate)).
- append(" msg/sec").toString());
- System.out.println(new StringBuilder("Max Producer rate : ").
- append(df.format(maxSystemProdRate)).
- append(" msg/sec").toString());
-
- System.out.println(new StringBuilder("Avg System Latency : ").
- append(df.format(avgSystemLatency)).
- append(" ms").toString());
- System.out.println(new StringBuilder("Min System Latency : ").
- append(df.format(minSystemLatency)).
- append(" ms").toString());
- System.out.println(new StringBuilder("Max System Latency : ").
- append(df.format(maxSystemLatency)).
- append(" ms").toString());
- if (printStdDev)
- {
- System.out.println(new StringBuilder("Avg System Std Dev : ").
- append(avgSystemLatencyStdDev));
- }
- }
-
- private synchronized void sendMessageToNodes(OPCode code,Collection<MapMessage> nodes) throws Exception
- {
- System.out.println("\nController: Sending code " + code);
- MessageProducer tmpProd = controllerSession.createProducer(null);
- MapMessage msg = controllerSession.createMapMessage();
- msg.setInt(CODE, code.ordinal());
- for (MapMessage node : nodes)
- {
- if (node.getString(REPLY_ADDR) == null)
- {
- System.out.println("REPLY_ADDR is null " + node);
- }
- else
- {
- System.out.println("Controller: Sending " + code + " to " + node.getString(REPLY_ADDR));
- }
- tmpProd.send(controllerSession.createQueue(node.getString(REPLY_ADDR)), msg);
- }
- }
-
- public void onMessage(Message msg)
- {
- try
- {
- MapMessage m = (MapMessage)msg;
- OPCode code = OPCode.values()[m.getInt(CODE)];
-
- System.out.println("\n---------Controller Received Code : " + code);
- System.out.println("---------Data : " + ((AMQPEncodedMapMessage)m).getMap());
-
- switch (code)
- {
- case REGISTER_CONSUMER :
- if (consRegistered.getCount() == 0)
- {
- System.out.println("Warning : Expected number of consumers have already registered," +
- "ignoring extra consumer");
- break;
- }
- consumers.put(m.getString(ID),m);
- consRegistered.countDown();
- break;
-
- case REGISTER_PRODUCER :
- if (prodRegistered.getCount() == 0)
- {
- System.out.println("Warning : Expected number of producers have already registered," +
- "ignoring extra producer");
- break;
- }
- producers.put(m.getString(ID),m);
- prodRegistered.countDown();
- break;
-
- case CONSUMER_READY :
- consReady.countDown();
- break;
-
- case PRODUCER_READY :
- prodReady.countDown();
- break;
-
- case RECEIVED_END_MSG :
- receivedEndMsg.countDown();
- break;
-
- case RECEIVED_CONSUMER_STATS :
- consumers.put(m.getString(ID),m);
- receivedConsStats.countDown();
- break;
-
- case RECEIVED_PRODUCER_STATS :
- producers.put(m.getString(ID),m);
- receivedProdStats.countDown();
- break;
-
- default:
- throw new Exception("Invalid OPCode " + code);
- }
- }
- catch (Exception e)
- {
- handleError(e,"Error when receiving messages " + msg);
- }
- }
-
- public void run()
- {
- try
- {
- setUp();
- warmup();
- if (testMode == TestMode.SINGLE_RUN)
- {
- startTest();
- calcStats();
- printResults();
- }
- else
- {
- long startTime = Clock.getTime();
- long timeLimit = duration * 60 * 1000; // duration is in mins.
- boolean nextIteration = true;
- while (nextIteration)
- {
- startTest();
- calcStats();
- writeStatsToFile();
- if (Clock.getTime() - startTime < timeLimit)
- {
- sendMessageToNodes(OPCode.CONTINUE_TEST,consumers.values());
- sendMessageToNodes(OPCode.CONTINUE_TEST,producers.values());
- nextIteration = true;
- }
- else
- {
- nextIteration = false;
- }
- }
- }
- tearDown();
-
- }
- catch(Exception e)
- {
- handleError(e,"Error when running test");
- }
- }
-
- @Override
- public void tearDown() throws Exception {
- System.out.println("Controller: Completed the test......\n");
- if (testMode == TestMode.TIME_BASED)
- {
- writer.close();
- }
- sendMessageToNodes(OPCode.STOP_TEST,consumers.values());
- sendMessageToNodes(OPCode.STOP_TEST,producers.values());
- super.tearDown();
- }
-
- public void writeStatsToFile() throws Exception
- {
- writer.append(String.valueOf(totalMsgCount)).append(",");
- writer.append(df.format(totalSystemThroughput)).append(",");
- writer.append(df.format(avgSystemConsRate)).append(",");
- writer.append(df.format(minSystemConsRate)).append(",");
- writer.append(df.format(maxSystemConsRate)).append(",");
- writer.append(df.format(avgSystemProdRate)).append(",");
- writer.append(df.format(minSystemProdRate)).append(",");
- writer.append(df.format(maxSystemProdRate)).append(",");
- writer.append(df.format(avgSystemLatency)).append(",");
- writer.append(df.format(minSystemLatency)).append(",");
- writer.append(df.format(maxSystemLatency));
- if (printStdDev)
- {
- writer.append(",").append(String.valueOf(avgSystemLatencyStdDev));
- }
- writer.append("\n");
- writer.flush();
- }
-
- public static void main(String[] args)
- {
- PerfTestController controller = new PerfTestController();
- controller.run();
- }
-}
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java
index d73be0181b..89d6462a39 100644
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java
+++ b/qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java
@@ -25,25 +25,25 @@ import javax.jms.Session;
public class TestParams
{
/*
- * By default the connection URL is used.
+ * By default the connection URL is used.
* This allows a user to easily specify a fully fledged URL any given property.
* Ex. SSL parameters
- *
+ *
* By providing a host & port allows a user to simply override the URL.
* This allows to create multiple clients in test scripts easily,
- * without having to deal with the long URL format.
+ * without having to deal with the long URL format.
*/
private String url = "amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5672'";
-
+
private String host = "";
-
+
private int port = -1;
private String address = "queue; {create : always}";
private int msg_size = 1024;
- private int random_msg_size_start_from = 1;
+ private int msg_type = 1; // not used yet
private boolean cacheMessage = false;
@@ -62,28 +62,19 @@ public class TestParams
private int msg_count = 10;
private int warmup_count = 1;
-
+
private boolean random_msg_size = false;
- private String msgType = "bytes";
-
- private boolean printStdDev = false;
-
- private long rate = -1;
-
- private boolean externalController = false;
-
- private boolean useUniqueDest = false; // useful when using multiple connections.
-
public TestParams()
{
-
+
url = System.getProperty("url",url);
host = System.getProperty("host","");
port = Integer.getInteger("port", -1);
- address = System.getProperty("address",address);
+ address = System.getProperty("address","queue");
msg_size = Integer.getInteger("msg_size", 1024);
+ msg_type = Integer.getInteger("msg_type",1);
cacheMessage = Boolean.getBoolean("cache_msg");
disableMessageID = Boolean.getBoolean("disableMessageID");
disableTimestamp = Boolean.getBoolean("disableTimestamp");
@@ -94,12 +85,6 @@ public class TestParams
msg_count = Integer.getInteger("msg_count",msg_count);
warmup_count = Integer.getInteger("warmup_count",warmup_count);
random_msg_size = Boolean.getBoolean("random_msg_size");
- msgType = System.getProperty("msg_type","bytes");
- printStdDev = Boolean.getBoolean("print_std_dev");
- rate = Long.getLong("rate",-1);
- externalController = Boolean.getBoolean("ext_controller");
- useUniqueDest = Boolean.getBoolean("use_unique_dest");
- random_msg_size_start_from = Integer.getInteger("random_msg_size_start_from", 1);
}
public String getUrl()
@@ -137,9 +122,9 @@ public class TestParams
return msg_size;
}
- public int getRandomMsgSizeStartFrom()
+ public int getMsgType()
{
- return random_msg_size_start_from;
+ return msg_type;
}
public boolean isDurable()
@@ -176,39 +161,10 @@ public class TestParams
{
return disableTimestamp;
}
-
+
public boolean isRandomMsgSize()
{
return random_msg_size;
}
- public String getMessageType()
- {
- return msgType;
- }
-
- public boolean isPrintStdDev()
- {
- return printStdDev;
- }
-
- public long getRate()
- {
- return rate;
- }
-
- public boolean isExternalController()
- {
- return externalController;
- }
-
- public void setAddress(String addr)
- {
- address = addr;
- }
-
- public boolean isUseUniqueDests()
- {
- return useUniqueDest;
- }
}
diff --git a/qpid/java/upload.xml b/qpid/java/upload.xml
deleted file mode 100644
index 9f2fd6819b..0000000000
--- a/qpid/java/upload.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.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="upload" default="upload" xmlns:ivy="antlib:org.apache.ivy.ant">
- <description>Targets for uploading releases to ASF's Nexus instance</description>
-
- <property name="nexus.organisation" value="org.apache"/>
- <property name="nexus.host" value="repository.apache.org"/>
- <property name="nexus.upload.url" value="https://repository.apache.org/service/local/staging/deploy/maven2"/>
-
- <!-- properties for downloading ivy if required -->
- <property name="ivy.jar.dir" value="lib/ivy" />
- <property name="ivy.install.version" value="2.2.0" />
- <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy-${ivy.install.version}.jar" />
- <property name="ivy.repo.url" value="http://repo1.maven.org/maven2/org/apache/ivy/ivy"/>
-
- <target name="download-ivy">
- <mkdir dir="${ivy.jar.dir}"/>
- <!-- download Ivy from web site so that it can be used without any special installation -->
- <echo message="Downloading ivy..."/>
- <get src="${ivy.repo.url}/${ivy.install.version}/ivy-${ivy.install.version}.jar"
- dest="${ivy.jar.file}" usetimestamp="true"/>
- </target>
-
- <target name="load-ivy">
- <!-- Try to load Ivy from local ivy dir, in case the user has not already dropped it into
- Ant's lib dir (note that the latter copy will always take precedence). Won't
- fail so long as Ivy is in at least one of the locations. -->
- <mkdir dir="${ivy.jar.dir}"/>
- <path id="ivy.lib.path">
- <fileset dir="${ivy.jar.dir}" includes="*.jar"/>
- </path>
- <taskdef resource="org/apache/ivy/ant/antlib.xml"
- uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
- </target>
-
- <!-- check the following properties which must be specified by the user-->
- <target name="check-props-exist" description="check that the required properties have been set">
- <fail unless="nexus.user" message="You must supply the 'nexus.user' property"/>
- <fail unless="nexus.password" message="You must supply the 'nexus.password' property"/>
- <fail unless="maven.artifact.dir" message="You must supply the 'maven.artifact.dir' property"/>
- </target>
-
- <target name="perform-nexus-upload" description="really requires the prepare-upload target to be run first">
- <ivy:configure file="ivysettings-nexus.xml"/>
- <ivy:resolve file="ivy.xml"/>
- <ivy:retrieve/>
- <ivy:deliver/>
- <ivy:publish publishivy="false" resolver="nexus"
- artifactspattern="${maven.artifact.dir}/[organisation]/[module]/[artifact]/[revision]/[artifact]-[revision](-[classifier]).[ext]"/>
- </target>
-
- <target name="upload" depends="load-ivy, check-props-exist, perform-nexus-upload"/>
-
- <target name="help" description="display detailed build documentation">
- <echo>
-Ivy can be leveraged either by installing it in the Ant lib dir yourself,
-or by running the following command in qpid/java to place it in the
-qpid/java/lib/ivy lib folder:
-
- ant -buildfile upload.xml download-ivy
-
-The publishing task should be run once the release process has otherwise
-been completed and the artifacts signed. It can be performed from the
-qpid/java directory with a command as follows:
-
- ant -buildfile upload.xml -Dnexus.user=&lt;apache_username&gt; -Dnexus.password=&lt;password&gt;
- -Dmaven.artifact.dir=&lt;path to maven repo structure from release process&gt;
-
-Note: if you are behind a proxy server it is necessary to give Ant the
-proxy settings by doing something like:
-
-export ANT_OPTS=&quot;-Dhttp.proxyHost=&lt;host&gt; -Dhttp.proxyPort=&lt;port&gt; -Dhttps.proxyHost=&lt;host&gt; -Dhttps.proxyPort=&lt;port&gt;&quot;
- </echo>
- </target>
-</project>