summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/management/client/build.xml123
-rw-r--r--java/management/client/src/main/java/muse.xml10
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/Messages.java8
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/Names.java3
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java2
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObject.java307
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObjectMBean.java227
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java7
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmu.java124
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java92
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuMBean.java48
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java61
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java144
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java361
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java3
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMessageHandler.java103
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java6
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifacts.java45
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java3
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java171
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java11
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java25
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/DateSerializer.java75
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java1
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java24
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ObjectSerializer.java65
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/qman/debug/WsdlDebugger.java49
-rw-r--r--java/management/client/src/test/java/log4j.xml23
-rw-r--r--java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java5
-rw-r--r--java/management/client/src/test/java/org/apache/qpid/management/wsdm/EnhancedReflectionProxyHandler.java67
-rw-r--r--java/management/client/src/test/java/org/apache/qpid/management/wsdm/ServerThread.java82
-rw-r--r--java/management/client/src/test/java/org/apache/qpid/management/wsdm/WebApplicationLifeCycleListener.java52
-rw-r--r--java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java1026
-rw-r--r--java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilderTest.java278
-rw-r--r--java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityTest.java204
-rw-r--r--java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilderTest.java110
-rw-r--r--java/management/client/src/test/java/org/apache/qpid/management/wsdm/web.xml11
37 files changed, 3553 insertions, 403 deletions
diff --git a/java/management/client/build.xml b/java/management/client/build.xml
index aa215bbc24..4e595c69bf 100644
--- a/java/management/client/build.xml
+++ b/java/management/client/build.xml
@@ -20,22 +20,22 @@
-->
<project name="QMan - Qpid JMX / WS-DM Adapter" default="build">
- <property name="module.depends" value="client common systests"/>
+ <property name="module.depends" value="client common"/>
+ <property name="module.test.depends" value="client common"/>
+
<import file="../../module.xml"/>
<property name="war.name" value="qman.war"/>
<property name="build.root" value="${module.build}"/>
- <property name="web.module" value="${module.build}/WsdmModule"/>
- <property name="web-inf.folder" value="${web.module}/WEB-INF"/>
- <property name="classes.folder" value="${web-inf.folder}/classes"/>
+ <property name="web.module" value="${module.build}${file.separator}WsdmModule"/>
+ <property name="web-inf.folder" value="${web.module}${file.separator}WEB-INF"/>
+ <property name="classes.folder" value="${web-inf.folder}${file.separator}classes"/>
<target name="release-bin-other">
<mkdir dir="${module.release}${file.separator}log"/>
</target>
<target name="libs-release" description="copy dependencies into module release">
-
- <!-- Copy the module dependencies for JMX Bridge release-->
<copy todir="${module.release}${file.separator}" failonerror="true" verbose="true">
<fileset dir="${build}" casesensitive="yes" includes="${module.libs}">
<not><filename name="**/*javassist*"/></not>
@@ -46,38 +46,29 @@
<not><filename name="**/*muse*"/></not>
</fileset>
</copy>
-
- <!-- qpid-management-client.jar : this should be copied only on jmx dist -->
- <copy todir="${module.release}/lib" failonerror="true">
+ <copy todir="${module.release}${file.separator}lib" failonerror="true">
<fileset file="${module.jar}"/>
<fileset dir="${build.lib}" includes="${module.depends.jars}"/>
</copy>
-
- <!-- qman.war -->
- <copy todir="${module.release}/lib" failonerror="true">
- <fileset file="${web.module}${file.separator}${war.name}"/>
- </copy>
+ <jar destfile="${module.release}${file.separator}lib${file.separator}${war.name}" basedir="${web.module}"/>
</target>
<target name="prepare-wsdm-module">
<mkdir dir="${web.module}"/>
<mkdir dir="${web-inf.folder}"/>
<mkdir dir="${classes.folder}"/>
- <copy file="./web.xml" todir="${web-inf.folder}" verbose="false"/>
- <copy todir="${classes.folder}" verbose="false">
- <fileset dir="${module.classes}">
- <include name="org/apache/qpid/management/servlet/*"/>
- <include name="org/apache/qpid/management/wsdm/**"/>
- <include name="org/apache/qpid/qman/**"/>
- <include name="wsdl/**"/>
+ <copy file=".${file.separator}web.xml" todir="${web-inf.folder}" verbose="false"/>
+ <copy todir="${classes.folder}" verbose="false">
+ <fileset dir="${module.classes}">
+ <include name="wsdl/**"/>
<include name="muse.xml"/>
<include name="router-entries/**"/>
- </fileset>
- </copy>
+ </fileset>
+ </copy>
<copy todir="${web-inf.folder}">
<fileset dir="${build}" includes="${module.libs}"/>
</copy>
- <copy todir="${web-inf.folder}/lib">
+ <copy todir="${web-inf.folder}${file.separator}lib">
<fileset dir="${build}/lib">
<include name="qpid-client-*.jar"/>
<include name="qpid-common-*.jar"/>
@@ -89,45 +80,69 @@
</fileset>
</copy>
</target>
- <target name="jar.manifest" depends="compile" if="module.manifest">
- <jar destfile="${module.jar}" manifest="${module.manifest}">
- <fileset dir="${module.classes}" casesensitive="yes">
+ <target name="jar.manifest" depends="compile" if="module.manifest">
+ <jar destfile="${module.jar}" manifest="${module.manifest}">
+ <fileset dir="${module.classes}" casesensitive="yes">
<include name="**/**"/>
- <exclude name="org/apache/qpid/management/servlet/*"/>
- <exclude name="org/apache/qpid/management/wsdm/**"/>
- <exclude name="org/apache/qpid/qman/**"/>
<exclude name="wsdl/**"/>
<exclude name="muse.xml"/>
<exclude name="router-entries/**"/>
- </fileset>
- </jar>
- </target>
- <target name="jar.nomanifest" depends="compile" unless="module.manifest">
- <jar destfile="${module.jar}">
- <metainf dir="${project.root}/resources/" />
- <fileset dir="${module.classes}" casesensitive="yes">
+ </fileset>
+ </jar>
+ </target>
+ <target name="jar.nomanifest" depends="compile" unless="module.manifest">
+ <jar destfile="${module.jar}">
+ <metainf dir="${project.root}${file.separator}resources/" />
+ <fileset dir="${module.classes}" casesensitive="yes">
<include name="**/**"/>
- <exclude name="org/apache/qpid/management/servlet/*"/>
- <exclude name="org/apache/qpid/management/wsdm/**"/>
- <exclude name="org/apache/qpid/qman/**"/>
<exclude name="wsdl/**"/>
<exclude name="muse.xml"/>
<exclude name="router-entries/**"/>
</fileset>
- </jar>
- </target>
-
- <target name="clean-wsdm-module" description="Clean up web module directory before proceed.">
- <delete dir="${web.module}"/>
- </target>
+ </jar>
+ </target>
+ <target name="postbuild" depends="prepare-wsdm-module" description="Build WS-DM module"/>
+ <path id="module.test.path">
+ <pathelement path="${module.test.classes}" />
+ <path refid="module.test.libs"/>
+ <fileset dir="${build}/lib">
+ <include name="qpid-client-*.jar"/>
+ <include name="qpid-common-*.jar"/>
+ <include name="qpid-management-client-*.jar"/>
+ <exclude name="qpid-client-example*.jar"/>
+ <exclude name="qpid-client-tests*.jar"/>
+ <exclude name="qpid-common-tests*.jar"/>
+ <exclude name="qpid-management-client-tests*.jar"/>
+ </fileset>
+ </path>
+ <target name="test" depends="build,compile-tests" if="module.test.src.exists" unless="${dontruntest}" description="execute unit tests">
+ <delete file="${module.failed}"/>
+ <echo message="Using config:${config}" level="info"/>
+ <junit fork="${test.fork}" maxmemory="1024M" reloading="no"
+ haltonfailure="${haltonfailure}" haltonerror="${haltonerror}"
+ failureproperty="test.failures" printsummary="on" timeout="600000" >
+
+ <jvmarg value="${jvm.args}"/>
+ <sysproperty key="qman.war" value="${web.module}"/>
+
+ <formatter type="plain"/>
+ <formatter type="xml"/>
- <target name="clenaup-wsdm-module-tmp-files" description="Clean up all the temporary files used for build WSDM module.">
- <delete dir="${web-inf.folder}"/>
- </target>
+ <classpath refid="module.test.path"/>
- <target name="create-wsdm-module" description="Creates WSDM Module (Web Application Archive ).">
- <jar destfile="${web.module}/${war.name}" basedir="${web.module}"/>
- </target>
-
- <target name="postbuild" depends="clean-wsdm-module,prepare-wsdm-module,create-wsdm-module,clenaup-wsdm-module-tmp-files" description="Build WS-DM module"/>
+ <batchtest fork="${test.fork}" todir="${module.results}">
+ <fileset dir="${module.test.src}" excludes="${module.test.excludes}">
+ <include name="**/${test}.java"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ <antcall target="touch-failed"/>
+ <condition property="failed">
+ <and>
+ <isfalse value="${test.failures.ignore}"/>
+ <available file="${module.failed}"/>
+ </and>
+ </condition>
+ <fail if="failed" message="TEST SUITE FAILED"/>
+ </target>
</project> \ No newline at end of file
diff --git a/java/management/client/src/main/java/muse.xml b/java/management/client/src/main/java/muse.xml
index aa1ece3404..cf4ec4000a 100644
--- a/java/management/client/src/main/java/muse.xml
+++ b/java/management/client/src/main/java/muse.xml
@@ -13,6 +13,10 @@
<java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.MapSerializer</java-serializer-class>
</custom-serializer>
<custom-serializer>
+ <java-serializable-type>java.util.HashMap</java-serializable-type>
+ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.MapSerializer</java-serializer-class>
+ </custom-serializer>
+ <custom-serializer>
<java-serializable-type>java.util.UUID</java-serializable-type>
<java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.UUIDSerializer</java-serializer-class>
</custom-serializer>
@@ -20,11 +24,15 @@
<java-serializable-type>org.apache.qpid.management.wsdm.capabilities.Result</java-serializable-type>
<java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.InvocationResultSerializer</java-serializer-class>
</custom-serializer>
+ <custom-serializer>
+ <java-serializable-type>java.util.Date</java-serializable-type>
+ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.DateSerializer</java-serializer-class>
+ </custom-serializer>
<router>
<java-router-class>org.apache.muse.core.routing.SimpleResourceRouter</java-router-class>
<logging>
<log-file>log/muse.log</log-file>
- <log-level>FINE</log-level>
+ <log-level>SEVERE</log-level>
</logging>
<persistence>
<java-persistence-class>org.apache.muse.core.routing.RouterFilePersistence</java-persistence-class>
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/Messages.java b/java/management/client/src/main/java/org/apache/qpid/management/Messages.java
index 6acc83cd1a..c0b43d0c29 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/Messages.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/Messages.java
@@ -108,6 +108,8 @@ public interface Messages
String QMAN_200040_WS_ARTIFACTS_CACHED = "<QMAN-200040> : WS Artifacts has been stored on cache with the following id : %s";
String QMAN_200041_INCOMING_OBJECT_NAME_AND_DERIVED_KEY = "<QMAN-200041> : Incoming object name : %s, derived search key : %s";
String QMAN_200042_REMOVING_RESOURCE = "<QMAN-200042> : WS-Resource %s is going to be removed";
+ String QMAN_200043_GENERATED_ACCESSOR_METHOD = "<QMAN-200043> : Generated accessor method for %s : %s";
+ String QMAN_200044_GENERATED_METHOD = "<QMAN-200044> : Generated method for %s : %s";
// WARNING
String QMAN_300001_MESSAGE_DISCARDED = "<QMAN-300001> : No handler has been configured for processing messages with \"%s\" as opcode. Message will be discarded.";
@@ -150,4 +152,10 @@ public interface Messages
String QMAN_100032_WS_RESOURCE_NOT_YET_INITIALIZED = "<QMAN-100032> : Bad request has been received on this WS-Resource : Shutdown is not possible because the resource hasn't yet been initialized.";
String QMAN_100033_WS_RESOURCE_ALREADY_SHUTDOWN = "<QMAN-100033> : Bad request has been received on this WS-Resource : Shutdown is not possible because the resource has already been shutdown.";
String QMAN_100034_WSDL_SCHEMA_SECTION_NOT_FOUND = "<QMAN-100034> : Unable to get via XPath the schema section in WSDL.";
+ String QMAN_100035_RESOURCE_CAPABILITY_INVOCATION_FAILURE = "<QMAN-100035> : Resource thrown a failure while invoking a capability operation.";
+
+ // NEW
+ String QMAN_100035_GET_ATTRIBUTE_FAILURE = "<QMAN-100035> : Get Attribute invocation failure for attribute %s, resource %s.";
+ String QMAN_100036_SET_ATTRIBUTE_FAILURE = "<QMAN-100036> : Set Attribute invocation failure for attribute %s, resource %s.";
+ String QMAN_100037_INVOKE_OPERATION_FAILURE = "<QMAN-100037> : Operation Invocation failure for operation.";
} \ No newline at end of file
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/Names.java b/java/management/client/src/main/java/org/apache/qpid/management/Names.java
index db3cdf7abe..4b723ee5fe 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/Names.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/Names.java
@@ -141,5 +141,6 @@ public abstract class Names
public final static String TYPE = "type";
public final static String XSI_TYPE = "xsi:"+TYPE;
- public final static String ADAPTER_PORT= "qman.port";
+ public final static String ADAPTER_HOST_PROPERTY_NAME = "qman.host";
+ public final static String ADAPTER_PORT_PROPERTY_NAME = "qman.port";
} \ No newline at end of file
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java
index 6dd213aa8c..019fce5a50 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java
@@ -36,7 +36,7 @@ import org.apache.qpid.management.domain.services.MethodInvocationException;
public class InvocationResult implements Serializable
{
private static final long serialVersionUID = 2062662997326399693L;
-
+
private final long _returnCode;
private final String _statusText;
private final byte [] _outputAndBidirectionalArgumentValues;
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObject.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObject.java
new file mode 100644
index 0000000000..4026f6102b
--- /dev/null
+++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObject.java
@@ -0,0 +1,307 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.handler.impl;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.management.domain.services.MethodInvocationException;
+
+/**
+ * This is a sample entity used on QMan test case.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidDomainObject implements QpidDomainObjectMBean
+{
+ private UUID _vhostRef;
+ private String _name;
+ private Boolean _durable;
+ private Map<String, Object> _arguments;
+ private Long _msgTotalEnqueues;
+ private Integer _consumerCount;
+ private Short _mgmtPubInterval;
+ private Date _expireTime;
+ private String _type;
+
+ /**
+ * Builds a new QpidDomainObject with default values for
+ * its properties.
+ */
+ public QpidDomainObject()
+ {
+ _vhostRef = UUID.randomUUID();
+ _name = "Initial Name";
+ _durable = Boolean.TRUE;
+ _arguments = new HashMap<String, Object>();
+ _arguments.put("Key1", "aStringValue");
+ _arguments.put("Key2", Long.MIN_VALUE);
+ _arguments.put("Key3", Integer.MAX_VALUE);
+ _arguments.put("Key4", Double.MIN_VALUE);
+ _arguments.put("Key4", Float.MAX_VALUE);
+
+ _msgTotalEnqueues = Long.MAX_VALUE-10;
+ _consumerCount = Integer.MIN_VALUE+10;
+ _mgmtPubInterval = Short.MAX_VALUE;
+ _expireTime = new Date(Long.MAX_VALUE);
+ }
+
+ /**
+ * A method that is throwing an exception, everytime.
+ *
+ * @throws Exception each time the method is called.
+ */
+ public void throwsException() throws Exception
+ {
+ throw new MethodInvocationException(-1,"KO");
+ }
+
+ /**
+ * Sample echo method that return an empty result object.
+ * That is, an object with only status code / text valorized
+ * (no output parameters).
+ *
+ * @return an empty result object.
+ */
+ public InvocationResult voidWithoutArguments()
+ {
+ return new InvocationResult(0,"OK,null",null);
+ }
+
+ /**
+ * Echo method that accepts and returns primitive type arrays.
+ *
+ * @param longs an array of long.
+ * @param booleans an array of boolean.
+ * @param doubles an array of double.
+ * @param floats an array of float.
+ * @param integers an array of int.
+ * @param shorts an array of short.
+ * @return a result object with the same input parameters (as output parameters).
+ */
+ public InvocationResult echoWithSimpleTypeArrays(
+ long [] longs,
+ boolean [] booleans,
+ double [] doubles,
+ float [] floats,
+ int [] integers,
+ short [] shorts)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put(long.class.getName(), longs);
+ outputParameters.put(boolean.class.getName(), booleans);
+ outputParameters.put(double.class.getName(), doubles);
+ outputParameters.put(float.class.getName(), floats);
+ outputParameters.put(int.class.getName(), integers);
+ outputParameters.put(short.class.getName(), shorts);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns wrapper types.
+ *
+ * @param aLong a java.lang.Long
+ * @param aBoolean a java.lang.Boolean
+ * @param aDouble a java.lang.Double
+ * @param aFloat a java.lang.Float
+ * @param anInteger a java.lang.Integer
+ * @param aShort a java.lang.Short
+ * @param aString a java.lang.String
+ * @param anURI a java.net.URI
+ * @param aDate a java.util.Date
+ * @return a result object with the same given parameters (as output parameters)
+ */
+ public InvocationResult echoWithSimpleTypes(
+ Long aLong,
+ Boolean aBoolean,
+ Double aDouble,
+ Float aFloat,
+ Integer anInteger,
+ Short aShort,
+ String aString,
+ URI anURI,
+ Date aDate)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put("p1", aLong);
+ outputParameters.put("p2", aBoolean);
+ outputParameters.put("p3", aDouble);
+ outputParameters.put("p4", aFloat);
+ outputParameters.put("p5", anInteger);
+ outputParameters.put("p6", aShort);
+ outputParameters.put("p7", aString);
+ outputParameters.put("p8", anURI);
+ outputParameters.put("p9", aDate);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns wrapper type arrays .
+ *
+ * @param longs an array of java.lang.Long
+ * @param booleans an array of java.lang.Boolean
+ * @param doubles an array of java.lang.Double
+ * @param floats an array of java.lang.Float
+ * @param integers an array of java.lang.Integer
+ * @param shorts an array of java.lang.Short
+ * @param strings an array of java.lang.String
+ * @param uris an array of java.net.URI
+ * @param dates an array of java.util.Date
+ * @return a result object with the same input parameters (as output parameters).
+ */
+ public InvocationResult echoWithArrays(
+ Long [] longs,
+ Boolean [] booleans,
+ Double [] doubles,
+ Float [] floats,
+ Integer [] integers,
+ Short [] shorts,
+ String [] strings,
+ URI [] uris,
+ Date [] dates)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put(Long.class.getName(), longs);
+ outputParameters.put(Boolean.class.getName(), booleans);
+ outputParameters.put(Double.class.getName(), doubles);
+ outputParameters.put(Float.class.getName(), floats);
+ outputParameters.put(Integer.class.getName(), integers);
+ outputParameters.put(Short.class.getName(), shorts);
+ outputParameters.put(String.class.getName(), strings);
+ outputParameters.put(URI.class.getName(), uris);
+ outputParameters.put(Date.class.getName(), dates);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns a byte array.
+ *
+ * @param byteArray a byte array
+ * @return a result containing the input byte array (as output parameter)
+ */
+ public InvocationResult echoWithByteArray(byte [] byteArray)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put(byte[].class.getName(),byteArray);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns an UUID.
+ *
+ * @param uuid a java.util.UUID.
+ * @return a result containing the input UUID (as output parameter)
+ */
+ public InvocationResult echoWithUUID(UUID uuid)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put("uuid",uuid);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns a Map.
+ *
+ * @param map a java.util.Map.
+ * @return a result containing the input Map (as output parameter)
+ */
+ public InvocationResult echoWithMap(Map<String,Object> map)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put("map",map);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ public UUID getVhostRef()
+ {
+ return _vhostRef;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public Boolean getDurable()
+ {
+ return _durable;
+ }
+
+ public Map<String, Object> getArguments()
+ {
+ return _arguments;
+ }
+
+ public Long getMsgTotalEnqueues()
+ {
+ return _msgTotalEnqueues;
+ }
+
+ public Integer getConsumerCount()
+ {
+ return _consumerCount;
+ }
+
+ public Date getExpireTime()
+ {
+ return _expireTime;
+ }
+
+ public Short getMgmtPubInterval()
+ {
+ return _mgmtPubInterval;
+ }
+
+ public void setExpireTime(Date expireTime)
+ {
+ this._expireTime = expireTime;
+ }
+
+ public void setMgmtPubInterval(Short value)
+ {
+ this._mgmtPubInterval = value;
+ }
+
+ public void setType(String type)
+ {
+ this._type = type;
+ }
+
+ public String getType()
+ {
+ return _type;
+ }
+} \ No newline at end of file
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObjectMBean.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObjectMBean.java
new file mode 100644
index 0000000000..8a383505c7
--- /dev/null
+++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObjectMBean.java
@@ -0,0 +1,227 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.handler.impl;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Management interface for Qpid domain object.
+ *
+ * @author Andrea Gazzarini
+ */
+public interface QpidDomainObjectMBean
+{
+ /**
+ * A method that is throwing an exception, everytime.
+ *
+ * @throws Exception each time the method is called.
+ */
+ void throwsException() throws Exception;
+
+ /**
+ * Sample echo method that return an empty result object.
+ * That is, an object with only status code / text valorized
+ * (no output parameters).
+ *
+ * @return an empty result object.
+ */
+ InvocationResult voidWithoutArguments();
+
+ /**
+ * Echo method that accepts and returns wrapper types.
+ *
+ * @param aLong a java.lang.Long
+ * @param aBoolean a java.lang.Boolean
+ * @param aDouble a java.lang.Double
+ * @param aFloat a java.lang.Float
+ * @param anInteger a java.lang.Integer
+ * @param aShort a java.lang.Short
+ * @param aString a java.lang.String
+ * @param anURI a java.net.URI
+ * @param aDate a java.util.Date
+ * @return a result object with the same given parameters (as output parameters)
+ */
+ InvocationResult echoWithSimpleTypes(
+ Long aLong,
+ Boolean aBoolean,
+ Double aDouble,
+ Float aFloat,
+ Integer anInteger,
+ Short aShort,
+ String aString,
+ URI anURI,
+ Date aDate);
+
+ /**
+ * Echo method that accepts and returns wrapper type arrays .
+ *
+ * @param longs an array of java.lang.Long
+ * @param booleans an array of java.lang.Boolean
+ * @param doubles an array of java.lang.Double
+ * @param floats an array of java.lang.Float
+ * @param integers an array of java.lang.Integer
+ * @param shorts an array of java.lang.Short
+ * @param strings an array of java.lang.String
+ * @param uris an array of java.net.URI
+ * @param dates an array of java.util.Date
+ * @return a result object with the same input parameters (as output parameters).
+ */
+ InvocationResult echoWithArrays(
+ Long [] longs,
+ Boolean [] booleans,
+ Double [] doubles,
+ Float [] floats,
+ Integer [] integers,
+ Short [] shorts,
+ String [] strings,
+ URI [] uris,
+ Date [] dates);
+
+ /**
+ * Echo method that accepts and returns primitive type arrays.
+ *
+ * @param longs an array of long.
+ * @param booleans an array of boolean.
+ * @param doubles an array of double.
+ * @param floats an array of float.
+ * @param integers an array of int.
+ * @param shorts an array of short.
+ * @return a result object with the same input parameters (as output parameters).
+ */
+ InvocationResult echoWithSimpleTypeArrays(
+ long [] longs,
+ boolean [] booleans,
+ double [] doubles,
+ float [] floats,
+ int [] integers,
+ short [] shorts);
+
+ /**
+ * Echo method that accepts and returns a byte array.
+ *
+ * @param byteArray a byte array
+ * @return a result containing the input byte array (as output parameter)
+ */
+ InvocationResult echoWithByteArray(byte [] byteArray);
+
+ /**
+ * Echo method that accepts and returns an UUID.
+ *
+ * @param uuid a java.util.UUID.
+ * @return a result containing the input UUID (as output parameter)
+ */
+ InvocationResult echoWithUUID(UUID uuid);
+
+ /**
+ * Echo method that accepts and returns a Map.
+ *
+ * @param map a java.util.Map.
+ * @return a result containing the input Map (as output parameter)
+ */
+ InvocationResult echoWithMap(Map<String,Object> map);
+
+ /**
+ * Returns the VHostRef property value.
+ *
+ * @return the VHostRef property value.
+ */
+ UUID getVhostRef();
+
+ /**
+ * Returns the name property value.
+ *
+ * @return the name property value.
+ */
+ String getName();
+
+ /**
+ * Returns the durable property value.
+ *
+ * @return the durable property value.
+ */
+ Boolean getDurable();
+
+ /**
+ * Returns the arguments property value.
+ *
+ * @return the arguments property value.
+ */
+ Map<String, Object> getArguments();
+
+ /**
+ * Returns the msgTotalEnqueues property value.
+ *
+ * @return the msgTotalEnqueues property value.
+ */
+ Long getMsgTotalEnqueues();
+
+ /**
+ * Returns the consumerCount property value.
+ *
+ * @return the consumerCount property value.
+ */
+ Integer getConsumerCount();
+
+ /**
+ * Returns the mgmtPubInterval property value.
+ *
+ * @return the mgmtPubInterval property value.
+ */
+ Short getMgmtPubInterval();
+
+ /**
+ * Sets the mgmtPubInterval property value.
+ *
+ * @param the mgmtPubInterval property value.
+ */
+ void setMgmtPubInterval(Short mgmtPubInterval);
+
+ /**
+ * Returns the expireTime property value.
+ *
+ * @return the expireTime property value.
+ */
+ Date getExpireTime();
+
+ /**
+ * Sets the expireTime property value.
+ *
+ * @return the expireTime property value.
+ */
+ void setExpireTime(Date expireTime);
+
+ /**
+ * Returns the type property value.
+ *
+ * @return the type property value.
+ */
+ void setType(String type);
+
+ /**
+ * Sets the type property value.
+ *
+ * @return the type property value.
+ */
+ String getType();
+} \ No newline at end of file
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java
index 359b276081..40868752fe 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java
@@ -368,7 +368,6 @@ class QpidClass extends QpidEntity implements QpidClassMBean
OperationHasBeenInvokedNotification notification = null;
try
{
- // TODO : Overloaded methods
QpidMethod method = _methods.get(actionName);
if (method != null)
{
@@ -384,12 +383,14 @@ class QpidClass extends QpidEntity implements QpidClassMBean
notification = new OperationHasBeenInvokedNotification(actionName,params,signature,exception);
throw exception;
}
- } else {
+ } else
+ {
ReflectionException exception = new ReflectionException(new NoSuchMethodException(actionName));
notification = new OperationHasBeenInvokedNotification(actionName,params,signature,exception);
throw exception;
}
- }finally {
+ } finally
+ {
sendNotification(notification);
}
}
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmu.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmu.java
new file mode 100644
index 0000000000..2067bc9164
--- /dev/null
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmu.java
@@ -0,0 +1,124 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm;
+
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObject;
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObjectMBean;
+import org.apache.qpid.management.jmx.EntityLifecycleNotification;
+
+/**
+ * QEmu is basically an instance creator that is installed separately
+ * as part of QMan test cases & examples.
+ * Reason for that is to emulate object creation (queues, exchanges, etc...) without having Qpid broker
+ * connected and therefore controlling the total number of the instances that are created.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QEmu extends NotificationBroadcasterSupport implements QEmuMBean, MBeanRegistration{
+
+ private MBeanServer _mxServer;
+ private final static String PACKAGE_NAME= "org.apache.qpid";
+ private final static String QUEUE = "queue";
+
+ /**
+ * Unregisters a Queue MBean with MBeanServer.
+ *
+ * @param objectName the name of the MBean that must unregistered.
+ * @throws Exception when the creation or the registration fails.
+ */
+ public void unregister(ObjectName objectName) throws Exception
+ {
+ _mxServer.unregisterMBean(objectName);
+ sendNotification(EntityLifecycleNotification.INSTANCE_REMOVED,objectName);
+ }
+
+ /**
+ * Creates and registers a Queue MBean with MBeanServer.
+ *
+ * @param objectName the name of the queue MBean.
+ * @throws Exception when the creation or the registration fails.
+ */
+ public void createQueue(ObjectName objectName) throws Exception
+ {
+ QpidDomainObjectMBean queue = new QpidDomainObject();
+ _mxServer.registerMBean(queue, objectName);
+
+ sendNotification(EntityLifecycleNotification.INSTANCE_ADDED,objectName);
+ }
+
+ /**
+ * Sends a notification about a lifecycle event of the mbean associated
+ * with the given object.
+ *
+ * @param type the event (notification) type.
+ * @param name the name of the event source.
+ */
+ private void sendNotification(String type,ObjectName name)
+ {
+ sendNotification(
+ new EntityLifecycleNotification(
+ type,
+ PACKAGE_NAME,
+ QUEUE,
+ Names.CLASS,
+ name));
+ }
+
+ /**
+ * Not implemented for this class.
+ */
+ public void postDeregister()
+ {
+ // N.A.
+ }
+
+ /**
+ * Not implemented for this class.
+ */
+ public void postRegister(Boolean registrationDone)
+ {
+ // N.A.
+ }
+
+ /**
+ * Not implemented for this class.
+ */
+ public void preDeregister()
+ {
+ // N.A.
+ }
+
+ /**
+ * MBean server callback.
+ * Stores the value of the owner MBeanServer.
+ */
+ public ObjectName preRegister(MBeanServer server, ObjectName name)
+ {
+ this._mxServer = server;
+ return name;
+ }
+} \ No newline at end of file
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java
new file mode 100644
index 0000000000..9a0e2c3955
--- /dev/null
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java
@@ -0,0 +1,92 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm;
+
+import java.lang.management.ManagementFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * QPid Emulator Initializer.
+ * This component is basically responsible to create and initialize an emulator module used
+ * for simulate object instances creation.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QEmuInitializer extends HttpServlet
+{
+ private static final long serialVersionUID = 6149614872902682208L;
+ private final static Logger LOGGER = Logger.get(QEmuInitializer.class);
+
+ /**
+ * QEmu initialization method.
+ *
+ * @throws ServletException when the module cannot be initialized.
+ */
+ public void init() throws ServletException
+ {
+ try
+ {
+ ManagementFactory.getPlatformMBeanServer().registerMBean(
+ new QEmu(),
+ Names.QPID_EMULATOR_OBJECT_NAME);
+ } catch(Exception exception)
+ {
+ LOGGER.warn(exception,Messages.QMAN_300005_QEMU_INITIALIZATION_FAILURE);
+ throw new ServletException(exception);
+ }
+ }
+
+ /**
+ * This is a startup module only so an override of the default servlet
+ * behaviour must be done in order to prevent incoming http requests processing.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException each time this method is called.
+ */
+ @Override
+ public void service(HttpServletRequest request,HttpServletResponse response) throws ServletException
+ {
+ throw new ServletException();
+ }
+
+ /**
+ * Unregister QPid emulator.
+ */
+ public void destroy()
+ {
+ try
+ {
+ ManagementFactory.getPlatformMBeanServer()
+ .unregisterMBean(Names.QPID_EMULATOR_OBJECT_NAME);
+ } catch (Exception exception)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuMBean.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuMBean.java
new file mode 100644
index 0000000000..f22e7ff12d
--- /dev/null
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuMBean.java
@@ -0,0 +1,48 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm;
+
+import javax.management.ObjectName;
+
+/**
+ * Management interface for QEmu.
+ *
+ * @author Andrea Gazzarini
+ * @see QEmu
+ */
+public interface QEmuMBean
+{
+ /**
+ * Creates and registers a Queue MBean with MBeanServer.
+ *
+ * @param objectName the name of the queue MBean.
+ * @throws Exception when the creation or the registration fails.
+ */
+ void createQueue(ObjectName name) throws Exception;
+
+ /**
+ * Unregisters a Queue MBean with MBeanServer.
+ *
+ * @param objectName the name of the MBean that must unregistered.
+ * @throws Exception when the creation or the registration fails.
+ */
+ void unregister(ObjectName name) throws Exception;
+} \ No newline at end of file
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java
new file mode 100644
index 0000000000..0676b4ac49
--- /dev/null
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java
@@ -0,0 +1,61 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm.capabilities;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.ObjectName;
+
+import org.apache.muse.core.Environment;
+
+/**
+ * Dummy capability builder used for avoid duplicated builds for the
+ * same class.
+ *
+ * @author Andrea Gazzarini
+ */
+public class DummyCapabilityBuilder implements IArtifactBuilder
+{
+
+ public void begin(ObjectName objectName) throws BuilderException
+ {
+ }
+
+ public void endAttributes() throws BuilderException
+ {
+ }
+
+ public void endOperations() throws BuilderException
+ {
+ }
+
+ public void onAttribute(MBeanAttributeInfo attributeMetadata) throws BuilderException
+ {
+ }
+
+ public void onOperation(MBeanOperationInfo operationMetadata) throws BuilderException
+ {
+ }
+
+ public void setEnvironment(Environment environment)
+ {
+ }
+} \ No newline at end of file
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java
index 1942e8809e..312315cdf1 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java
@@ -21,7 +21,6 @@
package org.apache.qpid.management.wsdm.capabilities;
import java.lang.management.ManagementFactory;
-import java.lang.reflect.Array;
import javax.management.Attribute;
import javax.management.AttributeNotFoundException;
@@ -29,25 +28,16 @@ import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
-import javax.xml.namespace.QName;
-import org.apache.muse.core.serializer.Serializer;
-import org.apache.muse.core.serializer.SerializerRegistry;
-import org.apache.muse.util.ReflectUtils;
-import org.apache.muse.util.xml.XmlUtils;
-import org.apache.muse.ws.addressing.soap.SoapFault;
-import org.apache.muse.ws.resource.basefaults.BaseFault;
-import org.apache.muse.ws.resource.basefaults.WsbfUtils;
import org.apache.muse.ws.resource.impl.AbstractWsResourceCapability;
-import org.apache.muse.ws.resource.properties.ResourcePropertyCollection;
+import org.apache.qpid.management.Messages;
import org.apache.qpid.management.domain.handler.impl.InvocationResult;
import org.apache.qpid.management.domain.services.MethodInvocationException;
import org.apache.qpid.management.wsdm.common.EntityInstanceNotFoundFault;
import org.apache.qpid.management.wsdm.common.MethodInvocationFault;
import org.apache.qpid.management.wsdm.common.NoSuchAttributeFault;
import org.apache.qpid.management.wsdm.common.QManFault;
-import org.apache.qpid.management.wsdm.muse.serializer.ByteArraySerializer;
-import org.w3c.dom.Element;
+import org.apache.qpid.transport.util.Logger;
/**
* Abstract capability used for centralize common behaviour of the QMan
@@ -57,11 +47,11 @@ import org.w3c.dom.Element;
*/
public abstract class MBeanCapability extends AbstractWsResourceCapability
{
- private static final Element[] _NO_VALUES = new Element[0];
+ private static final Logger LOGGER = Logger.get(MBeanCapability.class);
protected final MBeanServer _mxServer;
protected ObjectName _objectName;
-
+
/**
* Builds a new capability related to the given object name.
*
@@ -93,7 +83,7 @@ public abstract class MBeanCapability extends AbstractWsResourceCapability
* be found.
* @throws QManFault in case of internal system failure.
*/
- Object getAttribute(String attributeName) throws QManFault
+ Object getAttribute(String attributeName) throws NoSuchAttributeFault,EntityInstanceNotFoundFault,QManFault
{
try
{
@@ -110,6 +100,10 @@ public abstract class MBeanCapability extends AbstractWsResourceCapability
_objectName);
} catch (Exception exception)
{
+ LOGGER.error(
+ Messages.QMAN_100035_GET_ATTRIBUTE_FAILURE,
+ attributeName,
+ _objectName);
throw new QManFault(
getWsResource().getEndpointReference(),
exception);
@@ -134,7 +128,7 @@ public abstract class MBeanCapability extends AbstractWsResourceCapability
* @throws QManFault
* in case of internal system failure.
*/
- void setAttribute(String attributeName, Object value) throws QManFault
+ void setAttribute(String attributeName, Object value) throws NoSuchAttributeFault,EntityInstanceNotFoundFault,QManFault
{
try
{
@@ -151,6 +145,10 @@ public abstract class MBeanCapability extends AbstractWsResourceCapability
_objectName);
} catch (Exception exception)
{
+ LOGGER.error(
+ Messages.QMAN_100036_SET_ATTRIBUTE_FAILURE,
+ attributeName,
+ _objectName);
throw new QManFault(
getWsResource().getEndpointReference(),
exception);
@@ -163,16 +161,31 @@ public abstract class MBeanCapability extends AbstractWsResourceCapability
* @param operationName the name of the operation to be invoked.
* @param params parameters used for operation invocation.
* @param signature the operation / method signature.
- * @throws QManFault when invocation fails.
+ * @throws EntityInstanceNotFoundFault
+ * when the target MBean doesn't exist on Management server.
+ * @throws MethodInvocationFault
+ * when the invocation of the requested operation raises an exception.
+ * @throws QManFault
+ * in case of not-well known failure.
*/
- Result invoke(String operationName, Object [] params, String [] signature) throws QManFault
+ Result invoke(String operationName, Object [] params, String [] signature) throws EntityInstanceNotFoundFault, MethodInvocationFault,QManFault
{
try
{
- InvocationResult output = (InvocationResult) _mxServer.invoke(_objectName, operationName, params, signature);
- Result result = new Result(output.getReturnCode(),output.getStatusText(),output.getOutputSection());
+ InvocationResult output = (InvocationResult) _mxServer
+ .invoke(
+ _objectName,
+ operationName,
+ params,
+ signature);
+
+ Result result = new Result(
+ output.getReturnCode(),
+ output.getStatusText(),
+ output.getOutputSection());
+
return result;
- } catch (InstanceNotFoundException e)
+ } catch (InstanceNotFoundException exception)
{
throw new EntityInstanceNotFoundFault(
getWsResource().getEndpointReference(),
@@ -188,96 +201,23 @@ public abstract class MBeanCapability extends AbstractWsResourceCapability
failure.getStatusText(),
failure.getReturnCode());
} else {
+ LOGGER.error(
+ Messages.QMAN_100037_INVOKE_OPERATION_FAILURE,
+ operationName,
+ _objectName);
throw new QManFault(
getWsResource().getEndpointReference(),
exception);
}
}catch(Exception exception)
{
+ LOGGER.error(
+ Messages.QMAN_100037_INVOKE_OPERATION_FAILURE,
+ operationName,
+ _objectName);
throw new QManFault(
getWsResource().getEndpointReference(),
exception);
}
}
-
- /**
- *
- * @param name
- * @param value
- * TODO : Vedi che poi fà co 'sto metodo che è un pò una monnezza!!!
- * @return The XML representation of the resource property value(s).
- *
- */
- @SuppressWarnings("unchecked")
- protected Element[] getPropertyElements(QName name, Object value) throws BaseFault {
- //
- // in this case, we have to determine if there IS a property
- // and it's null, or there is no property
- //
- if (value == null) {
- ResourcePropertyCollection props = getWsResource().getPropertyCollection();
-
- //
- // property is nillable - we say it exists. not 100% accurate,
- // but as close as we're going to get
- //
- if (props.getSchema().isNillable(name))
- return new Element[] { XmlUtils.createElement(name) };
-
- //
- // not nillable - must not exist
- //
- return _NO_VALUES;
- }
-
- //
- // in all other cases, we determine the type of the property
- // values and use that to serialize into XML
- //
- Object valuesArray = null;
- Class type = null;
- // TODO
- if (value.getClass().isArray()) {
- if (value.getClass() == byte[].class) {
- Serializer serializer = new ByteArraySerializer();
- try {
- return new Element[] { serializer.toXML(value, name) };
- } catch (SoapFault e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- valuesArray = value;
- type = ReflectUtils.getClassFromArrayClass(value.getClass());
- }
-
- else {
- valuesArray = new Object[] { value };
- type = value.getClass();
- }
-
- int length = Array.getLength(valuesArray);
- Element[] properties = new Element[length];
-
- SerializerRegistry registry = SerializerRegistry.getInstance();
- Serializer ser = registry.getSerializer(type);
-
- for (int n = 0; n < length; ++n)
- {
- properties[n] = serializeValue(ser, Array.get(valuesArray, n), name);
- }
- return properties;
- }
-
- private Element serializeValue(Serializer ser, Object value, QName name) throws BaseFault
- {
- try
- {
- return ser.toXML(value, name);
- } catch (SoapFault exception)
- {
- throw WsbfUtils.convertToFault(exception);
- }
- }
} \ No newline at end of file
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java
index 01d8c07e55..334114f4b0 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java
@@ -35,14 +35,20 @@ import javax.management.ObjectName;
import javax.xml.namespace.QName;
import org.apache.muse.core.Environment;
+import org.apache.qpid.management.Messages;
import org.apache.qpid.management.Names;
+import org.apache.qpid.management.wsdm.common.EntityInstanceNotFoundFault;
+import org.apache.qpid.management.wsdm.common.MethodInvocationFault;
+import org.apache.qpid.management.wsdm.common.NoSuchAttributeFault;
import org.apache.qpid.management.wsdm.common.QManFault;
+import org.apache.qpid.transport.util.Logger;
public class MBeanCapabilityBuilder implements IArtifactBuilder{
private final static String GET_PROPERTY_NAMES_METHOD_COMMON_PART = "public QName[] getPropertyNames() { return ";
private final static String GET_PROPERTY_NAMES_METHOD_WITH_ARRAY = GET_PROPERTY_NAMES_METHOD_COMMON_PART+" PROPERTIES;}";
private final static String GET_PROPERTY_NAMES_METHOD_WITH_EMPTY_ARRAY = GET_PROPERTY_NAMES_METHOD_COMMON_PART+" new QName[0];}";
+ private final static Logger LOGGER = Logger.get(MBeanCapabilityBuilder.class);
/**
* Handler interface definining operation needed to be peformed (by a concrete
@@ -67,7 +73,7 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{
* that is activated when this builder detects the presence of at least one property on the
* capability class.
*/
- private final EndAttributesHandler _atLeastThereIsOneProperty = new EndAttributesHandler() {
+ final EndAttributesHandler _atLeastThereIsOneProperty = new EndAttributesHandler() {
/**
* Creates the QName array instance member and the corresponding
@@ -81,7 +87,7 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{
{
_properties.deleteCharAt(_properties.length()-1);
_properties.append("};");
-
+
CtField properties = CtField.make(_properties.toString(), _capabilityClassDefinition);
_capabilityClassDefinition.addField(properties);
@@ -102,7 +108,7 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{
* that is activated when this builder detects that there are no properties defined for
* the capability class.
*/
- private final EndAttributesHandler _noPropertyHasBeenDefined= new EndAttributesHandler()
+ final EndAttributesHandler _noPropertyHasBeenDefined= new EndAttributesHandler()
{
/**
* Creates the getPropertyNames() that simply returns an empty QName array.
@@ -124,10 +130,192 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{
}
};
- private StringBuilder _properties = new StringBuilder("private static final QName[] PROPERTIES = new QName[]{ ");
- private CtClass _capabilityClassDefinition;
+ /**
+ * This is the active state for this builder when the requested class has never been
+ * built.
+ */
+ IArtifactBuilder _classNotAvailable = new IArtifactBuilder()
+ {
+
+ /**
+ * Build process begins.
+ * The given object name is used to build a minimal definition of the product class.
+ *
+ * @param objectName the name of the JMX entity.
+ * @throws BuilderException when the initial definiton of the capability cannot be created.
+ */
+ public void begin(ObjectName objectName) throws BuilderException
+ {
+ String className = objectName.getKeyProperty(Names.CLASS);
+ ClassPool pool = ClassPool.getDefault();
+ pool.insertClassPath(new ClassClassPath(MBeanCapabilityBuilder.class));
+ pool.importPackage(QName.class.getPackage().getName());
+ pool.importPackage(ObjectName.class.getPackage().getName());
+ pool.importPackage(QManFault.class.getPackage().getName());
+ pool.importPackage(Names.class.getPackage().getName());
+ pool.importPackage(Result.class.getPackage().getName());
+ pool.importPackage(NoSuchAttributeFault.class.getPackage().getName());
+ pool.importPackage(EntityInstanceNotFoundFault.class.getPackage().getName());
+ pool.importPackage(MethodInvocationFault.class.getPackage().getName());
+
+ _capabilityClassDefinition = pool.makeClass("org.apache.qpid.management.wsdm.capabilities."+className);
+ try
+ {
+ _capabilityClassDefinition.setSuperclass(pool.get(MBeanCapability.class.getName()));
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+
+ public void endAttributes() throws BuilderException
+ {
+ _endAttributeHandler.endAttributes();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void endOperations() throws BuilderException
+ {
+ try
+ {
+ _capabilityClass = _capabilityClassDefinition.toClass(
+ QManAdapterCapability.class.getClassLoader(),
+ QManAdapterCapability.class.getProtectionDomain());
+ } catch (Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+
+ /**
+ * Director callback.
+ * Attrbute metadata notification. With this callback the director informs this builder that the
+ * currently processed MBean has an attribute with the given metadata.
+ * This builder uses this information in order to add a property and the corresponding accessors
+ * to the capability class that is going to be built.
+ *
+ * @throws BuilderException bytecode manipulation / creation failure.
+ */
+ public void onAttribute(MBeanAttributeInfo attribute) throws BuilderException
+ {
+ String name = attribute.getName();
+ String type = attribute.getType();
+
+ try
+ {
+ type = Class.forName(type).getCanonicalName();
+
+ addPropertyMemberInstance(type, name);
+
+ String nameForAccessors = getNameForAccessors(name);
+
+ if (attribute.isReadable())
+ {
+ String accessor = generateGetter(type, nameForAccessors);
+ CtMethod getter = CtNewMethod.make(accessor,_capabilityClassDefinition);
+ _capabilityClassDefinition.addMethod(getter);
+ appendToPropertiesArray(name);
+
+ LOGGER.debug(
+ Messages.QMAN_200043_GENERATED_ACCESSOR_METHOD,
+ _objectName,
+ accessor);
+ }
+
+ if (attribute.isWritable())
+ {
+ String accessor = generateSetter(type, nameForAccessors);
+ CtMethod setter = CtNewMethod.make(accessor,_capabilityClassDefinition);
+ _capabilityClassDefinition.addMethod(setter);
+
+ LOGGER.debug(
+ Messages.QMAN_200043_GENERATED_ACCESSOR_METHOD,
+ _objectName,
+ accessor);
+ }
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+
+ public void onOperation(MBeanOperationInfo operation) throws BuilderException
+ {
+ StringBuilder method = new StringBuilder();
+ try
+ {
+ method
+ .append("public Result ")
+ .append(operation.getName())
+ .append("( ");
+
+ for (MBeanParameterInfo parameter: operation.getSignature())
+ {
+ method
+ .append(Class.forName(parameter.getType()).getCanonicalName())
+ .append(' ')
+ .append(parameter.getName())
+ .append(',');
+ }
+
+ method.deleteCharAt(method.length()-1);
+ method.append(") throws EntityInstanceNotFoundFault, MethodInvocationFault,QManFault { return invoke(")
+ .append("\"").append(operation.getName()).append("\"")
+ .append(", new Object[]{ ");
+
+ for (MBeanParameterInfo parameter: operation.getSignature())
+ {
+ method.append(parameter.getName())
+ .append(',');
+ }
+
+ method.deleteCharAt(method.length()-1);
+ method.append("}, new String[]{ ");
+
+ for (MBeanParameterInfo parameter: operation.getSignature())
+ {
+ method
+ .append("\"")
+ .append(parameter.getType())
+ .append("\",");
+ }
+ method.deleteCharAt(method.length()-1);
+ method.append("}); }");
+
+ String methodAsString = method.toString();
+ methodAsString = methodAsString.replace("new Object[]{}","null");
+ methodAsString = methodAsString.replace("new String[]{}","null");
+
+ CtMethod definition = CtNewMethod.make(methodAsString,_capabilityClassDefinition);
+ _capabilityClassDefinition.addMethod(definition);
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ } finally {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(
+ Messages.QMAN_200044_GENERATED_METHOD,
+ _objectName,
+ method.toString());
+ }
+ }
+ }
+
+ public void setEnvironment(Environment environment)
+ {
+ // Nothing to do here...
+ }
+ };
+
+ StringBuilder _properties = new StringBuilder("private static final QName[] PROPERTIES = new QName[]{ ");
private Class<MBeanCapability> _capabilityClass;
- private EndAttributesHandler _endAttributeHandler = _noPropertyHasBeenDefined;
+ CtClass _capabilityClassDefinition;
+ EndAttributesHandler _endAttributeHandler = _noPropertyHasBeenDefined;
+
+ private ObjectName _objectName;
+
+ IArtifactBuilder _state;
/**
* Director callback.
@@ -140,31 +328,7 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{
*/
public void onAttribute(MBeanAttributeInfo attribute) throws BuilderException
{
- String name = attribute.getName();
- String type = attribute.getType();
- type = (type.startsWith("[B")) ? " byte[] " : type;
-
- try
- {
- addPropertyMemberInstance(type, name);
-
- String nameForAccessors =
- Character.toUpperCase(name.charAt(0)) +
- name.substring(1);
-
- if (attribute.isReadable())
- {
- generateGetter(type, nameForAccessors);
- }
-
- if (attribute.isWritable())
- {
- generateSetter(type, nameForAccessors);
- }
- } catch(Exception exception)
- {
- throw new BuilderException(exception);
- }
+ _state.onAttribute(attribute);
}
/**
@@ -174,25 +338,21 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{
* @param objectName the name of the target JMX entity of this capability.
* @throws BuilderException when the initialization fails.
*/
+ @SuppressWarnings("unchecked")
public void begin(ObjectName objectName) throws BuilderException
{
- String className = objectName.getKeyProperty(Names.CLASS);
- ClassPool pool = ClassPool.getDefault();
- pool.insertClassPath(new ClassClassPath(MBeanCapabilityBuilder.class));
- pool.importPackage(QName.class.getPackage().getName());
- pool.importPackage(ObjectName.class.getPackage().getName());
- pool.importPackage(QManFault.class.getPackage().getName());
- pool.importPackage(Names.class.getPackage().getName());
- pool.importPackage(Result.class.getPackage().getName());
-
- _capabilityClassDefinition = pool.makeClass("org.apache.qpid.management.wsdm.capabilities."+className);
- try
+ try
{
- _capabilityClassDefinition.setSuperclass(pool.get(MBeanCapability.class.getName()));
- } catch(Exception exception)
+ this._objectName = objectName;
+ String className = objectName.getKeyProperty(Names.CLASS);
+ _capabilityClass = (Class<MBeanCapability>) Class.forName("org.apache.qpid.management.wsdm.capabilities."+className);
+ _state = new DummyCapabilityBuilder();
+ } catch (ClassNotFoundException exception)
{
- throw new BuilderException(exception);
- }
+ _state = _classNotAvailable;
+ }
+
+ _state.begin(objectName);
}
/**
@@ -219,52 +379,7 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{
*/
public void onOperation(MBeanOperationInfo operation) throws BuilderException
{
- try
- {
- StringBuilder method = new StringBuilder()
- .append("public Result ")
- .append(operation.getName())
- .append("( ");
-
- for (MBeanParameterInfo parameter: operation.getSignature())
- {
- method
- .append(parameter.getType())
- .append(' ')
- .append(parameter.getName())
- .append(',');
- }
-
- method.deleteCharAt(method.length()-1);
- method.append(") throws QManFault { return invoke(")
- .append("\"").append(operation.getName()).append("\"")
- .append(", new Object[]{ ");
-
- for (MBeanParameterInfo parameter: operation.getSignature())
- {
- method.append(parameter.getName())
- .append(',');
- }
-
- method.deleteCharAt(method.length()-1);
- method.append("}, new String[]{ ");
-
- for (MBeanParameterInfo parameter: operation.getSignature())
- {
- method
- .append("\"")
- .append(parameter.getType())
- .append("\",");
- }
- method.deleteCharAt(method.length()-1);
- method.append("}); }");
-
- CtMethod definition = CtNewMethod.make(method.toString(),_capabilityClassDefinition);
- _capabilityClassDefinition.addMethod(definition);
- } catch(Exception exception)
- {
- throw new BuilderException(exception);
- }
+ _state.onOperation(operation);
}
/**
@@ -289,7 +404,7 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{
*/
public void endAttributes() throws BuilderException
{
- _endAttributeHandler.endAttributes();
+ _state.endAttributes();
}
/**
@@ -303,15 +418,7 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{
@SuppressWarnings("unchecked")
public void endOperations() throws BuilderException
{
- try
- {
- _capabilityClass = _capabilityClassDefinition.toClass(
- QManAdapterCapability.class.getClassLoader(),
- QManAdapterCapability.class.getProtectionDomain());
- } catch (Exception exception)
- {
- throw new BuilderException(exception);
- }
+ _state.endOperations();
}
/**
@@ -321,7 +428,7 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{
*/
public void setEnvironment(Environment environment)
{
- // N.A.
+ // Nothing to do here...
}
/**
@@ -329,24 +436,22 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{
*
* @param type the type of the property.
* @param name the name of the property.
- * @throws CannotCompileException compilation failure while adding the new feature.
+ * @return the getter method (as a string).
*/
- private void generateGetter(String type, String name) throws CannotCompileException
+ String generateGetter(String type, String name)
{
- StringBuilder buffer = new StringBuilder()
+ return new StringBuilder()
.append("public ")
.append(type)
.append(' ')
.append("get")
.append(name)
- .append("() throws QManFault { return (").append(type).append(") getAttribute(\"")
+ .append("() throws NoSuchAttributeFault,EntityInstanceNotFoundFault,QManFault { return (")
+ .append(type)
+ .append(") getAttribute(\"")
.append(name)
- .append("\"); }");
-
- CtMethod getter = CtNewMethod.make(buffer.toString(),_capabilityClassDefinition);
- _capabilityClassDefinition.addMethod(getter);
-
- appendToPropertiesArray(name);
+ .append("\"); }")
+ .toString();
}
/**
@@ -354,23 +459,21 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{
*
* @param type the type of the property.
* @param name the name of the property.
- * @throws CannotCompileException compilation failure while adding the new feature.
+ * @return the setter method (as a string).
*/
- private void generateSetter(String type, String name) throws CannotCompileException
+ String generateSetter(String type, String name)
{
- StringBuilder buffer = new StringBuilder()
+ return new StringBuilder()
.append("public void ")
.append("set")
.append(name)
.append("(")
.append(type)
- .append(" newValue) throws QManFault {")
+ .append(" newValue) throws NoSuchAttributeFault,EntityInstanceNotFoundFault,QManFault {")
.append(" setAttribute(\"")
.append(name)
- .append("\", newValue); }");
-
- CtMethod setter = CtNewMethod.make(buffer.toString(),_capabilityClassDefinition);
- _capabilityClassDefinition.addMethod(setter);
+ .append("\", newValue); }")
+ .toString();
}
/**
@@ -407,4 +510,20 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{
CtField field= CtField.make(buffer.toString(),_capabilityClassDefinition);
_capabilityClassDefinition.addField(field);
}
+
+ /**
+ * Returns a name that will be used in accessor methods.
+ * That name will differ from the given one because the first letter will be capitalized.
+ * For example, if the given name is "name" the return value will be "Name".
+ *
+ * @param name the plain name of the attribute.
+ * @return a capitalized version of the given name to be used in accessors.
+ */
+ String getNameForAccessors(String name)
+ {
+ return
+ Character.toUpperCase(name.charAt(0)) +
+ name.substring(1);
+ }
+
} \ No newline at end of file
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java
index ada995d35c..511587c372 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java
@@ -38,7 +38,6 @@ import org.apache.muse.core.AbstractCapability;
import org.apache.muse.core.Resource;
import org.apache.muse.core.ResourceManager;
import org.apache.muse.core.routing.MessageHandler;
-import org.apache.muse.core.routing.ReflectionMessageHandler;
import org.apache.muse.core.serializer.SerializerRegistry;
import org.apache.muse.ws.addressing.EndpointReference;
import org.apache.muse.ws.addressing.soap.SoapFault;
@@ -293,7 +292,7 @@ public class QManAdapterCapability extends AbstractCapability
QName returnValueName = new QName(Names.NAMESPACE_URI,name+"Response",Names.PREFIX);
String actionURI = Names.NAMESPACE_URI+"/"+name;
- MessageHandler handler = new ReflectionMessageHandler(actionURI, requestName, returnValueName);
+ MessageHandler handler = new QManMessageHandler(actionURI, requestName, returnValueName);
handler.setMethod(method);
handlers.add(handler);
}
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMessageHandler.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMessageHandler.java
new file mode 100644
index 0000000000..150a7d1905
--- /dev/null
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMessageHandler.java
@@ -0,0 +1,103 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm.capabilities;
+
+import java.lang.reflect.Method;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.routing.ReflectionMessageHandler;
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.wsdm.muse.serializer.ByteArraySerializer;
+import org.w3c.dom.Element;
+
+/**
+ * A custom implementation of Muse message handler to properly deal with
+ * byte arrays.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QManMessageHandler extends ReflectionMessageHandler
+{
+
+ /**
+ * Builds a new message handler with the given arguments.
+ *
+ * @param actionURI the action URI.
+ * @param requestQName the qname of the incoming request.
+ * @param returnValueName the qname of the result value.
+ */
+ public QManMessageHandler(String actionURI, QName requestQName,
+ QName returnValueName)
+ {
+ super(actionURI, requestQName, returnValueName);
+ }
+
+ /**
+ * Transforms the given xml element in the corresponding
+ * object representation.
+ *
+ * @throws SoapFaul when unmarshal operation fails.
+ */
+ public Object[] fromXML(Element xml) throws SoapFault
+ {
+ Method method = getMethod();
+
+ if (xml == null )
+ {
+ return EMPTY_REQUEST;
+ }
+
+ Class[] parameters = method.getParameterTypes();
+ Object[] objects = new Object[parameters.length];
+
+ Element[] elements = XmlUtils.getAllElements(xml);
+
+ if (parameters.length == 1 && elements.length == 0)
+ {
+ elements = new Element[]{ xml };
+ }
+
+ if (elements.length != parameters.length)
+ {
+ throw new SoapFault("IncorrectParams");
+ }
+
+ SerializerRegistry registry = SerializerRegistry.getInstance();
+
+ for (int i = 0; i < elements.length; ++i)
+ {
+ Class clazz = parameters[i];
+ if (clazz == byte[].class)
+ {
+ objects[i] = new ByteArraySerializer().fromXML(elements[i]);
+ } else
+ {
+ Serializer ser = registry.getSerializer(parameters[i]);
+ objects[i] = ser.fromXML(elements[i]);
+ }
+ }
+ return objects;
+ }
+} \ No newline at end of file
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java
index 1bde65180d..86aba0e5bb 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java
@@ -31,7 +31,7 @@ import org.apache.muse.core.Environment;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.ws.resource.metadata.WsrmdConstants;
import org.apache.qpid.management.Names;
-import org.apache.qpid.qman.debug.XmlDebugger;
+import org.apache.qpid.qman.debug.WsdlDebugger;
import org.w3c.dom.Element;
/**
@@ -45,7 +45,7 @@ class RmdBuilder implements IArtifactBuilder
{
private List<Element> _metadataDescriptor = new ArrayList<Element>();
- private ObjectName _objectName;
+ ObjectName _objectName;
/**
* Nothing to be done here on this builder.
@@ -96,7 +96,7 @@ class RmdBuilder implements IArtifactBuilder
: Names.READ_ONLY);
property.setAttribute(Names.MUTABILITY,Names.MUTABLE);
- XmlDebugger.debug(_objectName, property);
+ WsdlDebugger.debug(_objectName, property);
_metadataDescriptor.add(property);
}
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifacts.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifacts.java
index b8a4f7766f..ac4636b9c9 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifacts.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifacts.java
@@ -23,12 +23,32 @@ package org.apache.qpid.management.wsdm.capabilities;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+/**
+ * Web Service Artifacts.
+ * Basically it acts as a container for all artifacts built when a new WS-Resource is created.
+ * With WS artifacts we mean :
+ *
+ * <ul>
+ * <li>Capability class (which encapsulate the WS-DM capability concern)</li>
+ * <li>WS Resource Metadata Descriptor (RMD)</li>
+ * <li>Web Service Description (WSDL)</li>
+ * </ul>
+ *
+ * @author Andrea Gazzarini
+ */
class WsArtifacts {
private final Class<MBeanCapability>_capabilityClass;
private final Element[] _resourceMetadataDescriptor;
private final Document _wsdl;
-
+
+ /**
+ * Builds a new artifacts container with the given artifacts.
+ *
+ * @param capabilityClass the capability class.
+ * @param resourceMetadataDescriptor the resource metadata descriptor.
+ * @param wsdl the wsdl.
+ */
public WsArtifacts(
Class<MBeanCapability> capabilityClass,
Element[] resourceMetadataDescriptor,
@@ -39,17 +59,34 @@ class WsArtifacts {
this._wsdl = wsdl;
}
- public Class<MBeanCapability> getCapabilityClass()
+ /**
+ * Returns the capability class.
+ *
+ * @return the capability class.
+ */
+ Class<MBeanCapability> getCapabilityClass()
{
return _capabilityClass;
}
- public Element[] getResourceMetadataDescriptor()
+ /**
+ * Returns the resource metadata descriptor.
+ * It is not a whole document but each property metadata is described in a
+ * separated element so the returned object is an array of elements.
+ *
+ * @return the resource metadata descriptor.
+ */
+ Element[] getResourceMetadataDescriptor()
{
return _resourceMetadataDescriptor;
}
- public Document getWsdl()
+ /**
+ * Returns the web service description.
+ *
+ * @return the web service description (WSDL).
+ */
+ Document getWsdl()
{
return _wsdl;
}
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java
index 0209ddb55e..2a1bf059c3 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java
@@ -85,7 +85,8 @@ class WsArtifactsFactory
LOGGER.debug(
Messages.QMAN_200041_INCOMING_OBJECT_NAME_AND_DERIVED_KEY,
- objectName,searchKey);
+ objectName,
+ searchKey);
result = _cache.get(searchKey);
if (result == null)
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java
index a9aa845f3d..bc0e4da4fd 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java
@@ -21,26 +21,36 @@
package org.apache.qpid.management.wsdm.capabilities;
import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.ObjectName;
+import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import org.apache.muse.core.Environment;
+import org.apache.muse.util.ReflectUtils;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.ws.wsdl.WsdlUtils;
import org.apache.qpid.management.Messages;
import org.apache.qpid.management.Names;
import org.apache.qpid.management.wsdm.muse.serializer.ObjectSerializer;
-import org.apache.qpid.qman.debug.XmlDebugger;
+import org.apache.qpid.qman.debug.WsdlDebugger;
import org.apache.qpid.transport.util.Logger;
import org.apache.xpath.XPathAPI;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-
+/**
+ * TO BE IMPROVED USING JAXB!!
+ *
+ * @author Andrea Gazzarini
+ */
class WsdlBuilder implements IArtifactBuilder {
private final static Logger LOGGER = Logger.get(WsdlBuilder.class);
@@ -53,6 +63,10 @@ class WsdlBuilder implements IArtifactBuilder {
private ObjectName _objectName;
+ private boolean mapTypeHasBeenDeclared;
+ private boolean uuidTypeHasBeenDeclared;
+ private Map<String, String> arrayTypesAlreadyDeclared = new HashMap<String, String>();
+
public void onAttribute(MBeanAttributeInfo attributeMetadata) throws BuilderException
{
try
@@ -73,14 +87,17 @@ class WsdlBuilder implements IArtifactBuilder {
</xs:complexType>
</xs:element>
*/
- schema.appendChild(defineSchemaFor(attributeMetadata.getType(), attributeMetadata.getName()));
-
+ schema.appendChild(defineSchemaFor(attributeMetadata.getType(), attributeMetadata.getName()));
Element wsrpProperties = (Element) XPathAPI.selectSingleNode(
_document,
- "/wsdl:definitions/wsdl:types/xsd:schema[@targetNamespace='http://amqp.apache.org/qpid/management/qman']/xsd:element[@name='QManWsResourceProperties']/xsd:complexType/xsd:sequence");
+ "/wsdl:definitions/wsdl:types/xsd:schema[" +
+ "@targetNamespace='http://amqp.apache.org/qpid/management/qman']" +
+ "/xsd:element[@name='QManWsResourceProperties']/xsd:complexType/xsd:sequence");
- Element propertyRef= XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","element","xsd"));
- propertyRef.setAttribute("ref", "qman:"+attributeMetadata.getName());
+ Element propertyRef= XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ propertyRef.setAttribute(
+ "ref",
+ Names.PREFIX+":"+attributeMetadata.getName());
wsrpProperties.appendChild(propertyRef);
@@ -90,56 +107,95 @@ class WsdlBuilder implements IArtifactBuilder {
}
}
+ private final static QName XSD_ELEMENT_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"element","xsd");
+ private final static QName XSD_COMPLEX_TYPE_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"complexType","xsd");
+ private final static QName XSD_SEQUENCE_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"sequence","xsd");
+
private Element defineSchemaFor(String type, String attributeName) throws Exception
{
if (type.equals("java.util.Map"))
{
- Element prop = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","element","xsd"));
- prop.setAttribute("name",attributeName);
-
- Element complexType = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","complexType","xsd"));
+ if (!mapTypeHasBeenDeclared)
+ {
+ Element complexType = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
+ complexType.setAttribute("name","map");
+ Element sequence = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
+
+ Element entry = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ entry.setAttribute("name", "entry");
+ entry.setAttribute("minOccurs", "0");
+ entry.setAttribute("maxOccurs", "unbounded");
+
+ Element complexType2 = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
+ Element sequence2 = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
+
+ Element key = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ key.setAttribute("name", "key");
+ key.setAttribute("type", "xsd:string");
+
+ Element value = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ value.setAttribute("name", "value");
+ value.setAttribute("type", "xsd:anyType");
+
+ sequence2.appendChild(key);
+ sequence2.appendChild(value);
+ complexType2.appendChild(sequence2);
+ entry.appendChild(complexType2);
+ sequence.appendChild(entry);
+ complexType.appendChild(sequence);
+ schema.appendChild(complexType);
+ mapTypeHasBeenDeclared = true;
+ }
+ Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ propertyDeclaration.setAttribute("name",attributeName);
+ propertyDeclaration.setAttribute("type", "qman:map");
+ return propertyDeclaration;
- Element sequence = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","sequence","xsd"));
-
- Element entry = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","element","xsd"));
- entry.setAttribute("name", "entry");
- entry.setAttribute("minOccurs", "0");
- entry.setAttribute("maxOccurs", "unbounded");
-
- Element complexType2 = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","complexType","xsd"));
- Element sequence2 = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","sequence","xsd"));
-
- Element key = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","element","xsd"));
- key.setAttribute("name", "key");
- key.setAttribute("type", "xsd:string");
-
- Element value = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","element","xsd"));
- value.setAttribute("name", "value");
- value.setAttribute("type", "xsd:anyType");
-
- sequence2.appendChild(key);
- sequence2.appendChild(value);
- complexType2.appendChild(sequence2);
- entry.appendChild(complexType2);
- sequence.appendChild(entry);
- complexType.appendChild(sequence);
- prop.appendChild(complexType);
- return prop;
} else if ("java.util.UUID".equals(type))
{
- Element prop = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","element","xsd"));
- prop.setAttribute("name", attributeName);
- Element complexType = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","complexType","xsd"));
- Element sequence = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","sequence","xsd"));
- Element uuid = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","element","xsd"));
- uuid.setAttribute("name", "uuid");
- uuid.setAttribute("type", "xsd:string");
- sequence.appendChild(uuid);
- complexType.appendChild(sequence);
- prop.appendChild(complexType);
- return prop;
- } else {
- Element propertyDeclaration = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","element","xsd"));
+ if (!uuidTypeHasBeenDeclared)
+ {
+ Element complexType = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
+ complexType.setAttribute("name", "uuid");
+ Element sequence = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
+ Element uuid = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ uuid.setAttribute("name", "uuid");
+ uuid.setAttribute("type", "xsd:string");
+ sequence.appendChild(uuid);
+ complexType.appendChild(sequence);
+ schema.appendChild(complexType);
+ uuidTypeHasBeenDeclared = true;
+ }
+ Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ propertyDeclaration.setAttribute("name",attributeName);
+ propertyDeclaration.setAttribute("type", "qman:uuid");
+ return propertyDeclaration;
+ } else if (type.startsWith("["))
+ {
+ Class arrayClass = Class.forName(type);
+ Class clazz = ReflectUtils.getClassFromArrayClass(arrayClass);
+ String arrayType = arrayClass.getSimpleName().replace("[]", "").trim();
+ arrayType = Character.toUpperCase(arrayType.charAt(0))+arrayType.substring(1);
+ if (!arrayTypesAlreadyDeclared.containsKey(type))
+ {
+ Element complexType = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
+ complexType.setAttribute("name", "arrayOf"+arrayType);
+ Element sequence = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
+ Element entry = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ entry.setAttribute("name", "entry");
+ entry.setAttribute("type", serializer.getXmlType(clazz));
+ sequence.appendChild(entry);
+ complexType.appendChild(sequence);
+ schema.appendChild(complexType);
+ arrayTypesAlreadyDeclared.put(type, arrayType);
+ }
+ Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ propertyDeclaration.setAttribute("name",attributeName);
+ propertyDeclaration.setAttribute("type", "qman:arrayOf"+arrayTypesAlreadyDeclared.get(type));
+ return propertyDeclaration;
+ }
+ else {
+ Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
propertyDeclaration.setAttribute("name",attributeName);
propertyDeclaration.setAttribute("type", serializer.getXmlType(Class.forName(type)));
return propertyDeclaration;
@@ -158,7 +214,7 @@ class WsdlBuilder implements IArtifactBuilder {
StringBuilder builder = new StringBuilder("http://")
.append(InetAddress.getLocalHost().getHostName())
.append(':')
- .append(System.getProperty(Names.ADAPTER_PORT,"8080"))
+ .append(System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME,"8080"))
.append('/')
.append("qman")
.append('/')
@@ -218,14 +274,15 @@ class WsdlBuilder implements IArtifactBuilder {
statusCode.setAttribute("type", "xsd:long");
Element statusText = _document.createElement("xsd:element");
- statusCode.setAttribute("name", "statusText");
- statusCode.setAttribute("type", "xsd:string");
+ statusText.setAttribute("name", "statusText");
+ statusText.setAttribute("type", "xsd:string");
sequence.appendChild(statusCode);
sequence.appendChild(statusText);
Element outputParams = _document.createElement("xsd:complexType");
outputParams.setAttribute("name", "outputParameters");
+ sequence.appendChild(outputParams);
Element complexTypeOutput = _document.createElement("xsd:complexType");
Element outputSequence = _document.createElement("xsd:sequence");
@@ -243,9 +300,10 @@ class WsdlBuilder implements IArtifactBuilder {
Element entryComplexType = _document.createElement("xsd:complexType");
Element entrySequence = _document.createElement("xsd:sequence");
entryComplexType.appendChild(entrySequence);
+ entry.appendChild(entryComplexType);
Element name = _document.createElement("xsd:name");
- name.setAttribute("name", "name");
+ name.setAttribute("name", "key");
name.setAttribute("type", "xsd:string");
Element value = _document.createElement("xsd:element");
@@ -324,6 +382,7 @@ class WsdlBuilder implements IArtifactBuilder {
Element methodNameRequestComplexType = _document.createElement("xsd:complexType");
methodNameRequestComplexType.setAttribute("name", methodNameRequest);
Element methodNameRequestComplexTypeSequence = _document.createElement("xsd:sequence");
+
for(MBeanParameterInfo parameter : operationMetadata.getSignature())
{
methodNameRequestComplexTypeSequence.appendChild(defineSchemaFor(parameter.getType(), parameter.getName()));
@@ -340,7 +399,7 @@ class WsdlBuilder implements IArtifactBuilder {
Element result = _document.createElement("xsd:element");
result.setAttribute("name", "result");
- result.setAttribute("type", "qman:invocationResult");
+ result.setAttribute("type", "qman:result");
methodNameResponseSequence.appendChild(result);
schema.appendChild(methodNameResponseComplexType);
@@ -459,7 +518,7 @@ class WsdlBuilder implements IArtifactBuilder {
public Document getWsdl()
{
- XmlDebugger.debug(_objectName,_document);
+ WsdlDebugger.debug(_objectName,_document);
return _document;
}
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java
index 438c1d9db9..eb72bfc744 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java
@@ -67,18 +67,11 @@ public class WSDMAdapterEnvironment extends AbstractEnvironment
public String getDefaultURIPrefix()
{
- String host = null;
- try {
- host = InetAddress.getLocalHost().getHostName();
- } catch (UnknownHostException e) {
- host = "localhost";
- }
-
return new StringBuilder()
.append("http://")
- .append(host)
+ .append(System.getProperty(Names.ADAPTER_HOST_PROPERTY_NAME,"localhost"))
.append(":")
- .append(System.getProperty(Names.ADAPTER_PORT))
+ .append(System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME,"8080"))
.append(_servletContext.getContextPath())
.append("/services/")
.toString();
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java
index fc5f3fc7e4..78c3aea558 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java
@@ -321,16 +321,6 @@ public class QManWsResource implements WsResource
return _capabilitiesByURI.get(capabilityURI);
}
-// /**
-// * Returns all the WS-Action URIs supported by this resource.
-// *
-// * @return all of the WS-A Action URIs supported by this resource.
-// */
-// protected Collection getCapabilityActions()
-// {
-// return Collections.unmodifiableSet(_capabilitiesByAction.keySet());
-// }
-
/**
* Returns a collection with all registered capability URIs.
*
@@ -539,6 +529,10 @@ public class QManWsResource implements WsResource
}
catch (Throwable throwable)
{
+ LOGGER.error(
+ throwable,
+ Messages.QMAN_100037_INVOKE_OPERATION_FAILURE);
+
SoapFault response = SoapUtils.convertToFault(
(throwable.getCause()!= null)
? throwable.getCause()
@@ -725,15 +719,20 @@ public class QManWsResource implements WsResource
for (Element element : additionalProperties)
{
- rmdDoc.adoptNode(element);
- metadataDescriptor.appendChild(element);
+
+// rmdDoc.importNode(element, true);
+ Element adopted = (Element) rmdDoc.importNode(element,false);
+ metadataDescriptor.appendChild(adopted);
}
return new SimpleMetadataDescriptor(metadataDescriptor);
}
catch(Exception exception)
{
- LOGGER.error(exception,Messages.QMAN_100021_RMD_BUID_FAILURE,getContextPath());
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100021_RMD_BUID_FAILURE,
+ getContextPath());
throw new SoapFault(exception);
}
}
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/DateSerializer.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/DateSerializer.java
new file mode 100644
index 0000000000..60350ccc31
--- /dev/null
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/DateSerializer.java
@@ -0,0 +1,75 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm.muse.serializer;
+
+import java.util.Date;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.w3c.dom.Element;
+
+/**
+ * Implementation of Muse Serializer for Date type.
+ * Note that Muse already ships a serializer but the formatter used on that class
+ * is losing precision betweem marshal / unmarshal operations.
+ *
+ * @author Andrea Gazzarini
+ */
+public class DateSerializer implements Serializer
+{
+ /**
+ * Return a Date representation of the given xml element.
+ *
+ * @param xml the element to unmarshal.
+ * @throws SoapFault when the unmarshalling fails.
+ */
+ public Object fromXML(Element elementData) throws SoapFault
+ {
+ return new Date(Long.parseLong(elementData.getTextContent()));
+ }
+
+ /**
+ * Returns the java type associated to this class.
+ *
+ * @return the java type associated to this class.
+ */
+ public Class<?> getSerializableType()
+ {
+ return Date.class;
+ }
+
+ /**
+ * Return an xml representation of the given UUID with the given name.
+ *
+ * @param object the UUID to marshal.
+ * @param qname the qualified (xml) name of the object to use in xml representation.
+ * @return the xml representation of the UUID.
+ * @throws SoapFault when the marshalling fails.
+ */
+ public Element toXML(Object obj, QName qname) throws SoapFault
+ {
+ Date date = (Date) obj;
+ return XmlUtils.createElement(qname, String.valueOf(date.getTime()));
+ }
+} \ No newline at end of file
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java
index 5e208a281d..0af570eacf 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java
@@ -38,7 +38,6 @@ import org.w3c.dom.Element;
*/
public class InvocationResultSerializer implements Serializer
{
-
private Serializer _longSerializer = SerializerRegistry.getInstance().getSerializer(long.class);
private Serializer _stringSerializer = SerializerRegistry.getInstance().getSerializer(String.class);
private Serializer _mapSerializer = SerializerRegistry.getInstance().getSerializer(Map.class);
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java
index 6a404d45b9..1d0d02c669 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java
@@ -49,7 +49,9 @@ import org.w3c.dom.Element;
public class MapSerializer implements Serializer
{
- ByteArraySerializer byteArraySerializer = new ByteArraySerializer();
+ ByteArraySerializer _byteArraySerializer = new ByteArraySerializer();
+ Serializer _objectSerializer = SerializerRegistry.getInstance().getSerializer(Object.class);
+ Serializer _stringSerializer = SerializerRegistry.getInstance().getSerializer(String.class);
/**
* Return a map representation of the given xml element.
@@ -70,10 +72,10 @@ public class MapSerializer implements Serializer
Object value = null;
for (Element element : keysAndValues)
{
- if (Names.KEY.equals(element.getNodeName()))
+ if (Names.KEY.equals(element.getLocalName()))
{
- key = objectDeserializer.fromXML(element);
- } else if (Names.VALUE.equals(element.getNodeName()))
+ key = _stringSerializer.fromXML(element);
+ } else if (Names.VALUE.equals(element.getLocalName()))
{
value = objectDeserializer.fromXML(element);
}
@@ -103,23 +105,23 @@ public class MapSerializer implements Serializer
*/
public Element toXML(Object obj, QName qname) throws SoapFault
{
- Serializer objectSerializer = SerializerRegistry.getInstance().getSerializer(Object.class);
+
Map<?, ?> data = (Map<?, ?>) obj;
- QName entryQName = new QName(Names.ENTRY);
- QName keyQName = new QName(Names.KEY);
- QName valueQName = new QName(Names.VALUE);
+ QName entryQName = new QName(qname.getNamespaceURI(),Names.ENTRY,qname.getPrefix());
+ QName keyQName = new QName(qname.getNamespaceURI(),Names.KEY,qname.getPrefix());
+ QName valueQName = new QName(qname.getNamespaceURI(),Names.VALUE,qname.getPrefix());
Element root = XmlUtils.createElement(qname);
root.setAttribute("xmlns:xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
for (Entry<?, ?> mapEntry: data.entrySet())
{
Element entry = XmlUtils.createElement(entryQName);
- entry.appendChild(objectSerializer.toXML(mapEntry.getKey(), keyQName));
+ entry.appendChild(_stringSerializer.toXML(mapEntry.getKey(), keyQName));
if (mapEntry.getValue().getClass() == byte[].class) {
- entry.appendChild(byteArraySerializer.toXML(mapEntry.getValue(), valueQName));
+ entry.appendChild(_byteArraySerializer.toXML(mapEntry.getValue(), valueQName));
} else {
- entry.appendChild(objectSerializer.toXML(mapEntry.getValue(), valueQName));
+ entry.appendChild(_objectSerializer.toXML(mapEntry.getValue(), valueQName));
}
root.appendChild(entry);
}
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ObjectSerializer.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ObjectSerializer.java
index 7569ace181..ff0c69cdda 100644
--- a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ObjectSerializer.java
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ObjectSerializer.java
@@ -24,6 +24,7 @@ import java.net.URI;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
+import java.util.UUID;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
@@ -47,49 +48,70 @@ public class ObjectSerializer implements Serializer
private Map<String, Class<?>> xml2Java = new HashMap<String, Class<?>>();
{
xml2Java.put("xsd:long", Long.class);
- xml2Java.put("xsd:long", long.class);
xml2Java.put("xsd:boolean",Boolean.class);
- xml2Java.put("xsd:boolean",boolean.class);
- xml2Java.put("xsd:double",Double.class);
xml2Java.put("xsd:double",Double.class);
xml2Java.put("xsd:float",Float.class);
- xml2Java.put("xsd:float",float.class);
xml2Java.put("xsd:integer",Integer.class);
- xml2Java.put("xsd:integer",int.class);
xml2Java.put("xsd:int",Integer.class);
- xml2Java.put("xsd:int",int.class);
xml2Java.put("xsd:short",Short.class);
- xml2Java.put("xsd:short",short.class);
xml2Java.put("xsd:string",String.class);
xml2Java.put("xsd:anyURI",URI.class);
- xml2Java.put("xsd:dateTime",URI.class);
+ xml2Java.put("xsd:dateTime",Date.class);
xml2Java.put("xsd:QName",QName.class);
xml2Java.put("xsd:element",Element.class);
xml2Java.put("xsd:base64Binary",byte[].class);
+ xml2Java.put("qman:arrayOfLong",Long[].class);
+ xml2Java.put("qman:arrayOfBoolean",Boolean[].class);
+ xml2Java.put("qman:arrayOfDouble",Double[].class);
+ xml2Java.put("qman:arrayOfFloat",Float[].class);
+ xml2Java.put("qman:arrayOfInteger",Integer[].class);
+ xml2Java.put("qman:arrayOfShort",Short[].class);
+ xml2Java.put("qman:arrayOfString",String[].class);
+ xml2Java.put("qman:arrayOfURI",URI[].class);
+ xml2Java.put("qman:arrayOfDate",Date[].class);
+ xml2Java.put("qman:uuid",UUID.class);
+ xml2Java.put("qman:map",Map.class);
+ xml2Java.put("qman:map",HashMap.class);
}
private Map<Class<?>, String> java2Xml = new HashMap<Class<?>, String>();
- {
+ {
+ java2Xml.put(UUID.class,"qman:uuid");
java2Xml.put(Long.class,"xsd:long");
java2Xml.put(long.class,"xsd:long");
java2Xml.put(Boolean.class,"xsd:boolean");
- java2Xml.put(Boolean.class,"xsd:boolean");
- java2Xml.put(Double.class,"xsd:double");
+ java2Xml.put(boolean.class,"xsd:boolean");
java2Xml.put(Double.class,"xsd:double");
+ java2Xml.put(double.class,"xsd:double");
java2Xml.put(Float.class,"xsd:float");
- java2Xml.put(Float.class,"xsd:float");
- java2Xml.put(Integer.class,"xsd:integer");
+ java2Xml.put(float.class,"xsd:float");
java2Xml.put(Integer.class,"xsd:integer");
- java2Xml.put(Integer.class,"xsd:int");
- java2Xml.put(Integer.class,"xsd:int");
- java2Xml.put(Short.class,"xsd:short");
+ java2Xml.put(int.class,"xsd:integer");
java2Xml.put(Short.class,"xsd:short");
+ java2Xml.put(short.class,"xsd:short");
java2Xml.put(String.class,"xsd:string");
java2Xml.put(URI.class,"xsd:anyURI");
java2Xml.put(Date.class,"xsd:dateTime");
java2Xml.put(QName.class,"xsd:QName");
java2Xml.put(Element.class,"xsd:element");
java2Xml.put(byte[].class,"xsd:base64Binary");
+ java2Xml.put(Long[].class,"qman:arrayOfLong");
+ java2Xml.put(long[].class,"qman:arrayOfLong");
+ java2Xml.put(Boolean[].class,"qman:arrayOfBoolean");
+ java2Xml.put(boolean[].class,"qman:arrayOfBoolean");
+ java2Xml.put(Double[].class,"qman:arrayOfDouble");
+ java2Xml.put(double[].class,"qman:arrayOfDouble");
+ java2Xml.put(Float[].class,"qman:arrayOfFloat");
+ java2Xml.put(float[].class,"qman:arrayOfFloat");
+ java2Xml.put(Integer[].class,"qman:arrayOfInteger");
+ java2Xml.put(int[].class,"qman:arrayOfInteger");
+ java2Xml.put(Short[].class,"qman:arrayOfShort");
+ java2Xml.put(short[].class,"qman:arrayOfShort");
+ java2Xml.put(String[].class,"qman:arrayOfString");
+ java2Xml.put(URI[].class,"qman:arrayOfURI");
+ java2Xml.put(Date[].class,"qman:arrayOfDate");
+ java2Xml.put(Map.class,"qman:map");
+ java2Xml.put(HashMap.class,"qman:map");
}
/**
@@ -113,14 +135,18 @@ public class ObjectSerializer implements Serializer
{
throw new SoapFault(
"No type attribute was found for the current element. " +
- "If you are using this serializer, in order to unmarshal the opportune type the xsi:type must be specified.");
+ "If you are using this serializer, in order to unmarshal the" +
+ " opportune type the xsi:type must be specified.");
}
Class<?> clazz = xml2Java.get(typeAttribute.getValue());
if (clazz == null)
{
- throw new SoapFault(String.format("No corresponding class was found on this serializer mappings for xsi:type %s.",typeAttribute));
+ throw new SoapFault(
+ String.format(
+ "No corresponding class was found on this serializer mappings for xsi:type %s.",
+ typeAttribute));
}
if (clazz == byte[].class) {
@@ -155,7 +181,8 @@ public class ObjectSerializer implements Serializer
if (clazz == byte[].class) {
result = new ByteArraySerializer().toXML(obj,qname);
- } else {
+ }
+ else {
result = SerializerRegistry.getInstance().getSerializer(clazz).toXML(obj,qname);
}
result.setAttribute(Names.XSI_TYPE, java2Xml.get(clazz));
diff --git a/java/management/client/src/main/java/org/apache/qpid/qman/debug/WsdlDebugger.java b/java/management/client/src/main/java/org/apache/qpid/qman/debug/WsdlDebugger.java
new file mode 100644
index 0000000000..398a69817b
--- /dev/null
+++ b/java/management/client/src/main/java/org/apache/qpid/qman/debug/WsdlDebugger.java
@@ -0,0 +1,49 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.qman.debug;
+
+import javax.management.ObjectName;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.qpid.transport.util.Logger;
+import org.w3c.dom.Node;
+
+/**
+ * Utility class used for debbugging WSDL documents
+ *
+ * @author Andrea Gazzarini
+ */
+public class WsdlDebugger {
+ public final static Logger LOGGER = Logger.get(WsdlDebugger.class);
+
+ /**
+ * Prints out to log the given node.
+ *
+ * @param node the xml node to be printed out.
+ */
+ public static void debug(ObjectName resourceId, Node node)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(resourceId+" : "+XmlUtils.toString(node, false,true));
+ }
+ }
+} \ No newline at end of file
diff --git a/java/management/client/src/test/java/log4j.xml b/java/management/client/src/test/java/log4j.xml
new file mode 100644
index 0000000000..da47cadb80
--- /dev/null
+++ b/java/management/client/src/test/java/log4j.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+ <!-- Write to stdout -->
+ <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+ <param name="Target" value="System.out" />
+ <param name="Threshold" value="DEBUG" />
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern"
+ value="%d{ABSOLUTE} %-5p [%c{1}] %m%n" />
+ </layout>
+ </appender>
+
+ <category name="org">
+ <priority value="ERROR" />
+ <appender-ref ref="CONSOLE" />
+ </category>
+ <root>
+ <priority value="ERROR" />
+ </root>
+
+</log4j:configuration> \ No newline at end of file
diff --git a/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java b/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java
index 56195b6f20..d7ecd707fe 100644
--- a/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java
+++ b/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java
@@ -64,4 +64,7 @@ public interface TestConstants
String YEARS = "years";
int SAMPLE_MIN_VALUE = 1;
int SAMPLE_MAX_VALUE = 120;
-}
+
+ String DEFAULT_HOST = "localhost";
+ int DEFAULT_PORT = 8080;
+} \ No newline at end of file
diff --git a/java/management/client/src/test/java/org/apache/qpid/management/wsdm/EnhancedReflectionProxyHandler.java b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/EnhancedReflectionProxyHandler.java
new file mode 100644
index 0000000000..732f110ba3
--- /dev/null
+++ b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/EnhancedReflectionProxyHandler.java
@@ -0,0 +1,67 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.wsdm.muse.serializer.ByteArraySerializer;
+import org.w3c.dom.Element;
+
+/**
+ * Custom implementation of Muse ReflectionProxyHandler that uses a base64 serializer
+ * for byte arrays.
+ *
+ * @author Andrea Gazzarini
+ */
+public class EnhancedReflectionProxyHandler extends ReflectionProxyHandler
+{
+ @Override
+ protected Element serialize(Object obj, QName qname) throws SoapFault
+ {
+ if (obj == null)
+ {
+ return XmlUtils.createElement(qname);
+ }
+
+ if (obj.getClass() == byte[].class)
+ {
+ return new ByteArraySerializer().toXML(obj, qname);
+ } else
+ {
+ return super.serialize(obj, qname);
+ }
+ }
+
+ @Override
+ protected Object deserialize(Element xml, Class theClass) throws SoapFault
+ {
+ if (theClass == byte[].class)
+ {
+ return new ByteArraySerializer().fromXML(xml);
+ } else
+ {
+ return super.deserialize(xml, theClass);
+ }
+ }
+} \ No newline at end of file
diff --git a/java/management/client/src/test/java/org/apache/qpid/management/wsdm/ServerThread.java b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/ServerThread.java
new file mode 100644
index 0000000000..ff7d9b5a8a
--- /dev/null
+++ b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/ServerThread.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm;
+
+import java.io.File;
+
+import org.apache.qpid.management.Names;
+import org.mortbay.component.LifeCycle.Listener;
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.jetty.webapp.WebAppContext;
+import org.mortbay.start.Monitor;
+
+public class ServerThread extends Thread
+{
+ private final Listener _lifecycleListener;
+ private Server server;
+ ServerThread(Listener listener)
+ {
+ this._lifecycleListener = listener;
+ }
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ Monitor.monitor();
+ server = new Server();
+ server.setStopAtShutdown(true);
+
+ Connector connector=new SelectChannelConnector();
+ connector.setPort(
+ Integer.parseInt(
+ System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME)));
+ connector.setHost(System.getProperty(Names.ADAPTER_HOST_PROPERTY_NAME));
+
+ server.setConnectors(new Connector[]{connector});
+
+ WebAppContext webapp = new WebAppContext();
+// webapp.setExtractWAR(false);
+ webapp.setContextPath("/qman");
+ webapp.setDefaultsDescriptor("/org/apache/qpid/management/wsdm/web.xml");
+
+ String webApplicationPath = System.getProperty("qman.war");
+ File rootFolderPath = (webApplicationPath != null) ? new File(webApplicationPath) : new File(".");
+
+ webapp.setWar(rootFolderPath.toURI().toURL().toExternalForm());
+ webapp.addLifeCycleListener(_lifecycleListener);
+ server.setHandler(webapp);
+ server.start();
+ server.join();
+ } catch(Exception exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ public void shutdown() throws Exception
+ {
+ server.stop();
+ }
+}
diff --git a/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WebApplicationLifeCycleListener.java b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WebApplicationLifeCycleListener.java
new file mode 100644
index 0000000000..3a0bbb608a
--- /dev/null
+++ b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WebApplicationLifeCycleListener.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.wsdm;
+import org.mortbay.component.LifeCycle;
+import org.mortbay.component.LifeCycle.Listener;
+
+/**
+ * Adapter class used to provide an empty (base) implementation of
+ * Lifecycle listener interface.
+ *
+ * @author Andrea Gazzarini
+ */
+public class WebApplicationLifeCycleListener implements Listener
+{
+ public void lifeCycleFailure(LifeCycle event, Throwable cause)
+ {
+ }
+
+ public void lifeCycleStarted(LifeCycle event)
+ {
+ }
+
+ public void lifeCycleStarting(LifeCycle event)
+ {
+ }
+
+ public void lifeCycleStopped(LifeCycle event)
+ {
+ }
+
+ public void lifeCycleStopping(LifeCycle event)
+ {
+ }
+} \ No newline at end of file
diff --git a/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java
new file mode 100644
index 0000000000..8a4434bee1
--- /dev/null
+++ b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java
@@ -0,0 +1,1026 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm;
+
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.xml.namespace.QName;
+
+import junit.extensions.TestSetup;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.TestConstants;
+import org.apache.qpid.management.wsdm.capabilities.Result;
+import org.apache.qpid.management.wsdm.muse.serializer.DateSerializer;
+import org.apache.qpid.management.wsdm.muse.serializer.InvocationResultSerializer;
+import org.apache.qpid.management.wsdm.muse.serializer.MapSerializer;
+import org.apache.qpid.management.wsdm.muse.serializer.ObjectSerializer;
+import org.apache.qpid.management.wsdm.muse.serializer.UUIDSerializer;
+import org.mortbay.component.LifeCycle;
+import org.mortbay.component.LifeCycle.Listener;
+import org.w3c.dom.Element;
+
+/**
+ * Test case for WS-Resource lifecycle management.
+ *
+ * @author Andrea Gazzarini
+ */
+public class WsDmAdapterTest extends TestCase {
+
+ private MBeanServer _managementServer;
+ private ObjectName _resourceObjectName;
+
+ private WsResourceClient _resourceClient;
+ private MBeanInfo _mbeanInfo;
+
+ private Map<String, ProxyHandler> _invocationHandlers = createInvocationHandlers();
+ final Long retCodeOk = new Long(0);
+
+ /**
+ * Test case wide set up.
+ * Provides Server startup & shutdown global procedure.
+ *
+ * @author Andrea Gazzarini
+ */
+ private static class WsDmAdapterTestSetup extends TestSetup
+ {
+ private Object _serverMonitor = new Object();
+
+ Listener listener = new WebApplicationLifeCycleListener()
+ {
+ public void lifeCycleStarted(LifeCycle event)
+ {
+ synchronized (_serverMonitor)
+ {
+ _serverMonitor.notify();
+ }
+ }
+ };
+
+ private ServerThread server;
+
+ /**
+ * Builds a new test setup with for the given test.
+ *
+ * @param test the decorated test.
+ */
+ public WsDmAdapterTestSetup(Test test)
+ {
+ super(test);
+ }
+
+ /**
+ * Starts up Web server.
+ *
+ * @throws Exception when the server startup fails.
+ */
+ @Override
+ protected void setUp() throws Exception
+ {
+ SerializerRegistry.getInstance().registerSerializer(Object.class, new ObjectSerializer());
+ SerializerRegistry.getInstance().registerSerializer(Date.class, new DateSerializer());
+ SerializerRegistry.getInstance().registerSerializer(Map.class, new MapSerializer());
+ SerializerRegistry.getInstance().registerSerializer(HashMap.class, new MapSerializer());
+ SerializerRegistry.getInstance().registerSerializer(UUID.class, new UUIDSerializer());
+ SerializerRegistry.getInstance().registerSerializer(Result.class, new InvocationResultSerializer());
+
+ System.setProperty(
+ Names.ADAPTER_PORT_PROPERTY_NAME,
+ String.valueOf(TestConstants.DEFAULT_PORT));
+
+ System.setProperty(
+ Names.ADAPTER_HOST_PROPERTY_NAME,
+ TestConstants.DEFAULT_HOST);
+
+ server = new ServerThread(listener);
+ server.start();
+
+ synchronized(_serverMonitor) {
+ _serverMonitor.wait();
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ server.shutdown();
+ }
+ };
+
+ /**
+ * Set up fixture for this test case.
+ *
+ * @throws Exception when the test case intialization fails.
+ */
+ protected void setUp() throws Exception
+ {
+ _managementServer = ManagementFactory.getPlatformMBeanServer();
+
+ ServiceGroupClient serviceGroup = getServiceGroupClient();
+ WsResourceClient [] members = serviceGroup.getMembers();
+
+ assertEquals(
+ "No resource has been yet created so how is " +
+ "it possible that service group children list is not empty?",
+ 0,
+ members.length);
+
+ _managementServer.invoke(
+ Names.QPID_EMULATOR_OBJECT_NAME,
+ "createQueue", new Object[]{_resourceObjectName = createResourceName()},
+ new String[]{ObjectName.class.getName()});
+
+ members = serviceGroup.getMembers();
+ assertEquals(
+ "One resource has just been created so " +
+ "I expect to find it on service group children list...",
+ 1,
+ members.length);
+
+ _resourceClient = members[0];
+ _mbeanInfo = _managementServer.getMBeanInfo(_resourceObjectName);
+ }
+
+ /**
+ * Shutdown procedure for this test case.
+ *
+ * @throws Exception when either the server or some resource fails to shutdown.
+ */
+ @Override
+ protected void tearDown() throws Exception
+ {
+ ServiceGroupClient serviceGroup = getServiceGroupClient();
+ WsResourceClient [] members = serviceGroup.getMembers();
+
+ _managementServer.invoke(
+ Names.QPID_EMULATOR_OBJECT_NAME,
+ "unregister",
+ new Object[]{_resourceObjectName},
+ new String[]{ObjectName.class.getName()});
+
+ members = serviceGroup.getMembers();
+
+ assertEquals(
+ "No resource has been yet created so how is it possible that service group children list is not empty?",
+ 0,
+ members.length);
+ }
+
+ /**
+ * Test the WS-RP GetResourceProperty interface of the WS-DM adapter.
+ *
+ * <br>precondition : a ws resource exists and is registered.
+ * <br>postcondition : property values coming from WS-DM resource are the same of the JMX interface.
+ */
+ public void testGeResourcePropertiesOK() throws Exception
+ {
+ MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
+ for (MBeanAttributeInfo attributeMetadata : attributesMetadata)
+ {
+ String name = attributeMetadata.getName();
+ Object propertyValues = _resourceClient.getPropertyAsObject(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ Class.forName(attributeMetadata.getType()));
+
+ int length = Array.getLength(propertyValues);
+ if (length != 0)
+ {
+ Object propertyValue = Array.get(propertyValues, 0);
+
+ assertEquals(
+ "Comparison failed for property "+name,
+ _managementServer.getAttribute(_resourceObjectName,name),
+ propertyValue);
+ } else {
+ assertNull(
+ String.format(
+ "\"%s\" property value shouldn't be null. Its value is %s",
+ name,
+ _managementServer.getAttribute(_resourceObjectName,name)),
+ _managementServer.getAttribute(_resourceObjectName,name));
+ }
+ }
+ }
+
+ /**
+ * Test the WS-RP SetResourceProperty interface of the WS-DM adapter.
+ *
+ * <br>precondition : a WS-Resource exists and is registered.
+ * <br>postcondition : property values are correctly updated on the target WS-Resource..
+ */
+ public void testSetResourcePropertiesOK() throws Exception
+ {
+ Map<String, Object> sampleMap = new HashMap<String, Object>();
+ sampleMap.put("Key1", "BLABALABLABALBAL");
+ sampleMap.put("Key2", 182838484l);
+ sampleMap.put("Key3", -928376362);
+ sampleMap.put("Key4", 23762736276.33D);
+ sampleMap.put("Key4", 2327363.2F);
+
+ Map<String, Object> sampleValues = new HashMap<String, Object>();
+ sampleValues.put(String.class.getName(),"SAMPLE_STRING");
+ sampleValues.put(UUID.class.getName(),UUID.randomUUID());
+ sampleValues.put(Boolean.class.getName(),Boolean.FALSE);
+ sampleValues.put(Map.class.getName(),sampleMap);
+ sampleValues.put(Long.class.getName(),283781273L);
+ sampleValues.put(Integer.class.getName(),12727);
+ sampleValues.put(Short.class.getName(),new Short((short)22));
+ sampleValues.put(Date.class.getName(),new Date());
+
+ MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
+ boolean atLeastThereIsOneWritableProperty = false;
+
+ for (MBeanAttributeInfo attributeMetadata : attributesMetadata)
+ {
+ String name = attributeMetadata.getName();
+
+ if (attributeMetadata.isWritable())
+ {
+ atLeastThereIsOneWritableProperty = true;
+ Object sampleValue = sampleValues.get(attributeMetadata.getType());
+ Object []values = new Object[]{sampleValue};
+
+ Object result = _managementServer.getAttribute(_resourceObjectName, name);
+ if (result == null)
+ {
+ _resourceClient.insertResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ values);
+ } else
+ {
+ _resourceClient.updateResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ values);
+ }
+
+ Object propertyValues = _resourceClient.getPropertyAsObject(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ Class.forName(attributeMetadata.getType()));
+ int length = Array.getLength(propertyValues);
+ if (length != 0)
+ {
+ Object propertyValue = Array.get(propertyValues, 0);
+
+ assertEquals(
+ "Comparison failed for property "+name,
+ sampleValue,
+ propertyValue);
+ } else {
+ assertNull(
+ String.format(
+ "\"%s\" property value shouldn't be null. Its value is %s",
+ name,
+ _managementServer.getAttribute(_resourceObjectName,name)),
+ sampleValue);
+ }
+ }
+ }
+ assertTrue(
+ "It's not possibile to run successfully this test case if " +
+ "the target WS-Resource has no at least one writable property",
+ atLeastThereIsOneWritableProperty);
+ }
+
+ /**
+ * Test the WS-RP SetResourceProperty interface of the WS-DM adapter when the
+ * target property is null.
+ * According to WS-RP specs this operation is not allowed because in this case a SetResourceProperty with an "Insert"
+ * message should be sent in order to initialize the property.
+ *
+ * <br>precondition : a ws resource exists and is registered. The value of the target property is null.
+ * <br>postcondition : a Soap fault is received indicating the failuire.
+ */
+ public void testSetResourcePropertiesKO() throws Exception
+ {
+ Object typePropertyValue = _managementServer.getAttribute(_resourceObjectName, "Type");
+ assertNull(typePropertyValue);
+
+ try
+ {
+ _resourceClient.updateResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ "Type",
+ Names.PREFIX),
+ new Object[]{"sampleValue"});
+ fail(
+ "If the property is null on the target ws resource, according " +
+ "to WS-RP specs, an update of its value is not possible.");
+ } catch(SoapFault expected)
+ {
+
+ }
+ }
+
+// public void testGetAndPutResourcePropertyDocumentOK() throws Exception
+// {
+// Element properties = _resourceClient.getResourcePropertyDocument();
+//
+// Element mgmtPubInterval = XmlUtils.getElement(properties, new QName(Names.NAMESPACE_URI,"MgmtPubInterval",Names.PREFIX));
+// mgmtPubInterval.setTextContent(String.valueOf(Long.MAX_VALUE));
+//
+// Element durable = XmlUtils.getElement(properties, new QName(Names.NAMESPACE_URI,"Durable",Names.PREFIX));
+// durable.setTextContent(String.valueOf(Boolean.FALSE));
+//
+// Element consumerCount = XmlUtils.getElement(properties, new QName(Names.NAMESPACE_URI,"ConsumerCount",Names.PREFIX));
+// consumerCount.setTextContent(String.valueOf(13));
+//
+// fail("PutResourcePropertyDocument not yet implemented!");
+//// _resourceClient.putResourcePropertyDocument(properties);
+////
+//// Element newProperties = _resourceClient.getResourcePropertyDocument();
+////
+//// assertEquals(properties,newProperties);
+// }
+
+ /**
+ * Test the WS-RP GetResourceProperties interface of the WS-DM adapter.
+ *
+ * <br>precondition : a ws resource exists and is registered.
+ * <br>postcondition : Properties are correctly returned according to WSRP interface and they (their value)
+ * are matching with corresponding MBean properties.
+ */
+ public void testGetMultipleResourcePropertiesOK() throws Exception
+ {
+ MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
+ QName[] names = new QName[attributesMetadata.length];
+
+ int index = 0;
+ for (MBeanAttributeInfo attributeMetadata : _mbeanInfo.getAttributes())
+ {
+ QName qname = new QName(Names.NAMESPACE_URI,attributeMetadata.getName(),Names.PREFIX);
+ names[index++] = qname;
+ }
+
+ Element[] properties =_resourceClient.getMultipleResourceProperties(names);
+ for (Element element : properties)
+ {
+ String name = element.getLocalName();
+ Object value = _managementServer.getAttribute(_resourceObjectName, name);
+ if ("Name".equals(name))
+ {
+ assertEquals(
+ value,
+ element.getTextContent());
+ } else if ("Durable".equals(name))
+ {
+ assertEquals(
+ value,
+ Boolean.valueOf(element.getTextContent()));
+ } else if ("ExpireTime".equals(name))
+ {
+ assertEquals(
+ value,
+ new Date(Long.valueOf(element.getTextContent())));
+ } else if ("MsgTotalEnqueues".equals(name))
+ {
+ assertEquals(
+ value,
+ Long.valueOf(element.getTextContent()));
+ } else if ("ConsumerCount".equals(name))
+ {
+ assertEquals(
+ value,
+ Integer.valueOf(element.getTextContent()));
+ }else if ("VhostRef".equals(name))
+ {
+ assertEquals(
+ value,
+ UUID.fromString(element.getTextContent()));
+ }
+ }
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of simple types between requestor and service provider.
+ * With simple types we mean :
+ *
+ * <ul>
+ * <li>java.lang.Long / long (xsd:long)
+ * <li>java.lang.Integer / int (xsd:int / xsd:integer)
+ * <li>java.lang.Double/ double (xsd:double)
+ * <li>java.lang.Float / float (xsd:float)
+ * <li>java.lang.Short / short (xsd:short)
+ * <li>java.lang.Boolean / boolean (xsd:boolean)
+ * <li>java.lang.String (xsd:string)
+ * <li>java.net.URI (xsd:anyURI)
+ * <li>java.util.Date(xsd:dateTime)
+ * </ul>
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withSimpleTypes() throws Exception
+ {
+ Long expectedLongResult = new Long(1373);
+ Boolean expectedBooleanResult = Boolean.TRUE;
+ Double expectedDoubleResult = new Double(12763.44);
+ Float expectedFloatResult = new Float(2727.233f);
+ Integer expectedIntegerResult = new Integer(28292);
+ Short expectedShortResult = new Short((short)227);
+ String expectedStringResult = "expectedStringResult";
+ URI expectedUriResult = URI.create("http://qpid.apache.org/");
+ Date expectedDateResult = new Date();
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithSimpleTypes"),
+ new Object[]{
+ expectedLongResult,
+ expectedBooleanResult,
+ expectedDoubleResult,
+ expectedFloatResult,
+ expectedIntegerResult,
+ expectedShortResult,
+ expectedStringResult,
+ expectedUriResult,
+ expectedDateResult});
+
+ Method getStatusCode = result.getClass().getMethod("getStatusCode");
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+ assertEquals(retCodeOk,getStatusCode.invoke(result));
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 9.",9,out.size());
+ assertTrue("Long output parameter not found on result object.",out.containsValue(expectedLongResult));
+ assertTrue("Boolean output parameter not found on result object.",out.containsValue(expectedBooleanResult));
+ assertTrue("Double output parameter not found on result object.",out.containsValue(expectedDoubleResult));
+ assertTrue("Float output parameter not found on result object.",out.containsValue(expectedFloatResult));
+ assertTrue("Integer output parameter not found on result object.",out.containsValue(expectedIntegerResult));
+ assertTrue("Short output parameter not found on result object.",out.containsValue(expectedShortResult));
+ assertTrue("String output parameter not found on result object.",out.containsValue(expectedStringResult));
+ assertTrue("URI output parameter not found on result object.",out.containsValue(expectedUriResult));
+ assertTrue("Date output parameter not found on result object.",out.containsValue(expectedDateResult));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of arrays between requestor and service provider.
+ * For this test exchanged arrays contain :
+ *
+ * <ul>
+ * <li>java.lang.Long (xsd:long)
+ * <li>java.lang.Integer (xsd:int / xsd:integer)
+ * <li>java.lang.Double (xsd:double)
+ * <li>java.lang.Float (xsd:float)
+ * <li>java.lang.Short (xsd:short)
+ * <li>java.lang.Boolean (xsd:boolean)
+ * <li>java.lang.String (xsd:string)
+ * <li>java.net.URI (xsd:anyURI)
+ * <li>java.util.Date(xsd:dateTime)
+ * </ul>
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withWrapperArrays() throws Exception
+ {
+ Long [] expectedLongResult = {new Long(2),new Long(1),new Long(3),new Long(4)};
+ Boolean [] expectedBooleanResult = { Boolean.TRUE,Boolean.FALSE,Boolean.FALSE};
+ Double [] expectedDoubleResult = {12763.44d,2832.33d,2292.33d,22293.22d};
+ Float [] expectedFloatResult = {2727.233f,1f,2f,4f,5.4f,33.2f};
+ Integer [] expectedIntegerResult = {1,2,3,4,55,66,77,88,99};
+ Short [] expectedShortResult = {(short)227,(short)23,(short)9};
+ String [] expectedStringResult = {"s1","s2","s333","s4"};
+ URI [] expectedUriResult = {
+ URI.create("http://qpid.apache.org/"),
+ URI.create("http://www.apache.org"),
+ URI.create("http://projects.apache.org")};
+
+ Date [] expectedDateResult = {
+ new Date(),
+ new Date(38211897),
+ new Date(903820382)};
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithArrays"),
+ new Object[]{
+ expectedLongResult,
+ expectedBooleanResult,
+ expectedDoubleResult,
+ expectedFloatResult,
+ expectedIntegerResult,
+ expectedShortResult,
+ expectedStringResult,
+ expectedUriResult,
+ expectedDateResult});
+
+ Method getStatusCode = result.getClass().getMethod("getStatusCode");
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+ assertEquals(retCodeOk,getStatusCode.invoke(result));
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 9.",9,out.size());
+ assertTrue("Long array doesn't match.",Arrays.equals(expectedLongResult, (Long[])out.get(Long.class.getName())));
+ assertTrue("Boolean array doesn't match.",Arrays.equals(expectedBooleanResult, (Boolean[])out.get(Boolean.class.getName())));
+ assertTrue("Double array doesn't match.",Arrays.equals(expectedDoubleResult, (Double[])out.get(Double.class.getName())));
+ assertTrue("Float array doesn't match.",Arrays.equals(expectedFloatResult, (Float[])out.get(Float.class.getName())));
+ assertTrue("Integer array doesn't match.", Arrays.equals(expectedIntegerResult, (Integer[])out.get(Integer.class.getName())));
+ assertTrue("Short array doesn't match.",Arrays.equals(expectedShortResult, (Short[])out.get(Short.class.getName())));
+ assertTrue("String array doesn't match.",Arrays.equals(expectedStringResult, (String[])out.get(String.class.getName())));
+ assertTrue("URI array doesn't match.",Arrays.equals(expectedUriResult, (URI[])out.get(URI.class.getName())));
+ assertTrue("Date array doesn't match.",Arrays.equals(expectedDateResult, (Date[])out.get(Date.class.getName())));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of primitive type arrays between requestor and service provider.
+ * NOte that even the sent array contain primtiive type QMan deals only with objects so in the result
+ * object you will find the corresponding wrapper types.
+ *
+ * For this test exchanged arrays contain :
+ *
+ * <ul>
+ * <li>java.lang.Long / long (xsd:long)
+ * <li>java.lang.Integer / int (xsd:int / xsd:integer)
+ * <li>java.lang.Double/ double (xsd:double)
+ * <li>java.lang.Float / float (xsd:float)
+ * <li>java.lang.Short / short (xsd:short)
+ * <li>java.lang.Boolean / boolean (xsd:boolean)
+ * </ul>
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withPrimitiveArrays() throws Exception
+ {
+ long [] expectedLongResult = {1L,2L,3L,4L};
+ boolean [] expectedBooleanResult = { true,false,false};
+ double [] expectedDoubleResult = {12763.44d,2832.33d,2292.33d,22293.22d};
+ float [] expectedFloatResult = {2727.233f,1f,2f,4f,5.4f,33.2f};
+ int [] expectedIntegerResult = {1,2,3,4,55,66,77,88,99};
+ short [] expectedShortResult = {(short)227,(short)23,(short)9};
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithSimpleTypeArrays"),
+ new Object[]{
+ expectedLongResult,
+ expectedBooleanResult,
+ expectedDoubleResult,
+ expectedFloatResult,
+ expectedIntegerResult,
+ expectedShortResult});
+
+ Method getStatusCode = result.getClass().getMethod("getStatusCode");
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+ assertEquals(retCodeOk,getStatusCode.invoke(result));
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 6.",6,out.size());
+ assertArrayEquals(expectedLongResult, out.get(long.class.getName()));
+ assertArrayEquals(expectedBooleanResult, out.get(boolean.class.getName()));
+ assertArrayEquals(expectedDoubleResult, out.get(double.class.getName()));
+ assertArrayEquals(expectedFloatResult, out.get(float.class.getName()));
+ assertArrayEquals(expectedIntegerResult, out.get(int.class.getName()));
+ assertArrayEquals(expectedShortResult, out.get(short.class.getName()));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of a byte type array between requestor and service provider.
+ *
+ * <br>precondition : a WS-Resource exists and is registered and the requested operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and byte array are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withByteArray() throws Exception
+ {
+ byte [] expectedByteResult = {1,3,4,2,2,44,22,3,3,55,66};
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithByteArray"),
+ new Object[]{expectedByteResult});
+
+ Method getStatusCode = result.getClass().getMethod("getStatusCode");
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+
+ assertEquals(retCodeOk,getStatusCode.invoke(result));
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 1.",1,out.size());
+ assertArrayEquals(expectedByteResult, out.get(byte[].class.getName()));
+ }
+
+ /**
+ * Test a simple operation invocation on a WS-Resource.
+ * This method tests a simple operation without any input and output parameters.
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
+ * <br>postcondition : invocations are executed successfully an no exception is thrown.
+ */
+ @SuppressWarnings("unchecked")
+ public void testSimpleOperationInvocationOK() throws Exception
+ {
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("voidWithoutArguments"),
+ null);
+
+ Method getStatusCode = result.getClass().getMethod("getStatusCode");
+ assertEquals(
+ "Something was wrong...expected return code is "+retCodeOk,
+ retCodeOk,
+ getStatusCode.invoke(result));
+ }
+
+ /**
+ * Test a the invocation on a WS-Resource with a method that throws an exception..
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
+ * <br>postcondition : an exception is thrown by the requested method.
+ */
+ @SuppressWarnings("unchecked")
+ public void testInvocationException_OK() throws Exception
+ {
+ try
+ {
+ _resourceClient.invoke(
+ _invocationHandlers.get("throwsException"),
+ null);
+ fail("The requested operation has thrown an exception so a Soap Fault is expected...");
+ } catch(SoapFault expected)
+ {
+ }
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of UUID type between requestor and service provider.
+ *
+ * <br>precondition : a WS-Resource exists and is registered and the requested operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withUUID() throws Exception
+ {
+ UUID expectedUuid = UUID.randomUUID();
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithUUID"),
+ new Object[]{expectedUuid});
+
+ Method getStatusCode = result.getClass().getMethod("getStatusCode");
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+
+ assertEquals(retCodeOk,getStatusCode.invoke(result));
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 1.",1,out.size());
+ assertEquals(expectedUuid, out.get("uuid"));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of Map type between requestor and service provider.
+ * For this test exchanged arrays contain :
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withMap() throws Exception
+ {
+ Map<String,Object> expectedMap = new HashMap<String, Object>();
+ expectedMap.put("p1", new Long(1));
+ expectedMap.put("p2", Boolean.TRUE);
+ expectedMap.put("p3", 1234d);
+ expectedMap.put("p4", 11.2f);
+ expectedMap.put("p5", 1272);
+ expectedMap.put("p6", (short)12);
+ expectedMap.put("p7", "aString");
+ expectedMap.put("p8", "http://qpid.apache.org");
+ expectedMap.put("p9", new Date(12383137128L));
+ expectedMap.put("p10", new byte[]{1,2,2,3,3,4});
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithMap"),
+ new Object[]{expectedMap});
+
+ Method getStatusCode = result.getClass().getMethod("getStatusCode");
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+
+ assertEquals(retCodeOk,getStatusCode.invoke(result));
+ Map<String,Object> out = (Map<String, Object>) ((Map<String, Object>) getOutputParameters.invoke(result)).get("map");
+
+ assertEquals("Output parameters must be 10.",10,out.size());
+ assertEquals(expectedMap.get("p1"),out.get("p1"));
+ assertEquals(expectedMap.get("p2"),out.get("p2"));
+ assertEquals(expectedMap.get("p3"),out.get("p3"));
+ assertEquals(expectedMap.get("p4"),out.get("p4"));
+ assertEquals(expectedMap.get("p5"),out.get("p5"));
+ assertEquals(expectedMap.get("p6"),out.get("p6"));
+ assertEquals(expectedMap.get("p7"),out.get("p7"));
+ assertEquals(expectedMap.get("p8"),out.get("p8"));
+ assertEquals(expectedMap.get("p9"),out.get("p9"));
+ assertTrue( Arrays.equals((byte[])expectedMap.get("p10"),(byte[])out.get("p10")));
+ }
+
+ /**
+ * Main entry point for running this test case.
+ *
+ * @return the decorated test case.
+ */
+ public static Test suite() {
+ TestSuite suite = new TestSuite("Test Suite for WS-DM Adapter");
+ suite.addTestSuite(WsDmAdapterTest.class);
+ return new WsDmAdapterTestSetup(suite);
+ }
+
+ /**
+ * Creates a service group client reference.
+ *
+ * @return a service group client reference.
+ */
+ private ServiceGroupClient getServiceGroupClient()
+ {
+ URI address = URI.create(
+ "http://"+
+ TestConstants.DEFAULT_HOST+
+ ":"+
+ TestConstants.DEFAULT_PORT+
+ "/qman/services/adapter");
+ return new ServiceGroupClient(new EndpointReference(address));
+ }
+
+ /**
+ * In order to test the behaviour of the WS-DM adapter, at
+ * least one resource must be created. This is the method that
+ * returns the name (ObjectName on JMX side, Resource-ID on WSDM side)
+ * of that resource
+ *
+ * @return the name of the MBean instance that will be created.
+ * @throws Exception when the name if malformed. Practically never.
+ */
+ private ObjectName createResourceName() throws Exception
+ {
+ return new ObjectName(
+ "Q-MAN:objectId="+UUID.randomUUID()+
+ ", brokerID="+UUID.randomUUID()+
+ ",class=queue"+
+ ",package=org.apache.qpid"+
+ ",name="+System.currentTimeMillis());
+ }
+
+ private Map<String,ProxyHandler> createInvocationHandlers()
+ {
+ Map<String, ProxyHandler> handlers = new HashMap<String, ProxyHandler>();
+
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction(Names.NAMESPACE_URI+"/"+"voidWithoutArguments");
+ handler.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "voidWithoutArgumentsRequest",
+ Names.PREFIX));
+ handler.setRequestParameterNames(new QName[]{});
+ handler.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "voidWithoutArgumentsResponse",
+ Names.PREFIX));
+ handler.setReturnType(Result.class);
+
+ ProxyHandler exceptionHandler = new ReflectionProxyHandler();
+ exceptionHandler.setAction(Names.NAMESPACE_URI+"/"+"throwsException");
+ exceptionHandler.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "throwsExceptionRequest",
+ Names.PREFIX));
+
+ exceptionHandler.setRequestParameterNames(new QName[]{});
+ exceptionHandler.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "throwsExceptionResponse",
+ Names.PREFIX));
+
+ exceptionHandler.setReturnType(Result.class);
+
+ ProxyHandler echoWithWrapperTypesHandler = new ReflectionProxyHandler();
+ echoWithWrapperTypesHandler.setAction(Names.NAMESPACE_URI+"/"+"echoWithSimpleTypes");
+ echoWithWrapperTypesHandler.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypesRequest",
+ Names.PREFIX));
+
+ echoWithWrapperTypesHandler.setRequestParameterNames(new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p7",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p8",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p9",Names.PREFIX),
+ });
+
+ echoWithWrapperTypesHandler.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypesResponse",
+ Names.PREFIX));
+
+ echoWithWrapperTypesHandler.setReturnType(Result.class);
+
+ ProxyHandler echoWithArrayOfWrapperTypes = new ReflectionProxyHandler();
+ echoWithArrayOfWrapperTypes.setAction(Names.NAMESPACE_URI+"/"+"echoWithArrays");
+ echoWithArrayOfWrapperTypes.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithArraysRequest",
+ Names.PREFIX));
+
+ echoWithArrayOfWrapperTypes.setRequestParameterNames(new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p7",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p8",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p9",Names.PREFIX),
+ });
+
+ echoWithArrayOfWrapperTypes.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithArraysResponse",
+ Names.PREFIX));
+
+ echoWithArrayOfWrapperTypes.setReturnType(Result.class);
+
+ ProxyHandler echoWithArrayOfPrimitiveTypes = new ReflectionProxyHandler();
+ echoWithArrayOfPrimitiveTypes.setAction(Names.NAMESPACE_URI+"/"+"echoWithSimpleTypeArrays");
+ echoWithArrayOfPrimitiveTypes.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypeArraysRequest",
+ Names.PREFIX));
+
+ echoWithArrayOfPrimitiveTypes.setRequestParameterNames(new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX)});
+
+ echoWithArrayOfPrimitiveTypes.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypeArraysResponse",
+ Names.PREFIX));
+
+ echoWithArrayOfPrimitiveTypes.setReturnType(Result.class);
+
+ ProxyHandler echoWithByteArray = new EnhancedReflectionProxyHandler();
+ echoWithByteArray.setAction(Names.NAMESPACE_URI+"/"+"echoWithByteArray");
+ echoWithByteArray.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithByteArrayRequest",
+ Names.PREFIX));
+
+ echoWithByteArray.setRequestParameterNames(
+ new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
+
+ echoWithByteArray.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithByteArrayResponse",
+ Names.PREFIX));
+
+ echoWithByteArray.setReturnType(Result.class);
+
+ ProxyHandler echoWithUUID = new EnhancedReflectionProxyHandler();
+ echoWithUUID.setAction(Names.NAMESPACE_URI+"/"+"echoWithUUID");
+ echoWithUUID.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithUUIDRequest",
+ Names.PREFIX));
+
+ echoWithUUID.setRequestParameterNames(
+ new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
+
+ echoWithUUID.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithUUIDResponse",
+ Names.PREFIX));
+
+ echoWithUUID.setReturnType(Result.class);
+
+ ProxyHandler echoWithMap = new EnhancedReflectionProxyHandler();
+ echoWithMap.setAction(Names.NAMESPACE_URI+"/"+"echoWithMap");
+ echoWithMap.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithMapRequest",
+ Names.PREFIX));
+
+ echoWithMap.setRequestParameterNames(
+ new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
+
+ echoWithMap.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithMapResponse",
+ Names.PREFIX));
+
+ echoWithMap.setReturnType(Result.class);
+
+ handlers.put("voidWithoutArguments",handler);
+ handlers.put("echoWithSimpleTypes",echoWithWrapperTypesHandler);
+ handlers.put("echoWithArrays",echoWithArrayOfWrapperTypes);
+ handlers.put("echoWithSimpleTypeArrays", echoWithArrayOfPrimitiveTypes);
+ handlers.put("echoWithByteArray", echoWithByteArray);
+ handlers.put("echoWithUUID", echoWithUUID);
+ handlers.put("echoWithMap", echoWithMap);
+ handlers.put("throwsException",exceptionHandler);
+ return handlers;
+ }
+
+ /**
+ * Internal method used for array comparison using reflection.
+ *
+ * @param expectedArray the expected array.
+ * @param resultArray the array that must match the expected one.
+ */
+ private void assertArrayEquals(Object expectedArray, Object resultArray)
+ {
+ int expectedArrayLength = Array.getLength(expectedArray);
+ int resultArrayLength = Array.getLength(resultArray);
+
+ assertEquals(expectedArrayLength,resultArrayLength);
+
+ for (int index = 0; index < expectedArrayLength; index++)
+ {
+ Object expected = Array.get(expectedArray, index);
+ Object result = Array.get(resultArray, index);
+
+ assertEquals(expected,result);
+ }
+ }
+} \ No newline at end of file
diff --git a/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilderTest.java b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilderTest.java
new file mode 100644
index 0000000000..ead6bea6cc
--- /dev/null
+++ b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilderTest.java
@@ -0,0 +1,278 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm.capabilities;
+
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.List;
+
+import javassist.CtClass;
+import javassist.CtMethod;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObject;
+import org.apache.qpid.management.wsdm.common.EntityInstanceNotFoundFault;
+import org.apache.qpid.management.wsdm.common.MethodInvocationFault;
+import org.apache.qpid.management.wsdm.common.NoSuchAttributeFault;
+import org.apache.qpid.management.wsdm.common.QManFault;
+
+/**
+ * Test case for MBean capability builder.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MBeanCapabilityBuilderTest extends TestCase
+{
+
+ private MBeanCapabilityBuilder _builder;
+ private ObjectName _objectName;
+
+ /**
+ * Set up fixture for this test case.
+ */
+ protected void setUp() throws Exception
+ {
+ _builder = new MBeanCapabilityBuilder();
+ _objectName = new ObjectName("Test:Name=aName,class=DomainObject");
+ }
+
+ /**
+ * Tests that state change that occcurs on the begin() method when the requested
+ * class has not been defined.
+ */
+ public void testBegin_withClassNotYetDefined() throws Exception
+ {
+ _builder.begin(_objectName);
+ assertEquals(_builder._state,_builder._classNotAvailable);
+ }
+
+ /**
+ * Tests that state change that occcurs on the begin() method when the requested
+ * class has not been defined.
+ */
+ public void testBegin_withClassAlreadyDefined() throws Exception
+ {
+ _objectName = new ObjectName("Test:Name=aString,class=MBeanCapabilityBuilder");
+ _builder.begin(_objectName);
+
+ assertTrue(_builder._state instanceof DummyCapabilityBuilder);
+ assertSame(_builder._endAttributeHandler, _builder._noPropertyHasBeenDefined);
+ }
+
+ /**
+ * Tests the generateGetter method().
+ */
+ public void testGenerateGetter()
+ {
+ String name ="MyProperty";
+ String type = Long.class.getName();
+ String expected =
+ "public "+
+ type+
+ " get"+
+ name+
+ "() throws NoSuchAttributeFault,EntityInstanceNotFoundFault,QManFault { return ("+
+ type+
+ ") getAttribute(\""+
+ name+
+ "\"); }";
+
+ String result = _builder.generateGetter(type, name);
+ assertEquals(expected,result);
+ }
+
+ /**
+ * Tests the generateGetter method().
+ */
+ public void testGenerateSetter()
+ {
+ String name ="MyProperty";
+ String type = Long.class.getName();
+ String expected =
+ "public void setMyProperty("+
+ type+
+ " newValue) throws NoSuchAttributeFault,EntityInstanceNotFoundFault,QManFault { setAttribute(\""+
+ name+
+ "\", newValue); }";
+
+ String result = _builder.generateSetter(type, name);
+ assertEquals(expected,result);
+ }
+
+ /**
+ * Tests the whole execution of the builder.
+ */
+ @SuppressWarnings("unchecked")
+ public void testBuildOK() throws Exception
+ {
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+ QpidDomainObject mbean = new QpidDomainObject();
+ server.registerMBean(mbean, _objectName);
+
+ _builder.begin(_objectName);
+
+ CtClass definition = _builder._capabilityClassDefinition;
+ assertEquals(
+ MBeanCapability.class.getName(),
+ definition.getSuperclass().getName());
+
+ MBeanInfo metadata = server.getMBeanInfo(_objectName);
+
+ for (MBeanAttributeInfo attribute : metadata.getAttributes())
+ {
+ _builder.onAttribute(attribute);
+ checkAttribute(attribute, definition);
+
+ assertSame(
+ _builder._endAttributeHandler,
+ _builder._atLeastThereIsOneProperty);
+ }
+
+ for (MBeanOperationInfo operation : metadata.getOperations())
+ {
+ _builder.onOperation(operation);
+ checkOperation(operation,definition);
+ }
+
+ _builder.endAttributes();
+ _builder.endOperations();
+
+ assertNotNull(_builder.getCapabilityClass());
+ }
+
+ /**
+ * Checks an operation / method after that it has been declared on
+ * capability definition.
+ *
+ * @param operation the (JMX) operation metadata.
+ * @param definition the capability class definition.
+ * @throws Exception when something goes wrong during introspection.
+ */
+ private void checkOperation(MBeanOperationInfo operation, CtClass definition) throws Exception
+ {
+ CtMethod method = definition.getDeclaredMethod(operation.getName());
+ assertNotNull(method);
+
+ checkExceptionTypes(
+ method.getExceptionTypes(),
+ new String[]{
+ QManFault.class.getName(),
+ EntityInstanceNotFoundFault.class.getName(),
+ MethodInvocationFault.class.getName()});
+
+ assertEquals(Result.class.getName(),method.getReturnType().getName());
+
+ CtClass [] parameterTypes = method.getParameterTypes();
+ MBeanParameterInfo [] parameterMetadata = operation.getSignature();
+
+ assertEquals(parameterTypes.length, parameterMetadata.length);
+ for (int i = 0; i < parameterMetadata.length; i++)
+ {
+ assertEquals(
+ parameterTypes[i].getName(),
+ Class.forName(parameterMetadata[i].getType()).getCanonicalName());
+ }
+ }
+
+ /**
+ * Checks the exception types associated with a method.
+ *
+ * @param exceptionTypes the exception types actually thrown.
+ * @param expectedExceptionNames the expected exception types (as strings).
+ */
+ private void checkExceptionTypes(CtClass [] exceptionTypes, String [] expectedExceptionNames)
+ {
+ List<String> exceptionNames = new ArrayList<String>(exceptionTypes.length);
+ for (CtClass exception : exceptionTypes)
+ {
+ exceptionNames.add(exception.getName());
+ }
+
+ for (String expectedExceptionName : expectedExceptionNames)
+ {
+ exceptionNames.remove(expectedExceptionName);
+ }
+
+ assertTrue(exceptionNames.isEmpty());
+ }
+
+ /**
+ * Checks an attribute after that it has been declared on capability definition.
+ *
+ * @param attribute the (JMX) attribute metadata.
+ * @param definition the capability class definition.
+ * @throws Exception when something goes wrong during introspection.
+ */
+ private void checkAttribute(MBeanAttributeInfo attribute, CtClass definition) throws Exception
+ {
+ String name = _builder.getNameForAccessors(attribute.getName());
+
+ String newPropertyDeclaration =
+ new StringBuilder("new QName(Names.NAMESPACE_URI, \"")
+ .append(attribute.getName())
+ .append("\", Names.PREFIX),")
+ .toString();
+ assertTrue(_builder._properties.indexOf(newPropertyDeclaration) != -1);
+
+ if (attribute.isReadable())
+ {
+ CtMethod getter = definition.getDeclaredMethod("get"+name);
+ assertNotNull(getter);
+
+ checkExceptionTypes(
+ getter.getExceptionTypes(),
+ new String[]{
+ QManFault.class.getName(),
+ NoSuchAttributeFault.class.getName(),
+ EntityInstanceNotFoundFault.class.getName()});
+
+ assertEquals(0,getter.getParameterTypes().length);
+ assertEquals(attribute.getType(),getter.getReturnType().getName());
+ }
+
+ if (attribute.isWritable())
+ {
+ CtMethod setter = definition.getDeclaredMethod("set"+name);
+ assertNotNull(setter);
+
+ checkExceptionTypes(
+ setter.getExceptionTypes(),
+ new String[]{
+ QManFault.class.getName(),
+ NoSuchAttributeFault.class.getName(),
+ EntityInstanceNotFoundFault.class.getName()});
+
+ CtClass [] parameterTypes = setter.getParameterTypes();
+
+ assertEquals(1,parameterTypes.length);
+ assertEquals(attribute.getType(),parameterTypes[0].getName());
+ assertEquals(void.class.getName(),setter.getReturnType().getName());
+ }
+ }
+} \ No newline at end of file
diff --git a/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityTest.java b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityTest.java
new file mode 100644
index 0000000000..a9a6491209
--- /dev/null
+++ b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityTest.java
@@ -0,0 +1,204 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm.capabilities;
+
+import java.lang.management.ManagementFactory;
+import java.net.URI;
+
+import javax.management.ObjectName;
+
+import junit.framework.TestCase;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.WsResource;
+import org.apache.muse.ws.resource.impl.SimpleWsResource;
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObject;
+import org.apache.qpid.management.wsdm.common.EntityInstanceNotFoundFault;
+import org.apache.qpid.management.wsdm.common.NoSuchAttributeFault;
+import org.apache.qpid.management.wsdm.common.QManFault;
+
+/**
+ * Test case for MBeanCapability supertype layer..
+ *
+ * @author Andrea Gazzarini
+ */
+public class MBeanCapabilityTest extends TestCase
+{
+ private final String _typeAttributeName = "Type";
+ private final String _newTypeValue = "DomainObject";
+
+ private ObjectName _objectName;
+ private ObjectName _unknownObjectName;
+
+ private MBeanCapability _capability;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ _objectName = new ObjectName("Test:Name=aName");
+ _unknownObjectName = new ObjectName("Test:Type=unknown");
+
+ _capability = new MBeanCapability(){
+ @Override
+ public WsResource getWsResource()
+ {
+ return new SimpleWsResource(){
+ @Override
+ public EndpointReference getEndpointReference()
+ {
+ return new EndpointReference(URI.create("http://qpid.apache.org/qman"));
+ }
+ };
+ }
+ };
+ _capability.setResourceObjectName(_objectName);
+ ManagementFactory.getPlatformMBeanServer().registerMBean(new QpidDomainObject(), _objectName);
+ }
+
+ /**
+ * Tests the execution of the getAttribute() and setAttribute() method.
+ *
+ * <br>precondition : the mbean is registered and a _capability is associated with it.
+ * <br>postcondition : the set value of the requested attribute is correctly returned.
+ */
+ public void testGetAndSetAttributeOK() throws Exception
+ {
+ Object name = _capability.getAttribute(_typeAttributeName);
+ assertNull("Name has an initial value of null so how is possibile that is not null?",name);
+
+ _capability.setAttribute(_typeAttributeName,_newTypeValue);
+
+ name = _capability.getAttribute(_typeAttributeName);
+ assertEquals("Now the name attribute must be set to \""+_newTypeValue+"\"",_newTypeValue,name);
+ }
+
+ /**
+ * Tests the execution of the getAttribute() and setAttribte() methods when an unknown attribute is given..
+ *
+ * <br>precondition : the mbean is registered, a _capability is associated with it and the requested attribute doesn't exist.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testNoSuchAttributeFault() throws Exception
+ {
+ // I suppose that we shouldn't have an attribute with this name...
+ String unknownAttribute = String.valueOf(System.currentTimeMillis());
+
+ try
+ {
+ _capability.getAttribute(unknownAttribute);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(NoSuchAttributeFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.setAttribute(unknownAttribute,null);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(NoSuchAttributeFault expected)
+ {
+ }
+ }
+
+ /**
+ * Tests the execution of the setAttribute,getAttribute and invoke methods when the target mbean
+ * doesn't exists.
+ *
+ * <br>precondition : the object name associated with the capability is not pointing to an existent MBean.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testEntityInstanceNotFoundFault() throws Exception
+ {
+ _capability.setResourceObjectName(_unknownObjectName);
+
+ try
+ {
+ _capability.getAttribute(_typeAttributeName);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(EntityInstanceNotFoundFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.setAttribute(_typeAttributeName,_newTypeValue);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(EntityInstanceNotFoundFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.invoke("operationName", null,null);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(EntityInstanceNotFoundFault expected)
+ {
+ }
+ }
+
+ /**
+ * Tests the execution of the setAttribute,getAttribute and invoke methods when an unknown / unexpected
+ * exception is thrown.
+ *
+ * <br>precondition : the mbean is registered and a capability is associated with it. Something
+ * unexpected happens during method invocation.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testQManFault() throws Exception
+ {
+ // Emulate a RuntimeException (which is the best example of uncaught exception... :) )
+ _capability.setResourceObjectName(null);
+
+ try
+ {
+ _capability.getAttribute(_typeAttributeName);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(QManFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.setAttribute(_typeAttributeName,_newTypeValue);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(QManFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.invoke("operationName", null,null);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(QManFault expected)
+ {
+ }
+ }
+
+
+ /**
+ * Shutdown procedure for this test case.
+ */
+ @Override
+ protected void tearDown() throws Exception
+ {
+ ManagementFactory.getPlatformMBeanServer().unregisterMBean(_objectName);
+ }
+}
diff --git a/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilderTest.java b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilderTest.java
new file mode 100644
index 0000000000..77cda1c2c1
--- /dev/null
+++ b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilderTest.java
@@ -0,0 +1,110 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm.capabilities;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObject;
+import org.w3c.dom.Element;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for Resource Metadata Descriptor Builder.
+ *
+ * @author Andrea Gazzarini
+ */
+public class RmdBuilderTest extends TestCase
+{
+ private MBeanInfo _metadata;
+ private RmdBuilder _builder;
+ private ObjectName _objectName;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+ _objectName = new ObjectName("Test:Name=QpidDomainObject");
+
+ server.registerMBean(new QpidDomainObject(), _objectName);
+ _metadata = server.getMBeanInfo(_objectName);
+
+ _builder = new RmdBuilder();
+ _builder.begin(_objectName);
+
+ assertEquals(_objectName,_builder._objectName);
+ }
+
+ /**
+ * Tests the execution of the onOperation() method.
+ */
+ public void testOnOperation() throws Exception
+ {
+ MBeanAttributeInfo [] attributes = _metadata.getAttributes();
+ for (MBeanAttributeInfo attribute : attributes)
+ {
+ _builder.onAttribute(attribute);
+ }
+
+ Element [] rmd = _builder.getResourceMetadataDescriptor();
+
+ assertEquals(attributes.length,rmd.length);
+
+ for (MBeanAttributeInfo attribute: _metadata.getAttributes())
+ {
+ Element propertyMetadataDescriptor = getPropertyMetadatDescriptor(attribute.getName(), rmd);
+
+ String modifiability = propertyMetadataDescriptor.getAttribute(Names.MODIFIABILITY);
+ String expectedValue =
+ attribute.isWritable()
+ ? Names.READ_WRITE
+ : Names.READ_ONLY;
+ assertEquals(expectedValue,modifiability);
+ }
+ }
+
+ /**
+ * Returns the property metadata descriptor associated with the given attribute name.
+ *
+ * @param name the attribute name.
+ * @param rmd the resource metadata descriptor.
+ * @return the property metadata descriptor associated with the given attribute name.
+ * @throws RuntimeException if metadata for the given attribute is not found.
+ */
+ private Element getPropertyMetadatDescriptor(String name, Element [] rmd)
+ {
+ for (Element propertyMetadataDescriptor : rmd)
+ {
+ if ((Names.PREFIX+":"+name).equals(
+ propertyMetadataDescriptor.getAttribute(Names.NAME_ATTRIBUTE)))
+ {
+ return propertyMetadataDescriptor;
+ }
+ }
+ throw new RuntimeException("Property MetadataDescriptor not found for attribute "+name);
+ }
+} \ No newline at end of file
diff --git a/java/management/client/src/test/java/org/apache/qpid/management/wsdm/web.xml b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/web.xml
new file mode 100644
index 0000000000..d0a9eb20a4
--- /dev/null
+++ b/java/management/client/src/test/java/org/apache/qpid/management/wsdm/web.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+ <servlet>
+ <display-name>Qpid emulator startip</display-name>
+ <servlet-name>QEmu</servlet-name>
+ <servlet-class>org.apache.qpid.management.wsdm.QEmuInitializer</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+</web-app> \ No newline at end of file