summaryrefslogtreecommitdiff
path: root/RC9/qpid/java/management/client
diff options
context:
space:
mode:
Diffstat (limited to 'RC9/qpid/java/management/client')
-rw-r--r--RC9/qpid/java/management/client/README.txt117
-rwxr-xr-xRC9/qpid/java/management/client/bin/qman31
-rw-r--r--RC9/qpid/java/management/client/build.xml66
-rw-r--r--RC9/qpid/java/management/client/doc/man/qman17
-rw-r--r--RC9/qpid/java/management/client/etc/qman-config.xml47
-rw-r--r--RC9/qpid/java/management/client/etc/qman.log4j30
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java119
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java57
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java47
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/AccessModeMapping.java83
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerAlreadyConnectedException.java53
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java270
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.java137
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionException.java42
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java383
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/ConfigurationException.java51
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java287
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/IParser.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java90
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/QpidDatasource.java249
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.java51
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/TypeMapping.java90
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownAccessCodeException.java53
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownBrokerException.java43
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownTypeCodeException.java53
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/BaseMessageHandler.java54
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandler.java114
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/IMessageHandler.java52
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/ConfigurationMessageHandler.java57
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java51
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/HeartBeatIndicationMessageHandler.java39
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/IMethodInvocationListener.java41
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InstrumentationMessageHandler.java57
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java157
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodOrEventDataTransferObject.java68
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodResponseMessageHandler.java106
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java217
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/AccessMode.java33
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/Direction.java33
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java239
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/IValidator.java38
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/InvocationEvent.java76
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java348
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/MissingFeatureAttributesException.java35
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java82
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidAttribute.java105
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java768
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java158
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java456
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java88
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java454
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java147
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java279
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java295
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java34
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java51
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java105
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/AbsTime.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java151
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Boolean.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/DeltaTime.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Double.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Float.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int16.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int32.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int64.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int8.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/ObjectReference.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str16.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str8.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Type.java101
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint16.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint32.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint64.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint8.java44
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uuid.java46
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java177
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.java231
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MessageTokenizer.java152
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MethodInvocationException.java50
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java365
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java360
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/SequenceNumberGenerator.java41
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/StartupFailureException.java42
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/UnableToComplyException.java31
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java178
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/ManagementMessage.java189
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/MethodInvocationRequestMessage.java161
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/SchemaRequestMessage.java68
-rw-r--r--RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManServlet.java66
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java64
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java229
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java164
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/MappingParsersTest.java79
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandlerTest.java59
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseDomainModelTestCase.java44
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseQpidFeatureBuilderTestCase.java96
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/DomainModelTest.java55
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/OptionalPropertiesTest.java187
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java408
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java293
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidMethodBuilderTest.java147
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidNumberPropertyTest.java171
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPackageTest.java53
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPropertyBuilderTest.java269
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStatisticBuilderTest.java159
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStringPropertyTest.java127
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/type/BinaryTest.java59
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java241
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/MessageTokenizerTest.java140
-rw-r--r--RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/online/BaseOnlineTestCase.java58
-rw-r--r--RC9/qpid/java/management/client/web.xml32
113 files changed, 13638 insertions, 0 deletions
diff --git a/RC9/qpid/java/management/client/README.txt b/RC9/qpid/java/management/client/README.txt
new file mode 100644
index 0000000000..0c2a702a46
--- /dev/null
+++ b/RC9/qpid/java/management/client/README.txt
@@ -0,0 +1,117 @@
+1)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).
+The following README content could be read also in http://cwiki.apache.org/confluence/display/qpid/Qman+Tool
+
+2)HOW TO RUN Q-Man
+
+2.1)PREREQUISITES
+QMan is a standalone application that is packaged as qpid-management-client-<version>.jar. To run QMan you need to add the following jars in your CLASSPATH:
+
+log4j-1.2.12.jar
+slf4j-api-1.4.0.jar
+slf4j-log4j12-1.4.0.jar
+commons-pool-1.4.jar
+commons-codec-1.3.jar
+commons-lang-2.2.jar
+commons-collections-3.2.jar
+commons-configuration-1.2.jar
+qpid-client-<version>.jar (were <version> is the current qpid version)
+qpid-common-<version>.jar (were <version> is the current qpid version)
+
+alternatively you can run the following script (that add all the qpid jars to the CLASSPATH):
+
+> CLASSPATH=`find <lib-root> -name '*.jar' | tr '\n' ":"`
+
+Where <lib-root> is the directory containing the qpid jars (when qpid is built from source <lib-root> is equal to qpid/java/build/lib)
+
+You should have in your classpath a log4j.xml configuration file too with a category defined as this :
+
+<category name="org.apache.qpid.management">
+<priority value="INFO"/>
+</category>
+
+2.2) CONFIGURATION
+QMan can be connected at run time against any broker. However if you wish to automatically connect to one or several brokers you can do so by providing a configuration file as follows:
+
+<configuration>
+ <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>myhost</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>
+</configuration>
+The configuration above specifies that QMan should connect to two brokers, one on localhos and one on myhost, both listening on port 5672.
+
+The configuration file to use is specified through the JVM parameter "qman-config" that must point onto a valid configuration file.
+
+2.3)RUNNING Q-Man
+
+To run QMan in a console run the following command:
+
+> java -Dcom.sun.management.jmxremote org.apache.qpid.management.domain.services.QMan
+
+Messages similar to those should be displayed:
+
+... [org.apache.qpid.management.domain.services.QMan] <QMAN-000001> : Starting Q-Man...
+...
+Type "q" to quit.
+
+if you wish to use a configuration file <home>/myconfiguration.xml so QMan establishes a connection with one or several brokers, run the following command:
+
+java -Dqman-config="<home>/myconfiguration.xml" org.apache.qpid.management.domain.services.QMan
+
+
+2.4) STOPPING Q-Man
+Type "q" In the console from which QMan has been started.
+
+3) Browsing Manageable Beans using JConsole
+The jconsole tool (JMX-compliant graphical tool for monitoring a Java virtual machine) can be used for monitoring and QMan Mbeans. for more information see http://java.sun.com/javase/6/docs/technotes/guides/management/jconsole.html
+
+The jconsole executable can be found in JDK_HOME/bin, where JDK_HOME is the directory in which the JDK software is installed. If this directory is in your system path, you can start JConsole by simply typing jconsole in a console. Otherwise, you have to type the full path to the executable file.
+
+As jconsole needs to perform operations invocation you will need to add the QMan jar in jconsole classpath. In a console type:
+
+jconsole -J-Djava.class.path=$CLASSPATH:$JAVA_HOME/lib/jconsole.jar:$JAVA_HOME/lib/tools.jar
+Where CLASSPATH contains the QMan jars and JAVA_HOME point on your JDK home.
+
+NOte that in order to see QMan JVM on JConsole you need to add the following command line option to QMan launcher : -Dcom.sun.management.jmxremote
+
+4) Deploying Q-Man on JBoss
+QMan comes with a servlet that can be deployed in any application server. In the following we show how to deploy the qman servlet within JBoss application server.
+
+4.1) PREREQUISITES
+You mus install JBoss:
+
+- Download the latest stable version from: http://www.jboss.org/jbossas/downloads/
+- Unzip the download archive in <jboss-home>
+
+4.2) Deploying
+First you need to copy the provided qman.war in <jboss-home>/server/default/deploy/ (note that you can use another server configuration like for example minimal)
+
+Then run JBoss:
+
+Add the following option-Djboss.platform.mbeanserver to JAVA_OPTS (for example: export JAVA_OPTS=-Djboss.platform.mbeanserver)
+Execute <jboss-home>/binrun.sh (or run.bat on a windows platform)
+Notes:
+
+If you wish to configure QMan via a configuration file so QMan establishes a connection with one or several broker at starting time then add the options -Dqman-config=myconfigFile.xml to JAVA_OPTS.
+When Qpid is built form source, the war archive qman.war is located in qpid/java/build/management/client/servlet
+
+Enjoy!
diff --git a/RC9/qpid/java/management/client/bin/qman b/RC9/qpid/java/management/client/bin/qman
new file mode 100755
index 0000000000..7352bb0388
--- /dev/null
+++ b/RC9/qpid/java/management/client/bin/qman
@@ -0,0 +1,31 @@
+#!/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.
+#
+
+if [ "$QPID_LIB_PATH" = "" ] ; then
+ QPID_LIB_PATH=/usr/share/java
+fi
+
+if [ "$QPID_CONFIG_PATH" = "" ] ; then
+ QPID_CONFIG_PATH=/etc
+fi
+
+QMAN_CLASSPATH=`find $QPID_LIB_PATH | tr '\n' ":"`
+
+java -cp $QMAN_CLASSPATH -Dcom.sun.management.jmxremote -Dlog4j.configuration=qman.log4j -Dqman-config=$QPID_CONFIG_PATH/qman-config.xml org.apache.qpid.management.domain.services.QMan
diff --git a/RC9/qpid/java/management/client/build.xml b/RC9/qpid/java/management/client/build.xml
new file mode 100644
index 0000000000..bf32233214
--- /dev/null
+++ b/RC9/qpid/java/management/client/build.xml
@@ -0,0 +1,66 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<project name="Qpid Management Client" default="build">
+
+ <property name="module.depends" value="client common"/>
+
+ <import file="../../module.xml"/>
+
+
+ <property name="servlet.war" value="qman.war"/>
+ <property name="servlet.root" value="${module.build}/servlet"/>
+ <property name="servlet.web-inf" value="${servlet.root}/WEB-INF"/>
+ <property name="servlet.classes" value="${servlet.web-inf}/classes"/>
+
+
+ <target name="servlet-prepare">
+ <mkdir dir="${servlet.root}"/>
+ <mkdir dir="${servlet.web-inf}"/>
+ <mkdir dir="${servlet.classes}"/>
+ <copy file="./web.xml" todir="${servlet.web-inf}" verbose="false"/>
+ <copy todir="${servlet.classes}" verbose="false">
+ <fileset dir="${module.classes}">
+ <include name="org/apache/qpid/management/servlet/*"/>
+ </fileset>
+ </copy>
+ <copy todir="${servlet.web-inf}">
+ <fileset dir="${build}" includes="${module.libs}"/>
+ </copy>
+ <copy todir="${servlet.web-inf}/lib">
+ <fileset dir="${build}/lib">
+ <include name="qpid-client-*.jar"/>
+ <include name="qpid-common-*.jar"/>
+ <include name="qpid-management-client-*.jar"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="servlet-clean">
+ <delete dir="${servlet.root}"/>
+ </target>
+
+ <target name="servlet">
+ <jar destfile="${servlet.root}/${servlet.war}" basedir="${servlet.root}"/>
+ </target>
+
+ <target name="postbuild" depends="servlet-clean,servlet-prepare,servlet" description="run after a build"/>
+
+</project>
diff --git a/RC9/qpid/java/management/client/doc/man/qman b/RC9/qpid/java/management/client/doc/man/qman
new file mode 100644
index 0000000000..cf4f90845c
--- /dev/null
+++ b/RC9/qpid/java/management/client/doc/man/qman
@@ -0,0 +1,17 @@
+.TH qman
+.SH NAME
+qman 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 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 qma-config.xml from a different location, you can specify it using QPID_CONFIG_PATH 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/RC9/qpid/java/management/client/etc/qman-config.xml b/RC9/qpid/java/management/client/etc/qman-config.xml
new file mode 100644
index 0000000000..68ca3c6edf
--- /dev/null
+++ b/RC9/qpid/java/management/client/etc/qman-config.xml
@@ -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.
+ -
+ -->
+
+<configuration>
+ <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>myhost</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>
+</configuration>
diff --git a/RC9/qpid/java/management/client/etc/qman.log4j b/RC9/qpid/java/management/client/etc/qman.log4j
new file mode 100644
index 0000000000..c2d0b050bb
--- /dev/null
+++ b/RC9/qpid/java/management/client/etc/qman.log4j
@@ -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.
+#
+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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java
new file mode 100644
index 0000000000..579b00c2db
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java
@@ -0,0 +1,119 @@
+/*
+*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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
+{
+ // 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.";
+
+ // 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";
+
+ // 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)";
+
+ // 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_100008_MANAGEMENT_MESSAGE_HANDLER_NOT_AVAILABLE = "<QMAN-100008> : Management Message Handler configured for opcode %s is not available and therefore will be discarded.";
+ String QMAN_100009_METHOD_REPLY_MESSAGE_HANDLER_NOT_AVAILABLE = "<QMAN-100009> :Method-Reply Message Handler configured for opcode %s is not available and therefore will be discarded.";
+ 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.";
+
+ // MESSAGES
+ String EVENT_SEVERITY_ATTRIBUTE_DESCRIPTION = "Severity level for this event.";
+ String EVENT_TIMESTAMP_ATTRIBUTE_DESCRIPTION = "Current timestamp of this event.";
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java
new file mode 100644
index 0000000000..7ed0f8b24d
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.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;
+
+/**
+ * Enumeration of literal strings to avoid code duplication.
+ *
+ * @author Andrea Gazzarini
+ */
+public interface Names
+{
+ /** Name of the qpid management exchange. */
+ String MANAGEMENT_EXCHANGE = "qpid.management";
+ String MANAGEMENT_ROUTING_KEY = "console.#";
+
+ String MANAGEMENT_QUEUE_PREFIX = "management.";
+ String METHOD_REPLY_QUEUE_PREFIX = "reply.";
+
+ String AMQ_DIRECT_QUEUE = "amq.direct";
+ String AGENT_ROUTING_KEY_PREFIX = "agent.";
+ String AGENT_ROUTING_KEY = AGENT_ROUTING_KEY_PREFIX+"1.0";
+
+ // Attributes
+ String PACKAGE = "package";
+ String CLASS = "class";
+ String OBJECT_ID="objectID";
+ String BROKER_ID = "brokerID";
+ String DOMAIN_NAME = "Q-MAN";
+
+ String ARG_COUNT_PARAM_NAME = "argCount";
+ String DEFAULT_PARAM_NAME ="default";
+
+ String NUMBER_VALIDATOR = "org.apache.qpid.management.domain.model.QpidProperty$NumberValidator";
+ String STRING_VALIDATOR = "org.apache.qpid.management.domain.model.QpidProperty$StringValidator";
+
+ String QMAN_CONFIG_OPTION_NAME = "qman-config";
+
+ String ADD_BROKER_OPERATION_NAME = "addBroker";
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java
new file mode 100644
index 0000000000..5b41785b11
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.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.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;
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/AccessModeMapping.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/AccessModeMapping.java
new file mode 100644
index 0000000000..af6aaa36bf
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/AccessModeMapping.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.configuration;
+
+import org.apache.qpid.management.domain.model.AccessMode;
+
+/**
+ * Class used to encapsulate a mapping between an access mode and a code.
+ *
+ * @author Andrea Gazzarini
+ */
+class AccessModeMapping
+{
+ private final int _code;
+ private final AccessMode _accessMode;
+
+ /**
+ * Builds a new access mode mapping with the given parameters.
+ *
+ * @param code the access code.
+ * @param accessMode the access mode.
+ */
+ AccessModeMapping(int code, AccessMode accessMode)
+ {
+ this._code = code;
+ this._accessMode = accessMode;
+ }
+
+ /**
+ * Returns the access mode of this mapping.
+ *
+ * @return the access mode of this mapping.
+ */
+ AccessMode getAccessMode ()
+ {
+ return _accessMode;
+ }
+
+ /**
+ * Returns the code of this mapping.
+ *
+ * @return the code of this mapping.
+ */
+ int getCode ()
+ {
+ return _code;
+ }
+
+ /**
+ * Returns a string representation of this mapping.
+ * The returned string is indicating the code and the corresponding access mode.
+ *
+ * @return a string representation of this mapping.
+ */
+ @Override
+ public String toString ()
+ {
+ return new StringBuilder()
+ .append("AccessMode mapping (")
+ .append(_code)
+ .append(',')
+ .append(_accessMode)
+ .append(')').toString();
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerAlreadyConnectedException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerAlreadyConnectedException.java
new file mode 100644
index 0000000000..f23bf9d25e
--- /dev/null
+++ b/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java
new file mode 100644
index 0000000000..be04c67555
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java
@@ -0,0 +1,270 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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 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.
+ */
+ 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) {
+ try
+ {
+ BrokerConnectionData connectionData = (BrokerConnectionData) object;
+ return (_host.equals(connectionData._host) )
+ && (_port == connectionData._port)
+ && (_virtualHost.equals(connectionData._virtualHost));
+ } catch (Exception exception) {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return _host.hashCode()+_port+_virtualHost.hashCode();
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.java
new file mode 100644
index 0000000000..368970af00
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.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.management.configuration;
+
+import java.util.UUID;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Parser used for building access mode mappings.
+ * For each access-mode-mappings/mapping element found in the configuration file, a new access mode mapping
+ * is built and injected into the bridge configuration.
+ *
+ <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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionException.java
new file mode 100644
index 0000000000..9294cf740e
--- /dev/null
+++ b/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java
new file mode 100644
index 0000000000..12b3c6be9e
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java
@@ -0,0 +1,383 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.concurrent.BlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+
+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.handler.impl.InvocationResult;
+import org.apache.qpid.management.domain.model.AccessMode;
+import org.apache.qpid.management.domain.model.type.Type;
+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.
+ *
+ * @author Andrea Gazzarini
+ */
+public final class Configuration
+{
+ private final static Logger LOGGER = Logger.get(Configuration.class);
+ private static Configuration INSTANCE = new Configuration();
+
+ 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, String> _managementQueueHandlers = new HashMap<Character, String>();
+ Map<Character, String> _methodReplyQueueHandlers = new HashMap<Character, String>();
+
+ private String _managementQueueName;
+ private String _methodReplyQueueName;
+
+ private Header _headerForCommandMessages;
+ private DeliveryProperties _deliveryProperties = new DeliveryProperties();
+ private MessageProperties _messageProperties = new MessageProperties();
+ public BlockingQueue<InvocationResult> _resultExchangeChannel = new SynchronousQueue<InvocationResult>();
+
+ // Private constructor.
+ private Configuration()
+ {
+ defineQueueNames();
+ createHeaderForCommandMessages();
+ }
+
+ /**
+ * Returns the singleton instance.
+ *
+ * @return the singleton instance.
+ */
+ public static Configuration getInstance ()
+ {
+ return INSTANCE;
+ }
+
+ /**
+ * Returns true if this configuration has at least one broker connection data.
+ *
+ * @return true if this configuration has at least one broker connection data.
+ */
+ 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()
+ {
+ Map<Character, IMessageHandler> result = new HashMap<Character, IMessageHandler>();
+
+ for (Entry<Character, String> entry : _managementQueueHandlers.entrySet())
+ {
+ Character opcode = entry.getKey();
+ String className = entry.getValue();
+ try
+ {
+ result.put(opcode, (IMessageHandler)Class.forName(className).newInstance());
+ } catch(Exception exception)
+ {
+ LOGGER.error(exception,Messages.QMAN_100008_MANAGEMENT_MESSAGE_HANDLER_NOT_AVAILABLE,opcode);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * 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()
+ {
+ Map<Character, IMessageHandler> result = new HashMap<Character, IMessageHandler>();
+
+ for (Entry<Character, String> entry : _methodReplyQueueHandlers.entrySet())
+ {
+ Character opcode = entry.getKey();
+ String className = entry.getValue();
+ try
+ {
+ result.put(opcode, (IMessageHandler)Class.forName(className).newInstance());
+ } catch(Exception exception)
+ {
+ LOGGER.error(exception,Messages.QMAN_100009_METHOD_REPLY_MESSAGE_HANDLER_NOT_AVAILABLE,opcode);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * 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 mapping the type mapping that will be added.
+ */
+ void addTypeMapping(TypeMapping mapping) {
+ int code = mapping.getCode();
+ Type type = mapping.getType();
+ String validatorClassName = mapping.getValidatorClassName();
+ _typeMappings.put(code, type);
+ _validators.put(type, validatorClassName);
+
+ LOGGER.info(Messages.QMAN_000005_TYPE_MAPPING_CONFIGURED, code,type,validatorClassName);
+ }
+
+ /**
+ * Adds a new access mode mapping to this configuration.
+ *
+ * @param mapping the mapping that will be added.
+ */
+ void addAccessModeMapping(AccessModeMapping mapping){
+ int code = mapping.getCode();
+ AccessMode accessMode = mapping.getAccessMode();
+ _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();
+ String handlerClass = mapping.getMessageHandlerClass();
+ _managementQueueHandlers.put(opcode, handlerClass);
+
+ LOGGER.info(Messages.QMAN_000007_MANAGEMENT_HANDLER_MAPPING_CONFIGURED, opcode,handlerClass);
+ }
+
+ /**
+ * 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();
+ String handlerClass = mapping.getMessageHandlerClass();
+ _methodReplyQueueHandlers.put(opcode, handlerClass);
+
+ LOGGER.info(Messages.QMAN_000008_METHOD_REPLY_HANDLER_MAPPING_CONFIGURED, opcode,handlerClass);
+ }
+
+ /**
+ * 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);
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/ConfigurationException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/ConfigurationException.java
new file mode 100644
index 0000000000..6eed515e11
--- /dev/null
+++ b/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java
new file mode 100644
index 0000000000..0051b19c99
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java
@@ -0,0 +1,287 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.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.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.Int16;
+import org.apache.qpid.management.domain.model.type.Int32;
+import org.apache.qpid.management.domain.model.type.Int64;
+import org.apache.qpid.management.domain.model.type.Int8;
+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.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.
+ *
+ * @author Andrea Gazzarini
+ */
+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 _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;
+ }
+ }
+ }
+
+ @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);
+ throw new ConfigurationException(String.format(Messages.QMAN_300004_INVALID_CONFIGURATION_FILE, initialConfigFileName));
+ }
+ }
+
+ addTypeMappings();
+ addAccessModeMappings();
+
+ 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 access mode mappings.
+ * An access mode mapping is an association between a code and an access mode.
+ */
+ private void addAccessModeMappings() {
+ Configuration configuration = Configuration.getInstance();
+ configuration.addAccessModeMapping(new AccessModeMapping(1,AccessMode.RC));
+ configuration.addAccessModeMapping(new AccessModeMapping(2,AccessMode.RW));
+ configuration.addAccessModeMapping(new AccessModeMapping(3,AccessMode.RO));
+ }
+
+ /**
+ * Configures type mappings.
+ * A type mapping is an association between a code and a management type.
+ */
+ private void addTypeMappings()
+ {
+ Configuration configuration = Configuration.getInstance();
+ configuration.addTypeMapping(new TypeMapping(1,new Uint8(),Names.NUMBER_VALIDATOR));
+ configuration.addTypeMapping(new TypeMapping(2,new Uint16(),Names.NUMBER_VALIDATOR));
+ configuration.addTypeMapping(new TypeMapping(3,new Uint32(),Names.NUMBER_VALIDATOR));
+ configuration.addTypeMapping(new TypeMapping(4,new Uint64(),Names.NUMBER_VALIDATOR));
+ configuration.addTypeMapping(new TypeMapping(6,new Str8(),Names.STRING_VALIDATOR));
+ configuration.addTypeMapping(new TypeMapping(7,new Str16(),Names.STRING_VALIDATOR));
+ configuration.addTypeMapping(new TypeMapping(8,new AbsTime()));
+ configuration.addTypeMapping(new TypeMapping(9,new DeltaTime()));
+ configuration.addTypeMapping(new TypeMapping(10,new ObjectReference()));
+ configuration.addTypeMapping(new TypeMapping(11,new org.apache.qpid.management.domain.model.type.Boolean()));
+ configuration.addTypeMapping(new TypeMapping(12,new org.apache.qpid.management.domain.model.type.Float(),Names.NUMBER_VALIDATOR));
+ configuration.addTypeMapping(new TypeMapping(13,new org.apache.qpid.management.domain.model.type.Double(),Names.NUMBER_VALIDATOR));
+ configuration.addTypeMapping(new TypeMapping(14,new org.apache.qpid.management.domain.model.type.Uuid()));
+ configuration.addTypeMapping(new TypeMapping(15,new org.apache.qpid.management.domain.model.type.Map()));
+ configuration.addTypeMapping(new TypeMapping(16,new Int8(),Names.NUMBER_VALIDATOR));
+ configuration.addTypeMapping(new TypeMapping(17,new Int16(),Names.NUMBER_VALIDATOR));
+ configuration.addTypeMapping(new TypeMapping(18,new Int32(),Names.NUMBER_VALIDATOR));
+ configuration.addTypeMapping(new TypeMapping(19,new Int64(),Names.NUMBER_VALIDATOR));
+ }
+
+ /**
+ * Configures the mandatory management message handlers.
+ */
+ private void addMandatoryMethodReplyMessageHandlers ()
+ {
+ Configuration.getInstance().addMethodReplyMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.OPERATION_INVOCATION_RESPONSE_OPCODE,
+ MethodResponseMessageHandler.class.getName()));
+
+ Configuration.getInstance().addMethodReplyMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.SCHEMA_RESPONSE_OPCODE,
+ SchemaResponseMessageHandler.class.getName()));
+ }
+
+ /**
+ * Configures the mandatory management message handlers.
+ */
+ private void addMandatoryManagementMessageHandlers ()
+ {
+ Configuration.getInstance().addManagementMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.INSTRUMENTATION_CONTENT_RESPONSE_OPCODE,
+ InstrumentationMessageHandler.class.getName()));
+
+ Configuration.getInstance().addManagementMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.CONFIGURATION_CONTENT_RESPONSE_OPCDE,
+ ConfigurationMessageHandler.class.getName()));
+
+ Configuration.getInstance().addManagementMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.EVENT_CONTENT_RESPONSE_OPCDE,
+ EventContentMessageHandler.class.getName()));
+
+ Configuration.getInstance().addManagementMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.HEARTBEAT_INDICATION_RESPONSE_OPCODE,
+ HeartBeatIndicationMessageHandler.class.getName()));
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/IParser.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/IParser.java
new file mode 100644
index 0000000000..a221686765
--- /dev/null
+++ b/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java
new file mode 100644
index 0000000000..5e38346a2d
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.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.management.configuration;
+
+/**
+ * Message Handler mapping used for associating an opcode with a message handler.
+ *
+ * @author Andrea Gazzarini
+ */
+class MessageHandlerMapping
+{
+ private Character _opcode;
+ private String _handlerClass;
+
+ /**
+ * Builds an empty message handler mapping.
+ */
+ MessageHandlerMapping()
+ {
+ }
+
+ /**
+ * Builds a new mapping with the given opcode and handler class.
+ *
+ * @param opcode the opcode.
+ * @param handlerClass the handler class.
+ */
+ MessageHandlerMapping(Character opcode, String handlerClass) {
+ this._opcode = opcode;
+ this._handlerClass = handlerClass;
+ }
+
+ /**
+ * Returns the opcode of this mapping.
+ *
+ * @return the code of this mapping.
+ */
+ Character getOpcode ()
+ {
+ return _opcode;
+ }
+
+ /**
+ * Sets the opcode for this mapping.
+ *
+ * @param codeAsString the opcode as a string.
+ */
+ void setOpcode (String codeAsString)
+ {
+ this._opcode = codeAsString.charAt(0);
+ }
+
+ /**
+ * Returns the message handler for this mapping.
+ *
+ * @return the message handler for this mapping.
+ */
+ String getMessageHandlerClass()
+ {
+ return _handlerClass;
+ }
+
+ /**
+ * Sets the message handler of this mapping.
+ *
+ * @param handlerClass the handler class as a string.
+ */
+ void setMessageHandlerClass(String handlerClass)
+ {
+ this._handlerClass = handlerClass;
+ }
+} \ No newline at end of file
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/QpidDatasource.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/QpidDatasource.java
new file mode 100644
index 0000000000..569a65a782
--- /dev/null
+++ b/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.java
new file mode 100644
index 0000000000..7ff23c9d13
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.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;
+
+/**
+ * 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"; }};
+
+ /**
+ * 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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/TypeMapping.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/TypeMapping.java
new file mode 100644
index 0000000000..2c0a460c1a
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/TypeMapping.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.management.configuration;
+
+import org.apache.qpid.management.domain.model.type.Type;
+
+/**
+ * Type Mapping used for associating a code with a management type.
+ *
+ * @author Andrea Gazzarini
+ */
+class TypeMapping
+{
+ private final int _code;
+ private final Type _type;
+ private final String _validatorClass;
+
+ /**
+ * Builds a new type mapping with the given parameters and no validator.
+ *
+ * @param code the code.
+ * @param type the management type.
+ */
+ TypeMapping(int code, Type type)
+ {
+ this(code,type,null);
+ }
+
+ /**
+ * Builds a new type mapping with the given parameters.
+ *
+ * @param code the code.
+ * @param type the management type.
+ * @param validatorClassName the class name of the validator to be used.
+ */
+ TypeMapping(int code, Type type, String validatorClassName)
+ {
+ this._code = code;
+ this._type = type;
+ this._validatorClass = validatorClassName;
+ }
+
+ /**
+ * Returns the code of this mapping.
+ *
+ * @return the code of this mapping.
+ */
+ int getCode ()
+ {
+ return _code;
+ }
+
+ /**
+ * Returns the type for this mapping.
+ *
+ * @return the type for this mapping.
+ */
+ Type getType ()
+ {
+ return _type;
+ }
+
+ /**
+ * Returns the validator class of this mapping.
+ *
+ * @return the validator class (as a string) of this mapping.
+ */
+ public String getValidatorClassName()
+ {
+ return _validatorClass;
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownAccessCodeException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownAccessCodeException.java
new file mode 100644
index 0000000000..b7f1c0a7ec
--- /dev/null
+++ b/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownBrokerException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownBrokerException.java
new file mode 100644
index 0000000000..5b08e09c24
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownBrokerException.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.configuration;
+
+import java.util.UUID;
+
+/**
+ * Thrown when someone requests connection data for an unknown broker.
+ *
+ * @author Andrea Gazzarini
+ */
+public class UnknownBrokerException extends Exception
+{
+ private static final long serialVersionUID = 4965395428832158924L;
+
+ /**
+ * Builds a new UnknownBrokerException with the given broker id.
+ *
+ * @param brokerId the broker identifier.
+ */
+ UnknownBrokerException(UUID brokerId)
+ {
+ super(String.valueOf(brokerId));
+ }
+} \ No newline at end of file
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownTypeCodeException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownTypeCodeException.java
new file mode 100644
index 0000000000..57005d21e5
--- /dev/null
+++ b/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/BaseMessageHandler.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandler.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/IMessageHandler.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/ConfigurationMessageHandler.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/HeartBeatIndicationMessageHandler.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/IMethodInvocationListener.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InstrumentationMessageHandler.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java
new file mode 100644
index 0000000000..d188d20976
--- /dev/null
+++ b/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodOrEventDataTransferObject.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodResponseMessageHandler.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java
new file mode 100644
index 0000000000..ee5efe2af6
--- /dev/null
+++ b/RC9/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;
+ }
+ } \ No newline at end of file
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/AccessMode.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/Direction.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/IValidator.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/IValidator.java
new file mode 100644
index 0000000000..1ede559145
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/IValidator.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.management.domain.model;
+
+/**
+ * Interface definition for attribute validators.
+ *
+ * @author Andrea Gazzarini
+ */
+interface IValidator
+{
+ /**
+ * 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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/InvocationEvent.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java
new file mode 100644
index 0000000000..d919fdacae
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java
@@ -0,0 +1,348 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.QpidManagedObject;
+import org.apache.qpid.management.domain.model.QpidEvent.QpidManagedEvent;
+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.
+ *
+ * @author Andrea Gazzarini
+ */
+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
+ {
+ ObjectName name = createQManName();
+ if (!_mxServer.isRegistered(name))
+ {
+ try {
+ _mxServer.registerMBean(qman, name);
+ } catch (Exception exception) {
+ throw new MBeanException(exception);
+ }
+ }
+ }
+
+ void registerEventInstance(
+ QpidManagedEvent 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);
+ }
+ }
+}
+
+ /**
+ * 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.
+ */
+ void registerObjectInstance(
+ QpidManagedObject 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);
+ }
+ }
+ }
+
+ /**
+ * 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.
+ */
+ void 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);
+ }
+ }
+ }
+
+ /**
+ * Removes (unregister) all events from MBean Server.
+ */
+ void unregisterEvents()
+ {
+ for (ObjectName name : getEventMBeans())
+ {
+ try
+ {
+ _mxServer.unregisterMBean(name);
+ } catch(Exception ignore)
+ {
+ }
+ }
+ }
+
+ Set<ObjectName> getEventMBeans()
+ {
+ return _mxServer.queryNames(createEventSearchName(),null);
+ }
+
+ /**
+ * Removes (unregister) all object instances from MBean Server.
+ */
+ 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 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);
+ }
+ }
+
+ /**
+ * Creates the QMan object name.
+ *
+ * @return the QMan object name.
+ */
+ private ObjectName createQManName()
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(':')
+ .append("Type=Service")
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/MissingFeatureAttributesException.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java
new file mode 100644
index 0000000000..1e90479c0b
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.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.domain.model;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.transport.codec.Encoder;
+import org.apache.qpid.transport.util.Logger;
+
+class QpidArgument extends QpidProperty
+{
+ private final static Logger LOGGER = Logger.get(QpidArgument.class);
+
+ private Object _defaultValue;
+
+ private Direction _direction;
+
+ public void setDirection(String code)
+ {
+ this._direction = Direction.valueOf(code);
+ }
+
+ public Direction getDirection()
+ {
+ return _direction;
+ }
+
+ public void setDefaultValue(Object defaultValue)
+ {
+ this._defaultValue = defaultValue;
+ }
+
+ public Object getDefaultValue()
+ {
+ return _defaultValue;
+ }
+
+ 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();
+ }
+
+ public void encode(Object value,Encoder encoder)
+ {
+ _type.encode(value, encoder);
+ LOGGER.debug(Messages.QMAN_200013_ARGUMENT_VALUE_ENCODED,value,_name,_type);
+ }
+
+ public Object decode(org.apache.qpid.transport.codec.Decoder decoder)
+ {
+ return _type.decode(decoder);
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidAttribute.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java
new file mode 100644
index 0000000000..c7dfcb033c
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java
@@ -0,0 +1,768 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.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.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.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 2 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);
+ * 2) second state is when schema is injected. In this case 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).
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidClass extends QpidEntity
+{
+ /**
+ * 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 e)
+ {
+ _logger.error(
+ Messages.QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST,
+ _parent.getName(),
+ _name);
+ } finally {
+ QpidManagedObject 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 {
+ QpidManagedObject 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)
+ {
+ QpidManagedObject 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)
+ {
+ QpidManagedObject 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);
+
+ // Converting stored object instances into JMX MBean and removing raw instance data.
+ for (Entry<Binary, QpidManagedObject> instanceEntry : _objectInstances.entrySet())
+ {
+ Binary objectId = instanceEntry.getKey();
+ QpidManagedObject 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();
+ }
+
+ JMX_SERVICE.registerObjectInstance(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)
+ {
+ QpidManagedObject 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)
+ {
+ QpidManagedObject 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
+ *
+ * @author Andrea Gazzarini
+ */
+ class QpidManagedObject extends QpidManagedEntity 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.
+ */
+ QpidManagedObject(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
+ {
+ // TODO : Overloaded methods
+ QpidMethod method = _methods.get(actionName);
+ if (method != null)
+ {
+ try
+ {
+ method.validate(params);
+ return invokeMethod(_objectId, method, params);
+ } catch (Exception exception)
+ {
+ throw new MBeanException(exception);
+ }
+ } else {
+ 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
+ {
+ 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, QpidManagedObject> _objectInstances = new HashMap<Binary, QpidManagedObject>();
+ 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);
+ 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.
+ */
+ QpidManagedObject getObjectInstance(Binary objectId, boolean registration)
+ {
+ QpidManagedObject objectInstance = _objectInstances.get(objectId);
+ if (objectInstance == null)
+ {
+ objectInstance = new QpidManagedObject(objectId);
+ _objectInstances.put(objectId, objectInstance);
+ if (registration)
+ {
+ JMX_SERVICE.registerObjectInstance(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(QpidManagedObject 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(QpidManagedObject 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)
+ {
+ QpidManagedObject toBeRemoved = _objectInstances.remove(objectId);
+ if (toBeRemoved != null)
+ {
+ JMX_SERVICE.unregisterObjectInstance(_parent.getOwnerId(),_parent.getName(),_name,toBeRemoved._objectId);
+ }
+ }
+
+ /**
+ * Deregisters all the object instances and release all previously acquired resources.
+ */
+ void releaseResources ()
+ {
+ _objectInstances.clear();
+ JMX_SERVICE.unregisterObjectInstances();
+ _service.close();
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java
new file mode 100644
index 0000000000..59f8d807b2
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.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.domain.model;
+
+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.RuntimeOperationsException;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.management.domain.services.QpidService;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Layer supertype for QMan entities.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class QpidEntity
+{
+ /**
+ * Layer supertype for QMan managed bean entities.
+ *
+ * @author Andrea Gazzarini
+ */
+ abstract class QpidManagedEntity 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;
+
+ /**
+ * 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)
+ {
+ this._name = className;
+ this._parent = parentPackage;
+ this._hash = hash;
+ this._service = new QpidService(_parent.getOwnerId());
+
+ _logger.debug(
+ Messages.QMAN_200020_ENTITY_DEFINITION_HAS_BEEN_BUILT,
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name);
+ }
+
+ /**
+ * Internal method used to send a schema request for this entity.
+ *
+ * @throws Exception when the request cannot be sent.
+ */
+ void requestSchema() throws Exception
+ {
+ try
+ {
+ _service.connect();
+ _service.requestSchema(_parent.getName(), _name, _hash);
+ _service.sync();
+ } finally
+ {
+ _service.close();
+ }
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java
new file mode 100644
index 0000000000..273ae650c1
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java
@@ -0,0 +1,456 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.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 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.ReflectionException;
+import javax.management.RuntimeOperationsException;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.transport.codec.BBDecoder;
+
+/**
+ * Qpid event definition.
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidEvent extends QpidEntity
+{
+
+ /**
+ * State interface for this event definition.
+ * Each state is responsible to handle the injection of the data and / or schema.
+ *
+ * @author Andrea Gazzarini
+ */
+ 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 e)
+ {
+ _logger.error(
+ 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 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 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 (QpidManagedEvent instance : _eventInstances)
+ {
+ updateEventInstanceWithData(instance);
+ JMX_SERVICE.registerEventInstance(instance,_parent.getOwnerId(),_parent.getName(),_name);
+ }
+ _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 addNewEventData (byte[] rawData,long currentTimestamp, int severity)
+ {
+ QpidManagedEvent instance = createEventInstance(rawData,currentTimestamp, severity);
+ updateEventInstanceWithData(instance);
+ JMX_SERVICE.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 QpidManagedEvent extends QpidManagedEntity
+ {
+
+
+ // 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 QpidManagedEvent(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<QpidManagedEvent> _eventInstances = new LinkedList<QpidManagedEvent>();
+ 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);
+ }
+
+ /**
+ * 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.
+ */
+ QpidManagedEvent createEventInstance(byte [] data, long timestamp, int severity)
+ {
+ QpidManagedEvent eventInstance = new QpidManagedEvent(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(QpidManagedEvent 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();
+ _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();
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java
new file mode 100644
index 0000000000..e1ca5a4d42
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.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.domain.model;
+
+/**
+ * Layer Supertype for all qpid management features.
+ *
+ * @author Andrea Gazzarini
+ */
+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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java
new file mode 100644
index 0000000000..e9799cb147
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java
@@ -0,0 +1,279 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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)
+ {
+ QpidClassIdentity identity = (QpidClassIdentity) obj;
+ return name.equals(identity.name) && hash.equals(identity.hash);
+ }
+ }
+
+ 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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java
new file mode 100644
index 0000000000..37a652c098
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.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.domain.model;
+
+/**
+ * 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
+{
+ // EMPTY CLASS : Statistic metadata are all defined in superclasses.
+} \ No newline at end of file
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/AbsTime.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java
new file mode 100644
index 0000000000..8009150eb2
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.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.qpid.management.domain.model.type;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.UUID;
+
+import org.apache.qpid.management.messages.AmqpCoDec;
+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 = AmqpCoDec.unpack64(array);
+ uuid = UUID.randomUUID();
+ }
+
+ @Override
+ public int hashCode ()
+ {
+ return state.hashCode();
+ }
+
+ @Override
+ public boolean equals (Object obj)
+ {
+ try
+ {
+ Binary binary = (Binary)obj;
+ return Arrays.equals(_bytes, binary._bytes);
+ } catch (Exception exception)
+ {
+ 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;
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Boolean.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/DeltaTime.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Double.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Float.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int16.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int32.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int64.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int8.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java
new file mode 100644
index 0000000000..cc540ff4da
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.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 Map extends Type
+{
+ public Map()
+ {
+ super(java.util.Map.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readMap();
+ }
+
+ @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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/ObjectReference.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str16.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str8.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Type.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Type.java
new file mode 100644
index 0000000000..c455faaf2c
--- /dev/null
+++ b/RC9/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 getClass() == obj.getClass();
+ }
+
+ @Override
+ public int hashCode ()
+ {
+ return getClass().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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint16.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint32.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint64.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint8.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uuid.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java
new file mode 100644
index 0000000000..aa588043aa
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java
@@ -0,0 +1,177 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.java
new file mode 100644
index 0000000000..a3584571f3
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.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.management.domain.services;
+
+import java.util.UUID;
+
+import org.apache.qpid.QpidException;
+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
+ */
+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;
+
+ /**
+ * 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)
+ {
+ _service = new QpidService(brokerId);
+ _domainModel = new DomainModel(brokerId);
+ _managementQueueName = Configuration.getInstance().getManagementQueueName();
+ _methodReplyQueueName = Configuration.getInstance().getMethodReplyQueueName();
+ }
+
+ /**
+ * 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 () throws QpidException
+ {
+ 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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MessageTokenizer.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MethodInvocationException.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java
new file mode 100644
index 0000000000..600b54a6c9
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java
@@ -0,0 +1,365 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.Map.Entry;
+
+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.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.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QMan implements DynamicMBean
+{
+ private final static Logger LOGGER = Logger.get(QMan.class);
+ private final List<ManagementClient> managementClients = new ArrayList<ManagementClient>();
+
+ /**
+ * 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);
+
+ Configurator configurator = new Configurator();
+ try
+ {
+ configurator.configure();
+ Configuration configuration = Configuration.getInstance();
+ if (configuration.hasOneOrMoreBrokersDefined())
+ {
+ LOGGER.info(Messages.QMAN_000003_CREATING_MANAGEMENT_CLIENTS);
+ for (Entry<UUID, BrokerConnectionData> entry : Configuration.getInstance().getConnectionInfos())
+ {
+ createManagementClient(entry.getKey(), entry.getValue());
+ }
+ } else
+ {
+ LOGGER.info(Messages.QMAN_000022_NO_BROKER_CONFIGURED);
+ }
+
+ registerQManService();
+
+ LOGGER.info(Messages.QMAN_000019_QMAN_STARTED);
+ } catch(Exception exception) {
+ LOGGER.error(exception,Messages.QMAN_100018_UNABLE_TO_STARTUP_CORRECTLY );
+ throw new StartupFailureException(exception);
+ }
+ }
+
+ /**
+ * Creates a management client using the given data.
+ *
+ * @param brokerId the broker identifier.
+ * @param data the broker connection data.
+ */
+ private 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);
+ }
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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);
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java
new file mode 100644
index 0000000000..a12993d40e
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java
@@ -0,0 +1,360 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.QpidException;
+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 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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/SequenceNumberGenerator.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/StartupFailureException.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/UnableToComplyException.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java
new file mode 100644
index 0000000000..4d1dfe796a
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java
@@ -0,0 +1,178 @@
+/*
+*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.management.messages;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+
+/**
+ * AMQP Management messages codec.
+ *
+ * @author Andrea Gazzarini
+ */
+public class AmqpCoDec
+{
+ private byte [] _buffer;
+ private int _position;
+
+ /**
+ * Builds a new codec.
+ */
+ AmqpCoDec()
+ {
+ _buffer = new byte [1000];
+ _buffer[0] = 'A';
+ _buffer[1] = 'M';
+ _buffer[2] = '2';
+ _position = 3;
+ }
+
+
+ /**
+ * Int32-to-4 byte array marshalling.
+ * Marshalles an integer using four bytes.
+ *
+ * @param data the result array.
+ * @param pos the starting position of the array to be filled.
+ * @param value the value to be marshalled.
+ */
+ public final void pack32(int value) {
+ _buffer[_position++] = (byte) (value >> 24 & 0xff);
+ _buffer[_position++] = (byte) (value >> 16 & 0xff);
+ _buffer[_position++] = (byte) (value >> 8 & 0xff);
+ _buffer[_position++] = (byte) (value & 0xff);
+ }
+
+ /**
+ * Int32-to-4 byte array marshalling.
+ * Marshalles an integer using four bytes.
+ *
+ * @param data the result array.
+ * @param pos the starting position of the array to be filled.
+ * @param value the value to be marshalled.
+ */
+ public final void pack16(int value) {
+ _buffer[_position++] = (byte) (value >> 8 & 0xff);
+ _buffer[_position++] = (byte) (value & 0xff);
+ }
+
+ /**
+ * Int32-to-4 byte array marshalling.
+ * Marshalles an integer using four bytes.
+ *
+ * @param data the result array.
+ * @param pos the starting position of the array to be filled.
+ * @param value the value to be marshalled.
+ */
+ public final void pack64(long value) {
+ _buffer[_position++] = (byte) (value >> 56 & 0xff);
+ _buffer[_position++] = (byte) (value >> 48 & 0xff);
+ _buffer[_position++] = (byte) (value >> 40 & 0xff);
+ _buffer[_position++] = (byte) (value >> 32 & 0xff);
+ _buffer[_position++] = (byte) (value >> 24 & 0xff);
+ _buffer[_position++] = (byte) (value >> 16 & 0xff);
+ _buffer[_position++] = (byte) (value >> 8 & 0xff);
+ _buffer[_position++] = (byte) (value & 0xff);
+ }
+
+ /**
+ * Int32-to-byte array marshalling.
+ * Marshalles an integer using two bytes.
+ *
+ * @param data the result array.
+ * @param pos the starting position of the array to be filled.
+ * @param value the value to be marshalled.
+ */
+ public final void pack24(int value) {
+ _buffer[_position++] = (byte) (value >> 16 & 0xff);
+ _buffer[_position++] = (byte) (value >> 8 & 0xff);
+ _buffer[_position++] = (byte) (value & 0xff);
+ }
+
+ public final void pack8(int value) {
+ _buffer[_position++] = (byte) (value & 0xff);
+ }
+
+ public void pack8 (byte aByte)
+ {
+ _buffer[_position++] = aByte;
+ }
+
+ public void packStr8(String aString)
+ {
+ try
+ {
+ byte [] toBytes = aString.getBytes("UTF-8");
+ int length = toBytes.length;
+ pack8(length);
+ System.arraycopy(toBytes, 0, _buffer, _position, length);
+ _position+=length;
+ } catch (UnsupportedEncodingException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ public void packStr16(String aString)
+ {
+ try
+ {
+ byte [] toBytes = aString.getBytes("UTF-8");
+ int length = toBytes.length;
+ pack16(length);
+ System.arraycopy(toBytes, 0, _buffer, _position, length);
+ _position+=length;
+ } catch (UnsupportedEncodingException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ public static 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);
+ }
+
+
+ public void pack (byte[] bytes)
+ {
+ System.arraycopy(bytes, 0, _buffer, _position, bytes.length);
+ _position+=bytes.length;
+ }
+
+ /**
+ * Retruns the byte buffer that is wrapping the backing array of this codec.
+ *
+ * @return the byte buffer that is wrapping the backing array of this codec.
+ */
+ public ByteBuffer getEncodedBuffer ()
+ {
+ return ByteBuffer.wrap(_buffer,0,_position);
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/ManagementMessage.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/ManagementMessage.java
new file mode 100644
index 0000000000..2fa20fb456
--- /dev/null
+++ b/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/MethodInvocationRequestMessage.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/MethodInvocationRequestMessage.java
new file mode 100644
index 0000000000..99916085d6
--- /dev/null
+++ b/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/SchemaRequestMessage.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/SchemaRequestMessage.java
new file mode 100644
index 0000000000..9df1733649
--- /dev/null
+++ b/RC9/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/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManServlet.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManServlet.java
new file mode 100644
index 0000000000..f0d663701b
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManServlet.java
@@ -0,0 +1,66 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.servlet;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+
+import org.apache.qpid.management.domain.services.QMan;
+import org.apache.qpid.management.domain.services.StartupFailureException;
+
+/**
+ * QMan initializer.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QManServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 6149614872902682208L;
+
+ // QMan instance
+ private QMan qman;
+
+ /**
+ * Initializes QMan instance.
+ *
+ * @throws ServletException when It's not possibile to proceed with initialization.
+ */
+ @Override
+ public void init() throws ServletException
+ {
+ qman = new QMan();
+ try {
+ qman.start();
+ } catch (StartupFailureException exception)
+ {
+ throw new ServletException(exception);
+ }
+ }
+
+ /**
+ * Stops QMan instance.
+ */
+ @Override
+ public void destroy()
+ {
+ qman.stop();
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java
new file mode 100644
index 0000000000..5855a3e60b
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.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;
+
+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;
+
+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;
+}
diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java
new file mode 100644
index 0000000000..efd5990bd7
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java
@@ -0,0 +1,229 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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 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;
+import org.apache.qpid.management.domain.model.AccessMode;
+import org.apache.qpid.management.domain.model.type.Type;
+import org.apache.qpid.management.domain.model.type.Uint8;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for Configuration singleton.
+ *
+ * @author Andrea Gazzarini
+ */
+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 valid code is supplied.
+ *
+ * <br>precondition : the requested type already exist on the configuration.
+ * <br>postcondition : the requested type is returned and no exception is thrown.
+ */
+ public void testGetTypeOk() throws UnknownTypeCodeException
+ {
+ TypeMapping mapping = new TypeMapping(TestConstants.VALID_CODE,new Uint8());
+ Configuration.getInstance().addTypeMapping(mapping);
+ Type type = Configuration.getInstance().getType(TestConstants.VALID_CODE);
+
+ assertTrue(type instanceof Uint8);
+ }
+
+ /**
+ * 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(Integer.MIN_VALUE);
+ fail("If an unknwon code is supplied an exception must be thrown.");
+ } catch (UnknownTypeCodeException expected)
+ {
+ assertEquals(Integer.MIN_VALUE,expected.getCode());
+ }
+ }
+
+ /**
+ * Tests the execution of getAccessMode() method when a valid code is supplied.
+ *
+ * <br>precondition : the requested access mode already exist on the configuration.
+ * <br>postcondition : the requested access mode is returned and no exception is thrown.
+ */
+ public void testGetAccessModeOk() throws UnknownAccessCodeException
+ {
+ AccessModeMapping mapping = new AccessModeMapping(TestConstants.VALID_CODE,AccessMode.RW);
+ Configuration.getInstance().addAccessModeMapping(mapping);
+ AccessMode accessMode = Configuration.getInstance().getAccessMode(TestConstants.VALID_CODE);
+
+ assertSame(AccessMode.RW,accessMode);
+ }
+
+ /**
+ * 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(Integer.MIN_VALUE);
+ fail("If an unknwon code is supplied an exception must be thrown.");
+ } catch (UnknownAccessCodeException expected)
+ {
+ assertEquals(Integer.MIN_VALUE,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()
+ {
+ String i = "i";
+ String c = "c";
+
+ String instrMessageHandlerClassName = InstrumentationMessageHandler.class.getName();
+ String configMessageHandlerClassName = ConfigurationMessageHandler.class.getName();
+
+ MessageHandlerMapping instrMapping = new MessageHandlerMapping();
+ MessageHandlerMapping configMapping = new MessageHandlerMapping();
+
+ instrMapping.setOpcode(i);
+ instrMapping.setMessageHandlerClass(instrMessageHandlerClassName);
+
+ configMapping.setOpcode(c);
+ configMapping.setMessageHandlerClass(configMessageHandlerClassName);
+
+ Configuration.getInstance().addManagementMessageHandlerMapping(instrMapping);
+ Configuration.getInstance().addManagementMessageHandlerMapping(configMapping);
+
+ Map<Character, IMessageHandler> handlerMappings = Configuration.getInstance().getManagementQueueHandlers();
+
+ assertEquals(instrMessageHandlerClassName,handlerMappings.get(instrMapping.getOpcode()).getClass().getName());
+ assertEquals(configMessageHandlerClassName,handlerMappings.get(configMapping.getOpcode()).getClass().getName());
+ }
+
+ /**
+ * 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()
+ {
+ String s = "s";
+
+ String schemaMessageHandlerClassName = SchemaResponseMessageHandler.class.getName();
+
+ MessageHandlerMapping schemaMapping = new MessageHandlerMapping();
+
+ schemaMapping.setOpcode(s);
+ schemaMapping.setMessageHandlerClass(schemaMessageHandlerClassName);
+
+ Configuration.getInstance().addMethodReplyMessageHandlerMapping(schemaMapping);
+
+ Map<Character, IMessageHandler> handlerMappings = Configuration.getInstance().getMethodReplyQueueHandlers();
+
+ assertEquals(schemaMessageHandlerClassName,handlerMappings.get(schemaMapping.getOpcode()).getClass().getName());
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java
new file mode 100644
index 0000000000..6237f21cc9
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java
@@ -0,0 +1,164 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.Names;
+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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/MappingParsersTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/MappingParsersTest.java
new file mode 100644
index 0000000000..af261024bd
--- /dev/null
+++ b/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandlerTest.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseDomainModelTestCase.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseQpidFeatureBuilderTestCase.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/DomainModelTest.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/OptionalPropertiesTest.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java
new file mode 100644
index 0000000000..284f3841b8
--- /dev/null
+++ b/RC9/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.QpidManagedObject;
+
+/**
+ * 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));
+
+ QpidManagedObject 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;
+ QpidManagedObject 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(QpidManagedObject 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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java
new file mode 100644
index 0000000000..954a419787
--- /dev/null
+++ b/RC9/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.QpidManagedEvent;
+
+/**
+ * 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());
+
+ QpidManagedEvent 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(QpidManagedEvent 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 QpidManagedEvent 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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidMethodBuilderTest.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidNumberPropertyTest.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPackageTest.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPropertyBuilderTest.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStatisticBuilderTest.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStringPropertyTest.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/type/BinaryTest.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/MessageTokenizerTest.java b/RC9/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/RC9/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/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/online/BaseOnlineTestCase.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/online/BaseOnlineTestCase.java
new file mode 100644
index 0000000000..82a7a1698c
--- /dev/null
+++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/online/BaseOnlineTestCase.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.online;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
+import junit.framework.TestCase;
+
+/**
+ * Layer supertype for all online QMan test cases.
+ * Note that QMan must be running and up in order to run concrete subclasses (test cases).
+ *
+ * @author AGazzarini
+ */
+public abstract class BaseOnlineTestCase extends TestCase
+{
+ protected MBeanServerConnection connection;
+
+ /**
+ * Setup fixture for this test case.
+ * Basically it estabilishes a connection to QMan using RMI JMX connector.
+ */
+ @Override
+ protected void setUp ()
+ {
+ try
+ {
+ JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
+ JMXConnector jmxc = JMXConnectorFactory.connect(url);
+ connection = jmxc.getMBeanServerConnection();
+ } catch(Exception exception)
+ {
+ fail("QMan must be running and up in order to run this test!");
+ exception.printStackTrace();
+ }
+ }
+}
diff --git a/RC9/qpid/java/management/client/web.xml b/RC9/qpid/java/management/client/web.xml
new file mode 100644
index 0000000000..71ca74b2e5
--- /dev/null
+++ b/RC9/qpid/java/management/client/web.xml
@@ -0,0 +1,32 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app id="WebApp_ID" 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">
+ <display-name>QManEE</display-name>
+ <description>Web Application used for integrating QMan onto an Application Server.</description>
+ <servlet>
+ <display-name>QMan Servlet (Initializer)</display-name>
+ <servlet-name>QManServlet</servlet-name>
+ <servlet-class>org.apache.qpid.management.servlet.QManServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+</web-app>