From d38d0aedd98086b89f9f74afe76a7cc7bcbab37d Mon Sep 17 00:00:00 2001 From: Andrea Gazzarini Date: Fri, 23 Jan 2009 20:44:48 +0000 Subject: QPID-1579 : WS-DM unit tests and method invocation improvements git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@737182 13f79535-47bb-0310-9956-ffa450edef68 --- java/management/client/src/test/java/log4j.xml | 23 + .../org/apache/qpid/management/TestConstants.java | 5 +- .../wsdm/EnhancedReflectionProxyHandler.java | 67 ++ .../apache/qpid/management/wsdm/ServerThread.java | 82 ++ .../wsdm/WebApplicationLifeCycleListener.java | 52 + .../qpid/management/wsdm/WsDmAdapterTest.java | 1026 ++++++++++++++++++++ .../capabilities/MBeanCapabilityBuilderTest.java | 278 ++++++ .../wsdm/capabilities/MBeanCapabilityTest.java | 204 ++++ .../wsdm/capabilities/RmdBuilderTest.java | 110 +++ .../java/org/apache/qpid/management/wsdm/web.xml | 11 + 10 files changed, 1857 insertions(+), 1 deletion(-) create mode 100644 java/management/client/src/test/java/log4j.xml create mode 100644 java/management/client/src/test/java/org/apache/qpid/management/wsdm/EnhancedReflectionProxyHandler.java create mode 100644 java/management/client/src/test/java/org/apache/qpid/management/wsdm/ServerThread.java create mode 100644 java/management/client/src/test/java/org/apache/qpid/management/wsdm/WebApplicationLifeCycleListener.java create mode 100644 java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java create mode 100644 java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilderTest.java create mode 100644 java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityTest.java create mode 100644 java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilderTest.java create mode 100644 java/management/client/src/test/java/org/apache/qpid/management/wsdm/web.xml (limited to 'java/management/client/src/test') 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 @@ + + + + + + + + + + + + + + + + + + + + + + \ 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 _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. + * + *
precondition : a ws resource exists and is registered. + *
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. + * + *
precondition : a WS-Resource exists and is registered. + *
postcondition : property values are correctly updated on the target WS-Resource.. + */ + public void testSetResourcePropertiesOK() throws Exception + { + Map sampleMap = new HashMap(); + sampleMap.put("Key1", "BLABALABLABALBAL"); + sampleMap.put("Key2", 182838484l); + sampleMap.put("Key3", -928376362); + sampleMap.put("Key4", 23762736276.33D); + sampleMap.put("Key4", 2327363.2F); + + Map sampleValues = new HashMap(); + 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. + * + *
precondition : a ws resource exists and is registered. The value of the target property is null. + *
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. + * + *
precondition : a ws resource exists and is registered. + *
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 : + * + *
    + *
  • java.lang.Long / long (xsd:long) + *
  • java.lang.Integer / int (xsd:int / xsd:integer) + *
  • java.lang.Double/ double (xsd:double) + *
  • java.lang.Float / float (xsd:float) + *
  • java.lang.Short / short (xsd:short) + *
  • java.lang.Boolean / boolean (xsd:boolean) + *
  • java.lang.String (xsd:string) + *
  • java.net.URI (xsd:anyURI) + *
  • java.util.Date(xsd:dateTime) + *
+ * + *
precondition : a ws resource exists and is registered and the requested operation is available on that. + *
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 out = (Map) 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 : + * + *
    + *
  • java.lang.Long (xsd:long) + *
  • java.lang.Integer (xsd:int / xsd:integer) + *
  • java.lang.Double (xsd:double) + *
  • java.lang.Float (xsd:float) + *
  • java.lang.Short (xsd:short) + *
  • java.lang.Boolean (xsd:boolean) + *
  • java.lang.String (xsd:string) + *
  • java.net.URI (xsd:anyURI) + *
  • java.util.Date(xsd:dateTime) + *
+ * + *
precondition : a ws resource exists and is registered and the requested operation is available on that. + *
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 out = (Map) 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 : + * + *
    + *
  • java.lang.Long / long (xsd:long) + *
  • java.lang.Integer / int (xsd:int / xsd:integer) + *
  • java.lang.Double/ double (xsd:double) + *
  • java.lang.Float / float (xsd:float) + *
  • java.lang.Short / short (xsd:short) + *
  • java.lang.Boolean / boolean (xsd:boolean) + *
+ * + *
precondition : a ws resource exists and is registered and the requested operation is available on that. + *
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 out = (Map) 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. + * + *
precondition : a WS-Resource exists and is registered and the requested operation is available on that. + *
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 out = (Map) 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. + * + *
precondition : a ws resource exists and is registered and the requested operation is available on that. + *
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.. + * + *
precondition : a ws resource exists and is registered and the requested operation is available on that. + *
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. + * + *
precondition : a WS-Resource exists and is registered and the requested operation is available on that. + *
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 out = (Map) 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 : + * + *
precondition : a ws resource exists and is registered and the requested operation is available on that. + *
postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned. + */ + @SuppressWarnings("unchecked") + public void testOperationInvocationOK_withMap() throws Exception + { + Map expectedMap = new HashMap(); + 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 out = (Map) ((Map) 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 createInvocationHandlers() + { + Map handlers = new HashMap(); + + 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 exceptionNames = new ArrayList(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. + * + *
precondition : the mbean is registered and a _capability is associated with it. + *
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.. + * + *
precondition : the mbean is registered, a _capability is associated with it and the requested attribute doesn't exist. + *
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. + * + *
precondition : the object name associated with the capability is not pointing to an existent MBean. + *
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. + * + *
precondition : the mbean is registered and a capability is associated with it. Something + * unexpected happens during method invocation. + *
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 @@ + + + + Qpid emulator startip + QEmu + org.apache.qpid.management.wsdm.QEmuInitializer + 1 + + \ No newline at end of file -- cgit v1.2.1