From 2b0ed72b0f42f1f42474cc90764548b39fd939e7 Mon Sep 17 00:00:00 2001 From: Andrea Gazzarini Date: Thu, 15 Jan 2009 07:26:19 +0000 Subject: QPID-1574 : QMan WS-DM Adapter git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@734622 13f79535-47bb-0310-9956-ffa450edef68 --- java/management/client/README.txt | 2 + java/management/client/build.xml | 127 +++-- java/management/client/etc/jetty.xml | 26 + java/management/client/etc/log4j.xml | 71 +++ java/management/client/etc/qman-config.xml | 54 +- java/management/client/etc/qman-config.xsd | 63 +++ java/management/client/etc/qman.log4j | 30 -- java/management/client/src/main/java/muse.xml | 126 +++++ .../java/org/apache/qpid/management/ICommand.java | 32 ++ .../java/org/apache/qpid/management/Messages.java | 37 +- .../java/org/apache/qpid/management/Names.java | 91 +++- .../management/configuration/Configuration.java | 55 +- .../management/configuration/Configurator.java | 37 +- .../configuration/MessageHandlerMapping.java | 46 +- .../qpid/management/domain/model/JmxService.java | 110 +++- .../qpid/management/domain/model/QpidArgument.java | 45 +- .../qpid/management/domain/model/QpidClass.java | 166 ++++-- .../management/domain/model/QpidClassMBean.java | 41 ++ .../qpid/management/domain/model/QpidEntity.java | 65 +-- .../qpid/management/domain/model/QpidEvent.java | 73 ++- .../management/domain/model/QpidEventMBean.java | 41 ++ .../qpid/management/domain/model/QpidFeature.java | 2 - .../qpid/management/domain/model/type/Binary.java | 15 +- .../qpid/management/domain/model/type/Map.java | 3 +- .../domain/services/BrokerMessageListener.java | 28 +- .../qpid/management/domain/services/QMan.java | 95 ++-- .../jmx/EntityLifecycleNotification.java | 137 +++++ .../jmx/OperationHasBeenInvokedNotification.java | 149 ++++++ .../apache/qpid/management/messages/AmqpCoDec.java | 178 ------- .../management/servlet/ConnectQManToBroker.java | 77 +++ .../management/servlet/QManLifeCycleManager.java | 72 +++ .../qpid/management/servlet/QManServlet.java | 66 --- .../qpid/management/servlet/WSDMAdapter.java | 114 ++++ .../ArtifactsNotAvailableException.java | 66 +++ .../wsdm/capabilities/BuilderException.java | 41 ++ .../wsdm/capabilities/IArtifactBuilder.java | 82 +++ .../wsdm/capabilities/MBeanCapability.java | 244 +++++++++ .../wsdm/capabilities/MBeanCapabilityBuilder.java | 181 +++++++ .../wsdm/capabilities/QManAdapterCapability.java | 156 ++++++ .../QManMetadataExchangeCapability.java | 58 ++ .../management/wsdm/capabilities/RmdBuilder.java | 134 +++++ .../wsdm/capabilities/WSDMArtifactsDirector.java | 195 +++++++ .../management/wsdm/capabilities/WsArtifacts.java | 56 ++ .../wsdm/capabilities/WsArtifactsFactory.java | 134 +++++ .../management/wsdm/capabilities/WsdlBuilder.java | 204 +++++++ .../wsdm/common/EntityInstanceNotFoundFault.java | 66 +++ .../wsdm/common/NoSuchAttributeFault.java | 68 +++ .../wsdm/common/ObjectNameIdFactory.java | 52 ++ .../qpid/management/wsdm/common/QManFault.java | 72 +++ .../qpid/management/wsdm/common/ThreadSession.java | 105 ++++ .../wsdm/common/ThreadSessionManager.java | 68 +++ .../wsdm/muse/engine/WSDMAdapterEnvironment.java | 81 +++ .../muse/engine/WSDMAdapterIsolationLayer.java | 36 ++ .../wsdm/muse/resources/QManWsResource.java | 592 +++++++++++++++++++++ .../wsdm/muse/serializer/ByteArraySerializer.java | 85 +++ .../wsdm/muse/serializer/MapSerializer.java | 137 +++++ .../wsdm/muse/serializer/ObjectSerializer.java | 175 ++++++ .../wsdm/muse/serializer/UUIDSerializer.java | 72 +++ .../org/apache/qpid/qman/debug/XmlDebugger.java | 92 ++++ .../router-entries/adapter/resource-instance-1.xml | 2 + .../client/src/main/java/wsdl/QManAdapter.rmd | 17 + .../client/src/main/java/wsdl/QManAdapter.wsdl | 419 +++++++++++++++ .../client/src/main/java/wsdl/QManWsResource.rmd | 13 + .../client/src/main/java/wsdl/QManWsResource.wsdl | 535 +++++++++++++++++++ .../src/main/java/wsdl/SOAP-Envelope-1_2.xsd | 160 ++++++ .../src/main/java/wsdl/WS-Addressing-2005_08.xsd | 148 ++++++ .../src/main/java/wsdl/WS-BaseFaults-1_2.xsd | 84 +++ .../main/java/wsdl/WS-MetadataExchange-2004_09.xsd | 113 ++++ .../client/src/main/java/wsdl/WS-Resource-1_2.xsd | 48 ++ .../src/main/java/wsdl/WS-ResourceLifetime-1_2.xsd | 130 +++++ .../wsdl/WS-ResourceMetadataDescriptor-CD-01.xsd | 325 +++++++++++ .../main/java/wsdl/WS-ResourceProperties-1_2.xsd | 394 ++++++++++++++ .../src/main/java/wsdl/WS-ServiceGroup-1_2.xsd | 233 ++++++++ .../main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl | 206 +++++++ .../client/src/main/java/wsdl/WsResource.rmd | 14 + .../src/main/java/wsdl/WsResourceFactory.wsdl | 22 + .../src/main/java/wsdl/XML-Namespace-1998.xsd | 25 + .../org/apache/qpid/management/TestConstants.java | 3 + .../configuration/ConfigurationTest.java | 47 +- .../management/configuration/ConfiguratorTest.java | 1 - .../management/domain/model/QpidClassTest.java | 8 +- .../management/domain/model/QpidEventTest.java | 8 +- java/management/client/web.xml | 102 ++-- 83 files changed, 7881 insertions(+), 702 deletions(-) create mode 100644 java/management/client/etc/jetty.xml create mode 100644 java/management/client/etc/log4j.xml create mode 100644 java/management/client/etc/qman-config.xsd delete mode 100644 java/management/client/etc/qman.log4j create mode 100644 java/management/client/src/main/java/muse.xml create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/ICommand.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClassMBean.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEventMBean.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/jmx/EntityLifecycleNotification.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/jmx/OperationHasBeenInvokedNotification.java delete mode 100644 java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/servlet/ConnectQManToBroker.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/servlet/QManLifeCycleManager.java delete mode 100644 java/management/client/src/main/java/org/apache/qpid/management/servlet/QManServlet.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/servlet/WSDMAdapter.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ArtifactsNotAvailableException.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/BuilderException.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/IArtifactBuilder.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifacts.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/NoSuchAttributeFault.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ObjectNameIdFactory.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManFault.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSessionManager.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterIsolationLayer.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ByteArraySerializer.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ObjectSerializer.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/UUIDSerializer.java create mode 100644 java/management/client/src/main/java/org/apache/qpid/qman/debug/XmlDebugger.java create mode 100644 java/management/client/src/main/java/router-entries/adapter/resource-instance-1.xml create mode 100644 java/management/client/src/main/java/wsdl/QManAdapter.rmd create mode 100644 java/management/client/src/main/java/wsdl/QManAdapter.wsdl create mode 100644 java/management/client/src/main/java/wsdl/QManWsResource.rmd create mode 100644 java/management/client/src/main/java/wsdl/QManWsResource.wsdl create mode 100644 java/management/client/src/main/java/wsdl/SOAP-Envelope-1_2.xsd create mode 100644 java/management/client/src/main/java/wsdl/WS-Addressing-2005_08.xsd create mode 100644 java/management/client/src/main/java/wsdl/WS-BaseFaults-1_2.xsd create mode 100644 java/management/client/src/main/java/wsdl/WS-MetadataExchange-2004_09.xsd create mode 100644 java/management/client/src/main/java/wsdl/WS-Resource-1_2.xsd create mode 100644 java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.xsd create mode 100644 java/management/client/src/main/java/wsdl/WS-ResourceMetadataDescriptor-CD-01.xsd create mode 100644 java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.xsd create mode 100644 java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.xsd create mode 100644 java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl create mode 100644 java/management/client/src/main/java/wsdl/WsResource.rmd create mode 100644 java/management/client/src/main/java/wsdl/WsResourceFactory.wsdl create mode 100644 java/management/client/src/main/java/wsdl/XML-Namespace-1998.xsd (limited to 'java') diff --git a/java/management/client/README.txt b/java/management/client/README.txt index 0c2a702a46..c209ae7fe3 100644 --- a/java/management/client/README.txt +++ b/java/management/client/README.txt @@ -115,3 +115,5 @@ If you wish to configure QMan via a configuration file so QMan establishes a con When Qpid is built form source, the war archive qman.war is located in qpid/java/build/management/client/servlet Enjoy! + + diff --git a/java/management/client/build.xml b/java/management/client/build.xml index bf32233214..aa215bbc24 100644 --- a/java/management/client/build.xml +++ b/java/management/client/build.xml @@ -18,49 +18,116 @@ - under the License. - --> - + - + + - + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - - - + + + \ No newline at end of file diff --git a/java/management/client/etc/jetty.xml b/java/management/client/etc/jetty.xml new file mode 100644 index 0000000000..e7033e3e86 --- /dev/null +++ b/java/management/client/etc/jetty.xml @@ -0,0 +1,26 @@ + + + + true + + + + + + + + + + + + + + + + + /qman + /lib/qman.war + + + \ No newline at end of file diff --git a/java/management/client/etc/log4j.xml b/java/management/client/etc/log4j.xml new file mode 100644 index 0000000000..09d73efe6d --- /dev/null +++ b/java/management/client/etc/log4j.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/management/client/etc/qman-config.xml b/java/management/client/etc/qman-config.xml index 68ca3c6edf..beb33acfc9 100644 --- a/java/management/client/etc/qman-config.xml +++ b/java/management/client/etc/qman-config.xml @@ -18,30 +18,34 @@ - under the License. - --> - - - - - localhost - 5672 - test - guest - guest - 4 - 0 - -1 - - - + + diff --git a/java/management/client/etc/qman-config.xsd b/java/management/client/etc/qman-config.xsd new file mode 100644 index 0000000000..38282c63d1 --- /dev/null +++ b/java/management/client/etc/qman-config.xsd @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/management/client/etc/qman.log4j b/java/management/client/etc/qman.log4j deleted file mode 100644 index c2d0b050bb..0000000000 --- a/java/management/client/etc/qman.log4j +++ /dev/null @@ -1,30 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -log4j.rootLogger=${root.logging.level} - -log4j.logger.org.apache.qpid=ERROR, console -log4j.additivity.org.apache.qpid=false - -log4j.logger.org.apache.qpid.management.client=DEBUG, console - -log4j.appender.console=org.apache.log4j.ConsoleAppender -log4j.appender.console.Threshold=error -log4j.appender.console.layout=org.apache.log4j.PatternLayout -log4j.appender.console.layout.ConversionPattern=%t %d %p [%c{4}] %m%n - diff --git a/java/management/client/src/main/java/muse.xml b/java/management/client/src/main/java/muse.xml new file mode 100644 index 0000000000..4ebcff445b --- /dev/null +++ b/java/management/client/src/main/java/muse.xml @@ -0,0 +1,126 @@ + + + + java.lang.Object + org.apache.qpid.management.wsdm.muse.serializer.ObjectSerializer + + + java.util.Map + org.apache.qpid.management.wsdm.muse.serializer.MapSerializer + + + java.util.UUID + org.apache.qpid.management.wsdm.muse.serializer.UUIDSerializer + + + org.apache.muse.core.routing.SimpleResourceRouter + + log/muse.log + SEVERE + + + org.apache.muse.core.routing.RouterFilePersistence + router-entries + + + + + adapter + + wsdl/QManAdapter.wsdl + qman:QManAdapterPortType + + org.apache.muse.core.routing.RandomResourceIdFactory + org.apache.muse.ws.resource.impl.SimpleWsResource + + http://amqp.apache.org/qpid/management/qman + org.apache.qpid.management.wsdm.capabilities.QManAdapterCapability + + + http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata + org.apache.muse.ws.metadata.impl.SimpleMetadataExchange + + + http://docs.oasis-open.org/wsrf/rpw-2/Get + org.apache.muse.ws.resource.properties.get.impl.SimpleGetCapability + + + http://docs.oasis-open.org/wsrf/rpw-2/Query + org.apache.muse.ws.resource.properties.query.impl.SimpleQueryCapability + + + http://docs.oasis-open.org/wsrf/sgw-2/ServiceGroup + org.apache.muse.ws.resource.sg.impl.SimpleServiceGroup + + + + + + QManWsResource + + + wsdl/QManWsResource.wsdl + qman:QManWsResourcePortType + + org.apache.qpid.management.wsdm.common.ObjectNameIdFactory + org.apache.qpid.management.wsdm.muse.resources.QManWsResource + + http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata + org.apache.qpid.management.wsdm.capabilities.QManMetadataExchangeCapability + + + http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination + org.apache.muse.ws.resource.lifetime.impl.SimpleImmediateTermination + + + http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination + org.apache.muse.ws.resource.lifetime.impl.SimpleScheduledTermination + + + http://docs.oasis-open.org/wsrf/rpw-2/Get + org.apache.muse.ws.resource.properties.get.impl.SimpleGetCapability + + + http://docs.oasis-open.org/wsrf/rpw-2/Query + org.apache.muse.ws.resource.properties.query.impl.SimpleQueryCapability + + + http://docs.oasis-open.org/wsrf/rpw-2/Set + org.apache.muse.ws.resource.properties.set.impl.SimpleSetCapability + + + + ServiceGroupEntry + + /wsdl/WS-ServiceGroupEntry-1_2.wsdl + wsrf-sgw:ServiceGroupEntryPortType + + org.apache.muse.core.routing.RandomResourceIdFactory + org.apache.muse.ws.resource.impl.SimpleWsResource + + http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata + org.apache.muse.ws.metadata.impl.SimpleMetadataExchange + + + http://docs.oasis-open.org/wsrf/rpw-2/Get + org.apache.muse.ws.resource.properties.get.impl.SimpleGetCapability + + + http://docs.oasis-open.org/wsrf/sgw-2/ServiceGroupEntry + org.apache.muse.ws.resource.sg.impl.SimpleEntry + + + validate-wsrp-schema + false + + + \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/ICommand.java b/java/management/client/src/main/java/org/apache/qpid/management/ICommand.java new file mode 100644 index 0000000000..c95270688e --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/ICommand.java @@ -0,0 +1,32 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management; + +/** + * Command interface. + */ +public interface ICommand +{ + /** + * Executes the action specified by this command. + */ + public void execute() throws Exception; +} 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 579b00c2db..c2a102ff95 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 @@ -28,6 +28,11 @@ package org.apache.qpid.management; */ public interface Messages { + // MESSAGES + String EVENT_SEVERITY_ATTRIBUTE_DESCRIPTION = "Severity level for this event."; + String EVENT_TIMESTAMP_ATTRIBUTE_DESCRIPTION = "Current timestamp of this event."; + String ACTION_NOT_SUPPORTED="Action %S not supported by resource %s."; + // INFO String QMAN_000001_STARTING_QMAN = " : Starting Q-Man..."; String QMAN_000002_READING_CONFIGURATION = " : Reading Q-Man configuration..."; @@ -53,6 +58,11 @@ public interface Messages String QMAN_000022_NO_BROKER_CONFIGURED = " : Q-Man has no configured broker : in order to connect with a running one use Q-Man Administration interface."; String QMAN_000023_QMAN_REGISTERED_AS_MBEAN = " : Q-Man service is now available on MBeanServer."; + String QMAN_000026_WSDM_ADAPTER_STARTS = " : Initializing WS-DM Adapter Environment..."; + String QMAN_000027_WSDM_ADAPTER_STARTED = " : WS-DM Adapter ready for incoming requests."; + String QMAN_000028_TEST_MODULE_NOT_FOUND = " : Qpid emulator not found. Test notifications are disabled."; + String QMAN_000029_DEFAULT_URI = " : Default URI will be set to %s"; + // DEBUG String QMAN_200001_INCOMING_MESSAGE_HAS_BEEN_RECEIVED = " : New incoming message has been received. Message content is %s"; String QMAN_200002_OPCODE_HANDLER_ASSOCIATION = " : \"%s\" opcode is associated to handler %s"; @@ -86,6 +96,17 @@ public interface Messages String QMAN_200030_BINDING_REMOVED = " : Binding with %s as routing key has been removed between queue %s and exchange %s."; String QMAN_200031_COMPOUND_MESSAGE_CONTAINS = " : Incoming compound message contains %s message(s)."; String QMAN_200032_COMMAND_MESSAGE_ROUTING_KEY = " : Command message routing key : %s"; + String QMAN_200033_CAPABILITY_CLASS_HAS_BEEN_ADDED = " : Capability has been added to this resource. Class is %s while URI is %s."; + String QMAN_200034_RMD_NAME = " : Resource Metadata Descriptor name is %s."; + String QMAN_200035_RMD_PATH = " : Resource Metadata Descriptor path is %s."; + String QMAN_200036_ADDITIONAL_RMD_PROPERTY = " : Additional RMD property : %s"; + String QMAN_200037_RMD = " : Resource Metadata Descriptor : %s"; + String QMAN_200038_WSRP = " : WS Resource Properties fragment : %s"; + String QMAN_200039_DEBUG_JMX_NOTIFICATION = " : %s"; + String QMAN_200040_WS_ARTIFACTS_CACHED = " : WS Artifacts has been stored on cache with the following id : %s"; + String QMAN_200041_INCOMING_OBJECT_NAME_AND_DERIVED_KEY = " : Incoming object name : %s, derived search key : %s"; + + // WARNING String QMAN_300001_MESSAGE_DISCARDED = " : No handler has been configured for processing messages with \"%s\" as opcode. Message will be discarded."; @@ -101,8 +122,6 @@ public interface Messages String QMAN_100005_CLASS_SCHEMA_PROCESSING_FAILURE = " : Q-Man was unable to process the schema response message."; String QMAN_100006_EVENT_SCHEMA_PROCESSING_FAILURE = " : Q-Man was unable to process the schema response message."; String QMAN_100007_UNABLE_TO_CONNECT_WITH_BROKER = " : Unable to connect with broker located on %s. This broker will be ignored."; - String QMAN_100008_MANAGEMENT_MESSAGE_HANDLER_NOT_AVAILABLE = " : Management Message Handler configured for opcode %s is not available and therefore will be discarded."; - String QMAN_100009_METHOD_REPLY_MESSAGE_HANDLER_NOT_AVAILABLE = " :Method-Reply Message Handler configured for opcode %s is not available and therefore will be discarded."; String QMAN_100010_METHOD_INVOCATION_RESULT_FAILURE = " : an exception occurred while storing the result of a method invocation. Sequence number was %s"; String QMAN_100011_UNKNOWN_CLASS_KIND = " : Unknwon class kind : %s)."; String QMAN_100012_SCHEMA_MESSAGE_PROCESSING_FAILURE = " : Q-Man was unable to process the schema response message."; @@ -112,8 +131,12 @@ public interface Messages String QMAN_100016_UNABLE_TO_DECODE_FEATURE_VALUE = " : Unable to decode value for %s::%s::%s"; String QMAN_100017_UNABLE_TO_CONNECT = ": Cannot connect to broker %s on %s"; String QMAN_100018_UNABLE_TO_STARTUP_CORRECTLY = " : Q-Man was unable to startup correctly : see logs for further details."; - - // MESSAGES - String EVENT_SEVERITY_ATTRIBUTE_DESCRIPTION = "Severity level for this event."; - String EVENT_TIMESTAMP_ATTRIBUTE_DESCRIPTION = "Current timestamp of this event."; -} + String QMAN_100019_REQ_OR_RES_MALFORMED = " : Unexpected exception occurred on WSDM adapter layer : probably request or response was malformed."; + String QMAN_100020_ACTION_NOT_SUPPORTED = " : "+ACTION_NOT_SUPPORTED; + String QMAN_100021_RMD_BUID_FAILURE = " : Unable to build RDM for resource %s."; + String QMAN_100022_ISOLATION_LAYER_SHUTDOWN_FAILURE = " : Unable to shutdown Isolation Layer."; + String QMAN_100023_BUILD_WS_ARTIFACTS_FAILURE = " : Unable to build WS artifacts."; + String QMAN_100024_CAPABILITY_INSTANTIATION_FAILURE = " : Unable to instantiate generated capability class for %s."; + String QMAN_100025_WSRF_FAILURE = " : Resource manager raised an exception while creating capability for %s."; + String QMAN_100026_SOAP_ADDRESS_REPLACEMENT_FAILURE = " : Exception occurred while replacing the placeholder soap address with resource actual location."; +} \ 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 7ed0f8b24d..89d97d9297 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 @@ -20,38 +20,85 @@ */ package org.apache.qpid.management; +import javax.management.ObjectName; +import javax.xml.namespace.QName; + /** * Enumeration of literal strings to avoid code duplication. - * - * @author Andrea Gazzarini */ -public interface Names +public abstract class Names { /** Name of the qpid management exchange. */ - String MANAGEMENT_EXCHANGE = "qpid.management"; - String MANAGEMENT_ROUTING_KEY = "console.#"; + public static String MANAGEMENT_EXCHANGE = "qpid.management"; + public static String MANAGEMENT_ROUTING_KEY = "console.#"; - String MANAGEMENT_QUEUE_PREFIX = "management."; - String METHOD_REPLY_QUEUE_PREFIX = "reply."; + public static String MANAGEMENT_QUEUE_PREFIX = "management."; + public static String METHOD_REPLY_QUEUE_PREFIX = "reply."; - String AMQ_DIRECT_QUEUE = "amq.direct"; - String AGENT_ROUTING_KEY_PREFIX = "agent."; - String AGENT_ROUTING_KEY = AGENT_ROUTING_KEY_PREFIX+"1.0"; + public static String AMQ_DIRECT_QUEUE = "amq.direct"; + public static String AGENT_ROUTING_KEY_PREFIX = "agent."; + public static String AGENT_ROUTING_KEY = AGENT_ROUTING_KEY_PREFIX+"1.0"; + + public static String APPLICATION_NAME ="Q-Man"; // Attributes - String PACKAGE = "package"; - String CLASS = "class"; - String OBJECT_ID="objectID"; - String BROKER_ID = "brokerID"; - String DOMAIN_NAME = "Q-MAN"; + public static String PACKAGE = "package"; + public static String CLASS = "class"; + public static String EVENT = "event"; + public static String OBJECT_ID="objectID"; + public static String BROKER_ID = "brokerID"; + public static String DOMAIN_NAME = "Q-MAN"; - String ARG_COUNT_PARAM_NAME = "argCount"; - String DEFAULT_PARAM_NAME ="default"; + public static String ARG_COUNT_PARAM_NAME = "argCount"; + public static String DEFAULT_PARAM_NAME ="default"; + + public static String NUMBER_VALIDATOR = "org.apache.qpid.management.domain.model.QpidProperty$NumberValidator"; + public static String STRING_VALIDATOR = "org.apache.qpid.management.domain.model.QpidProperty$StringValidator"; + + public static String QMAN_CONFIG_OPTION_NAME = "qman-config"; - String NUMBER_VALIDATOR = "org.apache.qpid.management.domain.model.QpidProperty$NumberValidator"; - String STRING_VALIDATOR = "org.apache.qpid.management.domain.model.QpidProperty$StringValidator"; + public static String ADD_BROKER_OPERATION_NAME = "addBroker"; - String QMAN_CONFIG_OPTION_NAME = "qman-config"; + public static String NOT_AVAILABLE = "N.A."; - String ADD_BROKER_OPERATION_NAME = "addBroker"; -} + public static ObjectName QMAN_OBJECT_NAME; + static + { + try + { + QMAN_OBJECT_NAME = new ObjectName(new StringBuilder().append(DOMAIN_NAME).append(':').append("Type=Service").toString()); + } catch(Exception exception) + { + throw new ExceptionInInitializerError(exception); + } + } + + // WSDM Stuff + public static String NAMESPACE_URI = "http://amqp.apache.org/qpid/management/qman"; + public final static String PREFIX = "qman"; + public final static String QMAN_RESOURCE_NAME = "QManWsResource"; + public final static String VALIDATE_WSRP_PARAM = "validate-wsrp-schema"; + + public static final String WEB_APP_CLASSES_FOLDER = "/WEB-INF/classes"; + public static final String DEFAULT_ENDPOINT_URI = "http://localhost:8080/qman/adapter"; + + public final static QName QMAN_RESOURCE_PORT_TYPE_NAME = new QName( + Names.NAMESPACE_URI, + "QManWsResourcePortType", + Names.PREFIX); + + public final static String NAME_ATTRIBUTE = "name"; + public final static String MODIFIABILITY = "modifiability"; + public final static String READ_WRITE = "read-write"; + public final static String READ_ONLY = "read-only"; + public final static String MUTABILITY = "mutability"; + public final static String MUTABLE = "mutable"; + + public final static String ENTRY = "entry"; + public final static String KEY = "key"; + public final static String VALUE = "value"; + public final static String TYPE = "type"; + public final static String XSI_TYPE = "xsi:"+TYPE; + + public final static String ADAPTER_PORT= "qman.port"; +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java b/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java index 12b3c6be9e..0d9792aeb1 100644 --- a/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java +++ b/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java @@ -43,8 +43,6 @@ import org.apache.qpid.transport.util.Logger; /** * Qpid Management bridge configuration. * Basically iy is a singleton that is holding all the configurtion data loaded at startup. - * - * @author Andrea Gazzarini */ public final class Configuration { @@ -57,8 +55,8 @@ public final class Configuration Map _brokerConnectionInfos = new HashMap(); - Map _managementQueueHandlers = new HashMap(); - Map _methodReplyQueueHandlers = new HashMap(); + Map _managementQueueHandlers = new HashMap(); + Map _methodReplyQueueHandlers = new HashMap(); private String _managementQueueName; private String _methodReplyQueueName; @@ -75,6 +73,11 @@ public final class Configuration createHeaderForCommandMessages(); } + void clean() + { + INSTANCE = new Configuration(); + } + /** * Returns the singleton instance. * @@ -193,21 +196,7 @@ public final class Configuration */ public Map getManagementQueueHandlers() { - Map result = new HashMap(); - - for (Entry entry : _managementQueueHandlers.entrySet()) - { - Character opcode = entry.getKey(); - String className = entry.getValue(); - try - { - result.put(opcode, (IMessageHandler)Class.forName(className).newInstance()); - } catch(Exception exception) - { - LOGGER.error(exception,Messages.QMAN_100008_MANAGEMENT_MESSAGE_HANDLER_NOT_AVAILABLE,opcode); - } - } - return result; + return _managementQueueHandlers; } /** @@ -219,21 +208,7 @@ public final class Configuration */ public Map getMethodReplyQueueHandlers() { - Map result = new HashMap(); - - for (Entry entry : _methodReplyQueueHandlers.entrySet()) - { - Character opcode = entry.getKey(); - String className = entry.getValue(); - try - { - result.put(opcode, (IMessageHandler)Class.forName(className).newInstance()); - } catch(Exception exception) - { - LOGGER.error(exception,Messages.QMAN_100009_METHOD_REPLY_MESSAGE_HANDLER_NOT_AVAILABLE,opcode); - } - } - return result; + return _methodReplyQueueHandlers; } /** @@ -304,10 +279,10 @@ public final class Configuration void addManagementMessageHandlerMapping (MessageHandlerMapping mapping) { Character opcode = mapping.getOpcode(); - String handlerClass = mapping.getMessageHandlerClass(); - _managementQueueHandlers.put(opcode, handlerClass); + IMessageHandler handler = mapping.getMessageHandler(); + _managementQueueHandlers.put(opcode, handler); - LOGGER.info(Messages.QMAN_000007_MANAGEMENT_HANDLER_MAPPING_CONFIGURED, opcode,handlerClass); + LOGGER.info(Messages.QMAN_000007_MANAGEMENT_HANDLER_MAPPING_CONFIGURED, opcode,handler.getClass().getName()); } /** @@ -320,10 +295,10 @@ public final class Configuration void addMethodReplyMessageHandlerMapping (MessageHandlerMapping mapping) { Character opcode = mapping.getOpcode(); - String handlerClass = mapping.getMessageHandlerClass(); - _methodReplyQueueHandlers.put(opcode, handlerClass); + IMessageHandler handler = mapping.getMessageHandler(); + _methodReplyQueueHandlers.put(opcode, handler); - LOGGER.info(Messages.QMAN_000008_METHOD_REPLY_HANDLER_MAPPING_CONFIGURED, opcode,handlerClass); + LOGGER.info(Messages.QMAN_000008_METHOD_REPLY_HANDLER_MAPPING_CONFIGURED, opcode,handler.getClass().getName()); } /** diff --git a/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java b/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java index 0051b19c99..a65d3d9625 100644 --- a/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java +++ b/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java @@ -41,10 +41,6 @@ import org.apache.qpid.management.domain.handler.impl.SchemaResponseMessageHandl import org.apache.qpid.management.domain.model.AccessMode; import org.apache.qpid.management.domain.model.type.AbsTime; import org.apache.qpid.management.domain.model.type.DeltaTime; -import org.apache.qpid.management.domain.model.type.Int16; -import org.apache.qpid.management.domain.model.type.Int32; -import org.apache.qpid.management.domain.model.type.Int64; -import org.apache.qpid.management.domain.model.type.Int8; import org.apache.qpid.management.domain.model.type.ObjectReference; import org.apache.qpid.management.domain.model.type.Str16; import org.apache.qpid.management.domain.model.type.Str8; @@ -61,8 +57,6 @@ import org.xml.sax.helpers.DefaultHandler; /** * Director used for coordinating the build process of configuration. * This is the only component which has a read-write permission on Configuration object. - * - * @author Andrea Gazzarini */ public class Configurator extends DefaultHandler { @@ -135,12 +129,15 @@ public class Configurator extends DefaultHandler if (initialConfigurationFile.canRead()) { SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); - reader = new BufferedReader(new InputStreamReader(new FileInputStream(initialConfigFileName))); + reader = new BufferedReader( + new InputStreamReader( + new FileInputStream(initialConfigFileName))); InputSource source = new InputSource(reader); parser.parse(source, this); } else { - LOGGER.warn(Messages.QMAN_300004_INVALID_CONFIGURATION_FILE, initialConfigFileName); - throw new ConfigurationException(String.format(Messages.QMAN_300004_INVALID_CONFIGURATION_FILE, initialConfigFileName)); + LOGGER.warn( + Messages.QMAN_300004_INVALID_CONFIGURATION_FILE, + initialConfigFileName); } } @@ -233,55 +230,49 @@ public class Configurator extends DefaultHandler configuration.addTypeMapping(new TypeMapping(9,new DeltaTime())); configuration.addTypeMapping(new TypeMapping(10,new ObjectReference())); configuration.addTypeMapping(new TypeMapping(11,new org.apache.qpid.management.domain.model.type.Boolean())); - configuration.addTypeMapping(new TypeMapping(12,new org.apache.qpid.management.domain.model.type.Float(),Names.NUMBER_VALIDATOR)); - configuration.addTypeMapping(new TypeMapping(13,new org.apache.qpid.management.domain.model.type.Double(),Names.NUMBER_VALIDATOR)); configuration.addTypeMapping(new TypeMapping(14,new org.apache.qpid.management.domain.model.type.Uuid())); configuration.addTypeMapping(new TypeMapping(15,new org.apache.qpid.management.domain.model.type.Map())); - configuration.addTypeMapping(new TypeMapping(16,new Int8(),Names.NUMBER_VALIDATOR)); - configuration.addTypeMapping(new TypeMapping(17,new Int16(),Names.NUMBER_VALIDATOR)); - configuration.addTypeMapping(new TypeMapping(18,new Int32(),Names.NUMBER_VALIDATOR)); - configuration.addTypeMapping(new TypeMapping(19,new Int64(),Names.NUMBER_VALIDATOR)); } /** * Configures the mandatory management message handlers. */ - private void addMandatoryMethodReplyMessageHandlers () + void addMandatoryMethodReplyMessageHandlers () { Configuration.getInstance().addMethodReplyMessageHandlerMapping( new MessageHandlerMapping( Protocol.OPERATION_INVOCATION_RESPONSE_OPCODE, - MethodResponseMessageHandler.class.getName())); + new MethodResponseMessageHandler())); Configuration.getInstance().addMethodReplyMessageHandlerMapping( new MessageHandlerMapping( Protocol.SCHEMA_RESPONSE_OPCODE, - SchemaResponseMessageHandler.class.getName())); + new SchemaResponseMessageHandler())); } /** * Configures the mandatory management message handlers. */ - private void addMandatoryManagementMessageHandlers () + void addMandatoryManagementMessageHandlers () { Configuration.getInstance().addManagementMessageHandlerMapping( new MessageHandlerMapping( Protocol.INSTRUMENTATION_CONTENT_RESPONSE_OPCODE, - InstrumentationMessageHandler.class.getName())); + new InstrumentationMessageHandler())); Configuration.getInstance().addManagementMessageHandlerMapping( new MessageHandlerMapping( Protocol.CONFIGURATION_CONTENT_RESPONSE_OPCDE, - ConfigurationMessageHandler.class.getName())); + new ConfigurationMessageHandler())); Configuration.getInstance().addManagementMessageHandlerMapping( new MessageHandlerMapping( Protocol.EVENT_CONTENT_RESPONSE_OPCDE, - EventContentMessageHandler.class.getName())); + new EventContentMessageHandler())); Configuration.getInstance().addManagementMessageHandlerMapping( new MessageHandlerMapping( Protocol.HEARTBEAT_INDICATION_RESPONSE_OPCODE, - HeartBeatIndicationMessageHandler.class.getName())); + new HeartBeatIndicationMessageHandler())); } } diff --git a/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java b/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java index 5e38346a2d..b02fb789cc 100644 --- a/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java +++ b/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java @@ -20,32 +20,26 @@ */ package org.apache.qpid.management.configuration; +import org.apache.qpid.management.domain.handler.base.IMessageHandler; + /** * Message Handler mapping used for associating an opcode with a message handler. - * - * @author Andrea Gazzarini */ class MessageHandlerMapping { - private Character _opcode; - private String _handlerClass; - - /** - * Builds an empty message handler mapping. - */ - MessageHandlerMapping() - { - } - + private final Character _opcode; + private final IMessageHandler _handler; + /** * Builds a new mapping with the given opcode and handler class. * * @param opcode the opcode. * @param handlerClass the handler class. */ - MessageHandlerMapping(Character opcode, String handlerClass) { + MessageHandlerMapping(Character opcode, IMessageHandler handler) + { this._opcode = opcode; - this._handlerClass = handlerClass; + this._handler = handler; } /** @@ -58,33 +52,13 @@ class MessageHandlerMapping return _opcode; } - /** - * Sets the opcode for this mapping. - * - * @param codeAsString the opcode as a string. - */ - void setOpcode (String codeAsString) - { - this._opcode = codeAsString.charAt(0); - } - /** * Returns the message handler for this mapping. * * @return the message handler for this mapping. */ - String getMessageHandlerClass() - { - return _handlerClass; - } - - /** - * Sets the message handler of this mapping. - * - * @param handlerClass the handler class as a string. - */ - void setMessageHandlerClass(String handlerClass) + IMessageHandler getMessageHandler() { - this._handlerClass = handlerClass; + return _handler; } } \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java index d919fdacae..176cec451e 100644 --- a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java +++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java @@ -31,16 +31,14 @@ import javax.management.ObjectName; import org.apache.qpid.management.Messages; import org.apache.qpid.management.Names; -import org.apache.qpid.management.domain.model.QpidClass.QpidManagedObject; -import org.apache.qpid.management.domain.model.QpidEvent.QpidManagedEvent; +import org.apache.qpid.management.domain.model.QpidClass.QManManagedObject; +import org.apache.qpid.management.domain.model.QpidEvent.QManManagedEvent; import org.apache.qpid.management.domain.model.type.Binary; import org.apache.qpid.management.domain.services.QMan; import org.apache.qpid.transport.util.Logger; /** * A simple facade used to perform operations on Mbean server. - * - * @author Andrea Gazzarini */ public class JmxService { @@ -67,8 +65,17 @@ public class JmxService } } - void registerEventInstance( - QpidManagedEvent eventInstance, + /** + * Registers an event instance with MBean server. + * + * @param eventInstance the mben event instance + * @param brokerId the broker identifier. + * @param packageName the package name. + * @param eventClassName the event class name. + * @return the object name used for registration. + */ + ObjectName registerEventInstance( + QManManagedEvent eventInstance, UUID brokerId, String packageName, String eventClassName) @@ -91,6 +98,7 @@ public class JmxService throw new RuntimeException(exception); } } + return name; } /** @@ -102,9 +110,10 @@ public class JmxService * @param packageName the name of the package containing this instance. * @param className the name of the owner class of this instance. * @param objectId the object instance identifier. + * @return the object name used for registration. */ - void registerObjectInstance( - QpidManagedObject instance, + ObjectName registerObjectInstance( + QManManagedObject instance, UUID brokerId, String packageName, String className, @@ -129,6 +138,7 @@ public class JmxService throw new RuntimeException(exception); } } + return name; } /** @@ -138,8 +148,9 @@ public class JmxService * @param packageName the name of the package containing this instance. * @param className the name of the owner class of this instance. * @param objectId the object instance identifier. + * @return obejctName the obejct name used for deregistration. */ - void unregisterObjectInstance( + ObjectName unregisterObjectInstance( UUID brokerId, String packageName, String className, @@ -164,6 +175,7 @@ public class JmxService LOGGER.error(exception,Messages.QMAN_100013_MBEAN_REGISTRATION_FAILURE,name); } } + return name; } /** @@ -182,7 +194,8 @@ public class JmxService } } - Set getEventMBeans() + @SuppressWarnings("unchecked") + Set getEventMBeans() { return _mxServer.queryNames(createEventSearchName(),null); } @@ -190,7 +203,8 @@ public class JmxService /** * Removes (unregister) all object instances from MBean Server. */ - void unregisterObjectInstances() + @SuppressWarnings("unchecked") + void unregisterObjectInstances() { Set names = _mxServer.queryNames(createObjectInstanceSearchName(),null); for (ObjectName name : names) @@ -265,6 +279,26 @@ public class JmxService } } + /** + * Creates an object name that will be used for searching all registered events. + * + * @return the object name that will be used for searching all registered events. + */ + ObjectName createClassDefinitionSearchName() + { + String asString = new StringBuilder() + .append(Names.DOMAIN_NAME) + .append(":Category=Schema,*") + .toString(); + try + { + return new ObjectName(asString); + } catch (MalformedObjectNameException exception) + { + throw new RuntimeException(exception); + } + } + /** * Creates an object name that will be used for searching all registered object instances. * @@ -284,7 +318,7 @@ public class JmxService } catch (MalformedObjectNameException exception) { throw new RuntimeException(exception); - } + } } /** @@ -344,5 +378,55 @@ public class JmxService { throw new RuntimeException(exception); } - } + } + + ObjectName createEntityDefinitionName(String packageName, String className, String type) + { + String asString = new StringBuilder() + .append(Names.DOMAIN_NAME) + .append(':') + .append("Category=Schema,Type=") + .append(type) + .append(",package=") + .append(packageName) + .append(",name=") + .append(className) + .toString(); + try + { + return new ObjectName(asString); + } catch (MalformedObjectNameException exception) + { + throw new RuntimeException(exception); + } + } + + public void registerEntityDefinition(ObjectName name, QpidEntity entity,String packageName, String className) + { + try + { + if (!_mxServer.isRegistered(name)) + _mxServer.registerMBean(entity, name); + _mxServer.addNotificationListener(name, createQManName(), null, null); + } catch(Exception exception) + { + throw new RuntimeException(exception); + } + } + + @SuppressWarnings("unchecked") + public void unregisterClassDefinitions() + { + Set names = _mxServer.queryNames(createClassDefinitionSearchName(),null); + for (ObjectName name : names) + { + try + { + _mxServer.unregisterMBean(name); + } catch(Exception ignore) + { + } + } + + } } diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java index 1e90479c0b..e126fcb8f5 100644 --- a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java +++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java @@ -24,6 +24,9 @@ import org.apache.qpid.management.Messages; import org.apache.qpid.transport.codec.Encoder; import org.apache.qpid.transport.util.Logger; +/** + * An argument is the formal definition of a parameter belonging to a specific method / operation. + */ class QpidArgument extends QpidProperty { private final static Logger LOGGER = Logger.get(QpidArgument.class); @@ -32,27 +35,53 @@ class QpidArgument extends QpidProperty private Direction _direction; + /** + * Sets the direction of this argument. + * + * @param the direction of this argument. + */ public void setDirection(String code) { this._direction = Direction.valueOf(code); } + /** + * Returns the direction of this argument. + * + * @return the direction of this argument. + */ public Direction getDirection() { return _direction; } + /** + * Sets the default value of this argument. + * + * @param defaultValue the default value of this argument. + */ public void setDefaultValue(Object defaultValue) { this._defaultValue = defaultValue; } + /** + * Returns the default value of this argument. + * + * @return the default value of this argument. + */ public Object getDefaultValue() { return _defaultValue; } - public boolean isInput(){ + /** + * Returns true if this is an Input argument. + * + * @return true if this is an Input argument. + */ + public boolean isInput() + { return _direction != Direction.O; } @@ -69,14 +98,26 @@ class QpidArgument extends QpidProperty .toString(); } + /** + * Encodes the given value according to this argument type & definition. + * + * @param value the value to be encoded. + * @param encoder the encoder. + */ public void encode(Object value,Encoder encoder) { _type.encode(value, encoder); LOGGER.debug(Messages.QMAN_200013_ARGUMENT_VALUE_ENCODED,value,_name,_type); } + /** + * Decodes the value for this argument according to its type & definition. + * + * @param decoder the decoder + * @return the decoded value of this argument. + */ public Object decode(org.apache.qpid.transport.codec.Decoder decoder) { return _type.decode(decoder); } -} +} \ No newline at end of file diff --git a/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 c7dfcb033c..359b276081 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 @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.UUID; import java.util.Map.Entry; import java.util.concurrent.BlockingQueue; import java.util.concurrent.SynchronousQueue; @@ -47,11 +48,14 @@ import javax.management.ReflectionException; import javax.management.RuntimeOperationsException; import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; import org.apache.qpid.management.domain.handler.impl.IMethodInvocationListener; import org.apache.qpid.management.domain.handler.impl.InvocationResult; import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject; import org.apache.qpid.management.domain.model.type.Binary; import org.apache.qpid.management.domain.services.SequenceNumberGenerator; +import org.apache.qpid.management.jmx.EntityLifecycleNotification; +import org.apache.qpid.management.jmx.OperationHasBeenInvokedNotification; import org.apache.qpid.transport.codec.BBDecoder; import org.apache.qpid.transport.util.Logger; @@ -60,16 +64,17 @@ import org.apache.qpid.transport.util.Logger; * A type definition for a manageable object. * This class is also responsible to manage incoming obejct instance data (configuration & instrumentation). * How can we handle data before schema is injected into this class? simply we must retain that data in raw format. - * This class has 2 states : - * 1) first state is when schema is not yet injected. In this case the incoming object data is retained as is (in raw format); - * 2) second state is when schema is injected. In this case each injection of data will result in an update / create / delete of + * This class has 3 states : + * 1) first state is when schema is not yet injected. In this case the incoming object data is retained as is (in raw format) + * and a schema request is sent; + * 2) second state is when schema has been requested but not yet injected. The incoming object data is still retained as is + * (in raw format) + * 3) third state is when schema is injected. Each injection of data will result in an update / create / delete of * the corresponding object instance. In addition, the first time the state change, the old retained raw data is cnverted in * object instance(s). - * - * @author Andrea Gazzarini - */ -class QpidClass extends QpidEntity -{ + */ +class QpidClass extends QpidEntity implements QpidClassMBean +{ /** * State interface for this class definition. * Each state is responsible to handle the injection of the data and / or schema. @@ -130,14 +135,15 @@ class QpidClass extends QpidEntity { requestSchema(); _state = _schemaRequestedButNotYetInjected; - } catch (Exception e) + } catch (Exception exception) { _logger.error( + exception, Messages.QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST, _parent.getName(), _name); } finally { - QpidManagedObject instance = getObjectInstance(objectId,false); + QManManagedObject instance = getObjectInstance(objectId,false); instance._rawConfigurationData.add(rawData); } } @@ -162,7 +168,7 @@ class QpidClass extends QpidEntity _parent.getName(), _name); } finally { - QpidManagedObject instance = getObjectInstance(objectId,false); + QManManagedObject instance = getObjectInstance(objectId,false); instance._rawConfigurationData.add(rawData); } } @@ -194,7 +200,7 @@ class QpidClass extends QpidEntity */ public void addConfigurationData (Binary objectId, byte[] rawData) { - QpidManagedObject instance = getObjectInstance(objectId,false); + QManManagedObject instance = getObjectInstance(objectId,false); instance._rawConfigurationData.add(rawData); } @@ -206,7 +212,7 @@ class QpidClass extends QpidEntity */ public void addInstrumentationData (Binary objectId, byte[] rawData) { - QpidManagedObject instance = getObjectInstance(objectId,false); + QManManagedObject instance = getObjectInstance(objectId,false); instance._rawInstrumentationData.add(rawData); } @@ -231,12 +237,21 @@ class QpidClass extends QpidEntity buildMethods(methodDefinitions,operationsMetadata); _metadata = new MBeanInfo(_name,_name,attributesMetadata,null,operationsMetadata,null); - + + EntityLifecycleNotification notification = new EntityLifecycleNotification( + EntityLifecycleNotification.SCHEMA_INJECTED, + _parent.getName(), + _name, + Names.CLASS, + _objectName); + + sendNotification(notification); + // Converting stored object instances into JMX MBean and removing raw instance data. - for (Entry instanceEntry : _objectInstances.entrySet()) + for (Entry instanceEntry : _objectInstances.entrySet()) { Binary objectId = instanceEntry.getKey(); - QpidManagedObject instance = instanceEntry.getValue(); + QManManagedObject instance = instanceEntry.getValue(); for (Iterator iterator = instance._rawInstrumentationData.iterator(); iterator.hasNext();) { @@ -250,9 +265,10 @@ class QpidClass extends QpidEntity iterator.remove(); } - JMX_SERVICE.registerObjectInstance(instance,_parent.getOwnerId(),_parent.getName(),_name,objectId); + registerMBean(instance,_parent.getOwnerId(),_parent.getName(),_name,objectId); } - _state = _schemaInjected; + _state = _schemaInjected; + } }; @@ -269,7 +285,7 @@ class QpidClass extends QpidEntity */ public void addConfigurationData (Binary objectId, byte[] rawData) { - QpidManagedObject instance = getObjectInstance(objectId,true); + QManManagedObject instance = getObjectInstance(objectId,true); updateInstanceWithConfigurationData(instance, rawData); } @@ -281,7 +297,7 @@ class QpidClass extends QpidEntity */ public void addInstrumentationData (Binary objectId, byte[] rawData) { - QpidManagedObject instance = getObjectInstance(objectId,true); + QManManagedObject instance = getObjectInstance(objectId,true); updateInstanceWithInstrumentationData(instance, rawData); } @@ -300,23 +316,21 @@ class QpidClass extends QpidEntity /** * MBean used for representing remote broker object instances. * This is the core component of the QMan domain model - * - * @author Andrea Gazzarini */ - class QpidManagedObject extends QpidManagedEntity implements MBeanRegistration + class QManManagedObject extends QManManagedEntity implements MBeanRegistration { private Binary _objectId; // Arrays used for storing raw data before this mbean is registered to mbean server. List _rawInstrumentationData = new ArrayList(); List _rawConfigurationData = new ArrayList(); - + /** * Builds a new managed object with the given object identifier. * * @param objectId the object identifier. */ - QpidManagedObject(Binary objectId) + QManManagedObject(Binary objectId) { this._objectId = objectId; } @@ -351,21 +365,33 @@ class QpidClass extends QpidEntity */ public Object invoke (String actionName, Object[] params, String[] signature) throws MBeanException,ReflectionException { - // TODO : Overloaded methods - QpidMethod method = _methods.get(actionName); - if (method != null) - { - try - { - method.validate(params); - return invokeMethod(_objectId, method, params); - } catch (Exception exception) - { - throw new MBeanException(exception); - } - } else { - throw new ReflectionException(new NoSuchMethodException(actionName)); - } + OperationHasBeenInvokedNotification notification = null; + try + { + // TODO : Overloaded methods + QpidMethod method = _methods.get(actionName); + if (method != null) + { + try + { + method.validate(params); + InvocationResult result = invokeMethod(_objectId, method, params); + notification = new OperationHasBeenInvokedNotification(actionName,params,signature,result); + return result; + } catch (Exception ex) + { + MBeanException exception = new MBeanException(ex); + notification = new OperationHasBeenInvokedNotification(actionName,params,signature,exception); + throw exception; + } + } else { + ReflectionException exception = new ReflectionException(new NoSuchMethodException(actionName)); + notification = new OperationHasBeenInvokedNotification(actionName,params,signature,exception); + throw exception; + } + }finally { + sendNotification(notification); + } } /** @@ -450,7 +476,7 @@ class QpidClass extends QpidEntity private BlockingQueue _exchangeChannelForMethodInvocations; private final IMethodInvocationListener _methodInvocationListener; - Map _objectInstances = new HashMap(); + Map _objectInstances = new HashMap(); State _state = _schemaNotRequested;; private final static class Log @@ -474,7 +500,7 @@ class QpidClass extends QpidEntity */ QpidClass(String className, Binary hash, QpidPackage parentPackage) { - super(className,hash, parentPackage); + super(className,hash, parentPackage,Names.CLASS); this._methodInvocationListener = _parent.getMethodInvocationListener(); this._exchangeChannelForMethodInvocations = new SynchronousQueue(); } @@ -602,16 +628,16 @@ class QpidClass extends QpidEntity * @param registration a flag indicating whenever the (new ) instance must be registered with MBean server. * @return the object instance associated to the given identifier. */ - QpidManagedObject getObjectInstance(Binary objectId, boolean registration) + QManManagedObject getObjectInstance(Binary objectId, boolean registration) { - QpidManagedObject objectInstance = _objectInstances.get(objectId); + QManManagedObject objectInstance = _objectInstances.get(objectId); if (objectInstance == null) { - objectInstance = new QpidManagedObject(objectId); + objectInstance = new QManManagedObject(objectId); _objectInstances.put(objectId, objectInstance); if (registration) { - JMX_SERVICE.registerObjectInstance(objectInstance,_parent.getOwnerId(),_parent.getName(),_name,objectId); + registerMBean(objectInstance,_parent.getOwnerId(),_parent.getName(),_name,objectId); } } return objectInstance; @@ -691,7 +717,7 @@ class QpidClass extends QpidEntity * @param instance the managed object instance. * @param rawData the incoming configuration data which contains new values for instance properties. */ - void updateInstanceWithConfigurationData(QpidManagedObject instance,byte [] rawData) + void updateInstanceWithConfigurationData(QManManagedObject instance,byte [] rawData) { BBDecoder decoder = new BBDecoder(); decoder.init(ByteBuffer.wrap(rawData)); @@ -714,9 +740,9 @@ class QpidClass extends QpidEntity * @param instance the managed object instance. * @param rawData the incoming instrumentation data which contains new values for instance properties. */ - void updateInstanceWithInstrumentationData(QpidManagedObject instance,byte [] rawData) + void updateInstanceWithInstrumentationData(QManManagedObject instance,byte [] rawData) { - BBDecoder decoder = new BBDecoder(); + BBDecoder decoder = new BBDecoder(); decoder.init(ByteBuffer.wrap(rawData)); for (QpidStatistic statistic : _schemaOrderedStatistics) @@ -749,10 +775,19 @@ class QpidClass extends QpidEntity */ void removeObjectInstance (Binary objectId) { - QpidManagedObject toBeRemoved = _objectInstances.remove(objectId); + QManManagedObject toBeRemoved = _objectInstances.remove(objectId); if (toBeRemoved != null) { - JMX_SERVICE.unregisterObjectInstance(_parent.getOwnerId(),_parent.getName(),_name,toBeRemoved._objectId); + ObjectName objectName = JMX_SERVICE.unregisterObjectInstance(_parent.getOwnerId(),_parent.getName(),_name,toBeRemoved._objectId); + + EntityLifecycleNotification notification = new EntityLifecycleNotification( + EntityLifecycleNotification.INSTANCE_REMOVED, + _parent.getName(), + _name, + Names.CLASS, + objectName); + + sendNotification(notification); } } @@ -763,6 +798,35 @@ class QpidClass extends QpidEntity { _objectInstances.clear(); JMX_SERVICE.unregisterObjectInstances(); + JMX_SERVICE.unregisterClassDefinitions(); _service.close(); } + + /** + * Compose method used for registering mbean instance. + * + * @param instance the mbean instance. + * @param brokerId the broker identifier. + * @param packageName the package name. + * @param className the class name. + * @param objectId the object identifier. + */ + private void registerMBean( + QManManagedObject instance, + UUID brokerId, + String packageName, + String className, + Binary objectId) + { + ObjectName objectName = JMX_SERVICE.registerObjectInstance(instance,_parent.getOwnerId(),_parent.getName(),_name,objectId); + + EntityLifecycleNotification notification = new EntityLifecycleNotification( + EntityLifecycleNotification.INSTANCE_ADDED, + packageName, + className, + Names.CLASS, + objectName); + + sendNotification(notification); + } } diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClassMBean.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClassMBean.java new file mode 100644 index 0000000000..eeb4e0e2d8 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClassMBean.java @@ -0,0 +1,41 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +/** + * Management interface for Qpid entity class.. + */ +public interface QpidClassMBean +{ + /** + * Retruns the name of the class. + * + * @return the name of the class. + */ + String getName(); + + /** + * Returns the name of the package. + * + * @return the name of the package. + */ + String getPackageName(); +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java index 59f8d807b2..5f1a786eb9 100644 --- a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java +++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java @@ -1,24 +1,3 @@ -/* -* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - package org.apache.qpid.management.domain.model; import java.util.HashMap; @@ -28,26 +7,26 @@ import javax.management.Attribute; import javax.management.AttributeList; import javax.management.DynamicMBean; import javax.management.MBeanInfo; +import javax.management.NotificationBroadcasterSupport; +import javax.management.ObjectName; import javax.management.RuntimeOperationsException; import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; import org.apache.qpid.management.domain.model.type.Binary; import org.apache.qpid.management.domain.services.QpidService; +import org.apache.qpid.management.jmx.EntityLifecycleNotification; import org.apache.qpid.transport.util.Logger; /** * Layer supertype for QMan entities. - * - * @author Andrea Gazzarini */ -public abstract class QpidEntity +public abstract class QpidEntity extends NotificationBroadcasterSupport { /** * Layer supertype for QMan managed bean entities. - * - * @author Andrea Gazzarini */ - abstract class QpidManagedEntity implements DynamicMBean + abstract class QManManagedEntity implements DynamicMBean { // After mbean is registered with the MBean server this collection holds the mbean attribute values. Map _attributes = new HashMap(); @@ -114,8 +93,11 @@ public abstract class QpidEntity final QpidPackage _parent; MBeanInfo _metadata; - final QpidService _service; + + protected ObjectName _objectName; + + private final String _type; /** * Builds a new class with the given name and package as parent. @@ -124,11 +106,12 @@ public abstract class QpidEntity * @param hash the class schema hash. * @param parentPackage the parent of this class. */ - QpidEntity(String className, Binary hash, QpidPackage parentPackage) + QpidEntity(String className, Binary hash, QpidPackage parentPackage,String type) { this._name = className; this._parent = parentPackage; this._hash = hash; + this._type = type; this._service = new QpidService(_parent.getOwnerId()); _logger.debug( @@ -138,6 +121,16 @@ public abstract class QpidEntity _name); } + public String getName() + { + return _name; + } + + public String getPackageName() + { + return _parent.getName(); + } + /** * Internal method used to send a schema request for this entity. * @@ -145,7 +138,11 @@ public abstract class QpidEntity */ void requestSchema() throws Exception { - try + + _objectName = JMX_SERVICE.createEntityDefinitionName(_parent.getName(), _name,_type); + JMX_SERVICE.registerEntityDefinition(_objectName,this,_parent.getName(),_name); + + try { _service.connect(); _service.requestSchema(_parent.getName(), _name, _hash); @@ -154,5 +151,13 @@ public abstract class QpidEntity { _service.close(); } + + EntityLifecycleNotification notification = new EntityLifecycleNotification( + EntityLifecycleNotification.SCHEMA_REQUESTED, + _parent.getName(), + _name, + Names.CLASS, + _objectName); + sendNotification(notification); } } diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java index 273ae650c1..30288bc00e 100644 --- a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java +++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java @@ -27,6 +27,7 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.UUID; import javax.management.Attribute; import javax.management.AttributeList; @@ -35,26 +36,25 @@ import javax.management.InvalidAttributeValueException; import javax.management.MBeanAttributeInfo; import javax.management.MBeanException; import javax.management.MBeanInfo; +import javax.management.ObjectName; import javax.management.ReflectionException; import javax.management.RuntimeOperationsException; import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; import org.apache.qpid.management.domain.model.type.Binary; +import org.apache.qpid.management.jmx.EntityLifecycleNotification; import org.apache.qpid.transport.codec.BBDecoder; /** * Qpid event definition. - * - * @author Andrea Gazzarini */ -class QpidEvent extends QpidEntity +class QpidEvent extends QpidEntity implements QpidEventMBean { /** * State interface for this event definition. * Each state is responsible to handle the injection of the data and / or schema. - * - * @author Andrea Gazzarini */ interface State { @@ -99,9 +99,10 @@ class QpidEvent extends QpidEntity { requestSchema(); _state = _schemaRequestedButNotYetInjected; - } catch (Exception e) + } catch (Exception exception) { _logger.error( + exception, Messages.QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST, _parent.getName(), _name); @@ -116,7 +117,7 @@ class QpidEvent extends QpidEntity */ public void setSchema (List> agumentDefinitions) throws UnableToBuildFeatureException { - throw new IllegalStateException("When a schema arrives it's not possible for this class to be in this state."); + throw new IllegalStateException("When a schema arrives it's not possible for this event to be in this state."); } }; @@ -155,12 +156,21 @@ class QpidEvent extends QpidEntity _metadata = new MBeanInfo(_name,_name,attributesMetadata,null,null,null); // Converting stored object instances into JMX MBean and removing raw instance data. - for (QpidManagedEvent instance : _eventInstances) + for (QManManagedEvent instance : _eventInstances) { updateEventInstanceWithData(instance); - JMX_SERVICE.registerEventInstance(instance,_parent.getOwnerId(),_parent.getName(),_name); + registerEventInstance(instance,_parent.getOwnerId(),_parent.getName(),_name); } _state = _schemaInjected; + + EntityLifecycleNotification notification = new EntityLifecycleNotification( + EntityLifecycleNotification.SCHEMA_INJECTED, + _parent.getName(), + _name, + Names.EVENT, + _objectName); + + sendNotification(notification); } }; @@ -177,9 +187,9 @@ class QpidEvent extends QpidEntity */ public void addNewEventData (byte[] rawData,long currentTimestamp, int severity) { - QpidManagedEvent instance = createEventInstance(rawData,currentTimestamp, severity); + QManManagedEvent instance = createEventInstance(rawData,currentTimestamp, severity); updateEventInstanceWithData(instance); - JMX_SERVICE.registerEventInstance(instance,_parent.getOwnerId(),_parent.getName(),_name); + registerEventInstance(instance,_parent.getOwnerId(),_parent.getName(),_name); } /** @@ -197,7 +207,7 @@ class QpidEvent extends QpidEntity * * @author Andrea Gazzarini */ - class QpidManagedEvent extends QpidManagedEntity + class QManManagedEvent extends QManManagedEntity { @@ -211,7 +221,7 @@ class QpidEvent extends QpidEntity * * @param objectId the object identifier. */ - private QpidManagedEvent(byte [] data, long timestamp, int severity) + private QManManagedEvent(byte [] data, long timestamp, int severity) { this._rawEventData = data; this._timestamp = timestamp; @@ -284,7 +294,7 @@ class QpidEvent extends QpidEntity private List _schemaOrderedArguments = new ArrayList(); Map _arguments = new HashMap(); - List _eventInstances = new LinkedList(); + List _eventInstances = new LinkedList(); State _state = _schemaNotRequested;; /** @@ -296,7 +306,7 @@ class QpidEvent extends QpidEntity */ QpidEvent(String eventClassName, Binary hash, QpidPackage parentPackage) { - super(eventClassName,hash,parentPackage); + super(eventClassName,hash,parentPackage,Names.EVENT); } /** @@ -393,9 +403,9 @@ class QpidEvent extends QpidEntity * @param registration a flag indicating whenever the (new ) instance must be registered with MBean server. * @return the object instance associated to the given identifier. */ - QpidManagedEvent createEventInstance(byte [] data, long timestamp, int severity) + QManManagedEvent createEventInstance(byte [] data, long timestamp, int severity) { - QpidManagedEvent eventInstance = new QpidManagedEvent(data, timestamp, severity); + QManManagedEvent eventInstance = new QManManagedEvent(data, timestamp, severity); _eventInstances.add(eventInstance); return eventInstance; } @@ -406,7 +416,7 @@ class QpidEvent extends QpidEntity * @param instance the managed object instance. * @param rawData the incoming configuration data which contains new values for instance properties. */ - void updateEventInstanceWithData(QpidManagedEvent instance) + void updateEventInstanceWithData(QManManagedEvent instance) { BBDecoder decoder = new BBDecoder(); decoder.init(ByteBuffer.wrap(instance._rawEventData)); @@ -441,6 +451,7 @@ class QpidEvent extends QpidEntity { _eventInstances.clear(); JMX_SERVICE.unregisterEvents(); + JMX_SERVICE.unregisterClassDefinitions(); _service.close(); } @@ -453,4 +464,30 @@ class QpidEvent extends QpidEntity { return _eventInstances.isEmpty(); } + + /** + * Compose method used for registering an mbean (event) instance. + * + * @param instance the mbean event. + * @param brokerId the broker identifier. + * @param packageName the package name. + * @param eventClassName the event class name. + */ + private void registerEventInstance( + QManManagedEvent instance, + UUID brokerId, + String packageName, + String eventClassName) + { + ObjectName objectName = JMX_SERVICE.registerEventInstance(instance,brokerId,packageName,eventClassName); + + EntityLifecycleNotification notification = new EntityLifecycleNotification( + EntityLifecycleNotification.INSTANCE_ADDED, + packageName, + eventClassName, + Names.EVENT, + objectName); + + sendNotification(notification); + } } diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEventMBean.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEventMBean.java new file mode 100644 index 0000000000..35ba62e02c --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEventMBean.java @@ -0,0 +1,41 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +/** + * Management interface for Qpid entity class.. + */ +public interface QpidEventMBean +{ + /** + * Retruns the name of the event. + * + * @return the name of the event. + */ + String getName(); + + /** + * Returns the name of the package. + * + * @return the name of the package. + */ + String getPackageName(); +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java index e1ca5a4d42..3262448bd4 100644 --- a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java +++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java @@ -22,8 +22,6 @@ package org.apache.qpid.management.domain.model; /** * Layer Supertype for all qpid management features. - * - * @author Andrea Gazzarini */ abstract class QpidFeature { diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java index 8009150eb2..343280ca4b 100644 --- a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java +++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java @@ -24,7 +24,6 @@ import java.io.Serializable; import java.util.Arrays; import java.util.UUID; -import org.apache.qpid.management.messages.AmqpCoDec; import org.apache.qpid.transport.codec.Encoder; /** @@ -90,7 +89,7 @@ public final class Binary implements Serializable this._bytes = bytes; byte [] array = new byte [8]; System.arraycopy(_bytes, 0, array, 0, 8); - _first = AmqpCoDec.unpack64(array); + _first = unpack64(array); uuid = UUID.randomUUID(); } @@ -148,4 +147,16 @@ public final class Binary implements Serializable { return (_first & 281474708275200L) >> 28; } + + public final long unpack64(byte data[]) { + return ( + ((long) (data[0] & 0xff) << 56) | + ((long)(data[1] & 0xff) << 48) | + ((long)(data[2] & 0xff) << 40) | + ((long)(data[3] & 0xff) << 32) | + ((long)(data[4] & 0xff) << 24) | + ((long)(data[5] & 0xff) << 16) | + ((long)(data[6] & 0xff) << 8) | + (long) data[7] & 0xff); + } } diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java index cc540ff4da..ef5bc7a484 100644 --- a/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java +++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java @@ -36,7 +36,8 @@ public class Map extends Type return decoder.readMap(); } - @Override + @SuppressWarnings("unchecked") + @Override public void encode (Object value, Encoder encoder) { encoder.writeMap((java.util.Map)value); diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java index aa588043aa..fc9819fce4 100644 --- a/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java +++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java @@ -132,20 +132,26 @@ class BrokerMessageListener implements MessageListener IMessageHandler handler = entry.getValue(); try { - handler.setDomainModel(_domainModel); - _handlers.put(opcode, handler); - } catch(Exception exception) { - LOGGER.error(exception,Messages.QMAN_100004_HANDLER_INITIALIZATION_FAILURE, opcode); - } - } + handler.setDomainModel(_domainModel); + _handlers.put(opcode, handler); + } catch (Exception exception) { + LOGGER.error(exception, + Messages.QMAN_100004_HANDLER_INITIALIZATION_FAILURE, + opcode); + } + } } + + /** - * Dispatches the given message to the appropriate handler. - * - * @param message the incoming message. - * @throws IOException when the message content cannot be read. - */ + * Dispatches the given message to the appropriate handler. + * + * @param message + * the incoming message. + * @throws IOException + * when the message content cannot be read. + */ private void dispatch(Message message) throws IOException { ByteBuffer buffer = message.readData(); diff --git a/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java b/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java index 600b54a6c9..0bc684f04c 100644 --- a/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java +++ b/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java @@ -26,7 +26,6 @@ import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.UUID; -import java.util.Map.Entry; import javax.management.Attribute; import javax.management.AttributeList; @@ -35,6 +34,9 @@ import javax.management.MBeanException; import javax.management.MBeanInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanParameterInfo; +import javax.management.Notification; +import javax.management.NotificationBroadcasterSupport; +import javax.management.NotificationListener; import javax.management.ReflectionException; import org.apache.log4j.xml.DOMConfigurator; @@ -43,21 +45,20 @@ import org.apache.qpid.management.Names; import org.apache.qpid.management.configuration.BrokerAlreadyConnectedException; import org.apache.qpid.management.configuration.BrokerConnectionData; import org.apache.qpid.management.configuration.BrokerConnectionException; -import org.apache.qpid.management.configuration.Configuration; import org.apache.qpid.management.configuration.Configurator; import org.apache.qpid.management.domain.model.JmxService; import org.apache.qpid.transport.util.Logger; /** * Main entry point for starting Q-Man application. - * - * @author Andrea Gazzarini */ -public class QMan implements DynamicMBean +public class QMan extends NotificationBroadcasterSupport implements DynamicMBean, NotificationListener { private final static Logger LOGGER = Logger.get(QMan.class); private final List managementClients = new ArrayList(); + private Configurator _configurator = new Configurator(); + /** * Starts QMan. * @throws StartupFailureException when it's not possible to proceed with startup. @@ -67,24 +68,11 @@ public class QMan implements DynamicMBean LOGGER.info(Messages.QMAN_000001_STARTING_QMAN); LOGGER.info(Messages.QMAN_000002_READING_CONFIGURATION); - Configurator configurator = new Configurator(); try { - configurator.configure(); - Configuration configuration = Configuration.getInstance(); - if (configuration.hasOneOrMoreBrokersDefined()) - { - LOGGER.info(Messages.QMAN_000003_CREATING_MANAGEMENT_CLIENTS); - for (Entry entry : Configuration.getInstance().getConnectionInfos()) - { - createManagementClient(entry.getKey(), entry.getValue()); - } - } else - { - LOGGER.info(Messages.QMAN_000022_NO_BROKER_CONFIGURED); - } - - registerQManService(); + registerQManService(); + + _configurator.configure(); LOGGER.info(Messages.QMAN_000019_QMAN_STARTED); } catch(Exception exception) { @@ -92,26 +80,6 @@ public class QMan implements DynamicMBean throw new StartupFailureException(exception); } } - - /** - * Creates a management client using the given data. - * - * @param brokerId the broker identifier. - * @param data the broker connection data. - */ - private void createManagementClient(UUID brokerId, BrokerConnectionData data) - { - try - { - ManagementClient client = new ManagementClient(brokerId,data); - client.estabilishFirstConnectionWithBroker(); - managementClients.add(client); - - LOGGER.info(Messages.QMAN_000004_MANAGEMENT_CLIENT_CONNECTED,brokerId); - } catch(StartupFailureException exception) { - LOGGER.error(exception, Messages.QMAN_100017_UNABLE_TO_CONNECT,brokerId,data); - } - } /** * Connects Q-Man with a broker defined by the given parameter. @@ -156,7 +124,7 @@ public class QMan implements DynamicMBean throw exception; } } - + /** * Stop Qman */ @@ -175,6 +143,16 @@ public class QMan implements DynamicMBean LOGGER.info(Messages.QMAN_000021_SHUT_DOWN); } + /** + * Injects the configurator on this QMan instance. + * That configutator later will be responsible to manage the configuration. + * + * @param configurator the configurator to be injected. + */ + public void setConfigurator(Configurator configurator){ + this._configurator = configurator; + } + /** * Main method used for starting Q-Man. * @@ -349,6 +327,17 @@ public class QMan implements DynamicMBean { return null; } + + /** + * Simply dispatches the incoming notification to registered listeners. + * + * @param notification the incoming notification. + * @param handback the context associated to this notification. + */ + public void handleNotification(Notification notification, Object handback) + { + sendNotification(notification); + } /** * Registers QMan as an MBean on MBeanServer. @@ -361,5 +350,25 @@ public class QMan implements DynamicMBean service.registerQManService(this); LOGGER.info(Messages.QMAN_000023_QMAN_REGISTERED_AS_MBEAN); - } + } + + /** + * Creates a management client using the given data. + * + * @param brokerId the broker identifier. + * @param data the broker connection data. + */ + public void createManagementClient(UUID brokerId, BrokerConnectionData data) + { + try + { + ManagementClient client = new ManagementClient(brokerId,data); + client.estabilishFirstConnectionWithBroker(); + managementClients.add(client); + + LOGGER.info(Messages.QMAN_000004_MANAGEMENT_CLIENT_CONNECTED,brokerId); + } catch(StartupFailureException exception) { + LOGGER.error(exception, Messages.QMAN_100017_UNABLE_TO_CONNECT,brokerId,data); + } + } } diff --git a/java/management/client/src/main/java/org/apache/qpid/management/jmx/EntityLifecycleNotification.java b/java/management/client/src/main/java/org/apache/qpid/management/jmx/EntityLifecycleNotification.java new file mode 100644 index 0000000000..e387e56e2c --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/jmx/EntityLifecycleNotification.java @@ -0,0 +1,137 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.jmx; + +import javax.management.Notification; +import javax.management.ObjectName; + +import org.apache.qpid.management.Names; +import org.apache.qpid.management.domain.services.SequenceNumberGenerator; + +/** + * Q-Man JMX entity lifecycle notification. + * A notification is sent to interested listener by Q-Man on the following scenarios : + * + *
- A schema (class / event) has been requested (Schema request); + *
- A schema (class / event) has been injected (Schema response); + *
- A schema cannot be parsed (probably it is malformed); + *
- An object instance has been created (Instrumentation / Configuration response); + *
- An event instance has been created (Instrumentation / Configuration response); + *
- An object instance has been removed (Instrumentation / Configuration response); + *
- An event instance has been removed (Instrumentation / Configuration response); + */ +public class EntityLifecycleNotification extends Notification +{ + private static final long serialVersionUID = -7755773156742412161L; + + public static final String SCHEMA_INJECTED = "org.apache.qpid.management.lifecycle.entity.schema.injected"; + public static final String SCHEMA_REQUESTED = "org.apache.qpid.management.lifecycle.entity.schema.requested"; + public static final String MALFORMED_SCHEMA = "org.apache.qpid.management.lifecycle.error.schema"; + + public static final String INSTANCE_ADDED = "org.apache.qpid.management.lifecycle.entity.instance.created"; + public static final String INSTANCE_REMOVED = "org.apache.qpid.management.lifecycle.entity.instance.removed"; + + private String _packageName = Names.NOT_AVAILABLE; + private String _className = Names.NOT_AVAILABLE; + private String _classKind = Names.NOT_AVAILABLE; + + private ObjectName _objectName; + + /** + * Builds a new notification with the given parameters. + * + * @param type the notification type. + * @param sequenceNumber the sequence number. + * @param packageName the package name. + * @param className the class name. + * @param classKind the class kind (i.e. class or event) + * @param objectName the object name of the affected mbean. + */ + public EntityLifecycleNotification(String type,String packageName, String className, String classKind, ObjectName objectName) + { + super(type,Names.APPLICATION_NAME,SequenceNumberGenerator.getNextSequenceNumber()); + this._className = className; + this._packageName = packageName; + this._classKind = classKind; + this._objectName = objectName; + } + + /** + * Returns the package name of object contained in this notification. + * + * @return the package name of object contained in this notification. + */ + public String getPackageName() + { + return _packageName; + } + + /** + * Returns the class name of object contained in this notification. + * + * @return the class name of object contained in this notification. + */ + public String getClassName() + { + return _className; + } + + /** + * Returns the class kind of object contained in this notification. + * + * @return the class kind of object contained in this notification. + * @see Names#CLASS + * @see Names#EVENT + */ + public String getClassKind() + { + return _classKind; + } + + /** + * Returns the object name of object contained in this notification. + * + * @return the object name of object contained in this notification. + */ + public ObjectName getObjectName() + { + return _objectName; + } + + /** + * Returns a string representation of this notification. + * + * @return a string representation of this notification. + */ + @Override + public String toString() + { + return new StringBuilder() + .append(getType()) + .append(':') + .append(_packageName) + .append('.') + .append(_className) + .append('@') + .append(_objectName) + .toString(); + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/jmx/OperationHasBeenInvokedNotification.java b/java/management/client/src/main/java/org/apache/qpid/management/jmx/OperationHasBeenInvokedNotification.java new file mode 100644 index 0000000000..1812b803d1 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/jmx/OperationHasBeenInvokedNotification.java @@ -0,0 +1,149 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.jmx; + +import javax.management.Notification; + +import org.apache.qpid.management.Names; +import org.apache.qpid.management.domain.handler.impl.InvocationResult; +import org.apache.qpid.management.domain.services.SequenceNumberGenerator; + +/** + * Q-Man JMX method invocation notification. + * This kind of notification is sent to interested listener by Q-Man when a method has been invoked (Method invocation request) + */ +public class OperationHasBeenInvokedNotification extends Notification +{ + private static final long serialVersionUID = -7755773156742412161L; + + public static final String OPERATION_INVOKED = "org.apache.qpid.management.operation.invoked"; + + private final String _operationName; + private final Object [] _parameters; + private final String [] _signature; + private final Exception _exception; + private final InvocationResult _result; + + /** + * Builds a new notification with the given parameters. + * + * @param type the notification type. + * @param operationName the operation name. + * @param params the operation parameters. + * @param signature the operation signature. + * @param exception the exception raised by the invocation. + */ + public OperationHasBeenInvokedNotification(String operationName, Object[] parameters, String [] signature, Exception exception) + { + super(OPERATION_INVOKED,Names.APPLICATION_NAME,SequenceNumberGenerator.getNextSequenceNumber()); + this._operationName= operationName; + this._parameters = parameters; + this._signature = signature; + this._result = null; + this._exception = exception; + + } + + /** + * Builds a new notification with the given parameters. + * + * @param type the notification type. + * @param operationName the operation name. + * @param params the operation parameters. + * @param signature the operation signature. + * @param objectName the target mbean object name. + * @param result the invocation result. + */ + public OperationHasBeenInvokedNotification(String operationName, Object[] parameters, String [] signature,InvocationResult result) + { + super(OPERATION_INVOKED,Names.APPLICATION_NAME,SequenceNumberGenerator.getNextSequenceNumber()); + this._operationName= operationName; + this._parameters = parameters; + this._signature = signature; + this._result = result; + this._exception = null; + } + + /** + * Returns the exception raised by this notification referred operation. + * + * @return the exception raised by this notification referred operation. + */ + public Exception getException() + { + return _exception; + } + + /** + * Returns the exception raised by this notification referred operation. + * + * @return the exception raised by this notification referred operation. + */ + public InvocationResult getResult() + { + return _result; + } + + /** + * Returns the operation name. + * + * @return the operation name. + */ + public String getOperationName() + { + return _operationName; + } + + /** + * Returns the parameters used in method invocation. + * + * @return the parameters used in method invocation. + */ + public Object [] getParameters() + { + return _parameters; + } + + /** + * Returns the signature of the invoked operation. + * + * @return the signature of the invoked operation. + */ + public String [] getSignature() + { + return _signature; + } + + /** + * Returns a string representation of this notification. + * + * @return a string representation of this notification. + */ + @Override + public String toString() + { + return new StringBuilder() + .append(getType()) + .append(':') + .append(_operationName) + .toString(); + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java b/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java deleted file mode 100644 index 4d1dfe796a..0000000000 --- a/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java +++ /dev/null @@ -1,178 +0,0 @@ -/* -* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.management.messages; - -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; - -/** - * AMQP Management messages codec. - * - * @author Andrea Gazzarini - */ -public class AmqpCoDec -{ - private byte [] _buffer; - private int _position; - - /** - * Builds a new codec. - */ - AmqpCoDec() - { - _buffer = new byte [1000]; - _buffer[0] = 'A'; - _buffer[1] = 'M'; - _buffer[2] = '2'; - _position = 3; - } - - - /** - * Int32-to-4 byte array marshalling. - * Marshalles an integer using four bytes. - * - * @param data the result array. - * @param pos the starting position of the array to be filled. - * @param value the value to be marshalled. - */ - public final void pack32(int value) { - _buffer[_position++] = (byte) (value >> 24 & 0xff); - _buffer[_position++] = (byte) (value >> 16 & 0xff); - _buffer[_position++] = (byte) (value >> 8 & 0xff); - _buffer[_position++] = (byte) (value & 0xff); - } - - /** - * Int32-to-4 byte array marshalling. - * Marshalles an integer using four bytes. - * - * @param data the result array. - * @param pos the starting position of the array to be filled. - * @param value the value to be marshalled. - */ - public final void pack16(int value) { - _buffer[_position++] = (byte) (value >> 8 & 0xff); - _buffer[_position++] = (byte) (value & 0xff); - } - - /** - * Int32-to-4 byte array marshalling. - * Marshalles an integer using four bytes. - * - * @param data the result array. - * @param pos the starting position of the array to be filled. - * @param value the value to be marshalled. - */ - public final void pack64(long value) { - _buffer[_position++] = (byte) (value >> 56 & 0xff); - _buffer[_position++] = (byte) (value >> 48 & 0xff); - _buffer[_position++] = (byte) (value >> 40 & 0xff); - _buffer[_position++] = (byte) (value >> 32 & 0xff); - _buffer[_position++] = (byte) (value >> 24 & 0xff); - _buffer[_position++] = (byte) (value >> 16 & 0xff); - _buffer[_position++] = (byte) (value >> 8 & 0xff); - _buffer[_position++] = (byte) (value & 0xff); - } - - /** - * Int32-to-byte array marshalling. - * Marshalles an integer using two bytes. - * - * @param data the result array. - * @param pos the starting position of the array to be filled. - * @param value the value to be marshalled. - */ - public final void pack24(int value) { - _buffer[_position++] = (byte) (value >> 16 & 0xff); - _buffer[_position++] = (byte) (value >> 8 & 0xff); - _buffer[_position++] = (byte) (value & 0xff); - } - - public final void pack8(int value) { - _buffer[_position++] = (byte) (value & 0xff); - } - - public void pack8 (byte aByte) - { - _buffer[_position++] = aByte; - } - - public void packStr8(String aString) - { - try - { - byte [] toBytes = aString.getBytes("UTF-8"); - int length = toBytes.length; - pack8(length); - System.arraycopy(toBytes, 0, _buffer, _position, length); - _position+=length; - } catch (UnsupportedEncodingException exception) - { - throw new RuntimeException(exception); - } - } - - public void packStr16(String aString) - { - try - { - byte [] toBytes = aString.getBytes("UTF-8"); - int length = toBytes.length; - pack16(length); - System.arraycopy(toBytes, 0, _buffer, _position, length); - _position+=length; - } catch (UnsupportedEncodingException exception) - { - throw new RuntimeException(exception); - } - } - - public static final long unpack64(byte data[]) { - return ( - ((long) (data[0] & 0xff) << 56) | - ((long)(data[1] & 0xff) << 48) | - ((long)(data[2] & 0xff) << 40) | - ((long)(data[3] & 0xff) << 32) | - ((long)(data[4] & 0xff) << 24) | - ((long)(data[5] & 0xff) << 16) | - ((long)(data[6] & 0xff) << 8) | - (long) data[7] & 0xff); - } - - - public void pack (byte[] bytes) - { - System.arraycopy(bytes, 0, _buffer, _position, bytes.length); - _position+=bytes.length; - } - - /** - * Retruns the byte buffer that is wrapping the backing array of this codec. - * - * @return the byte buffer that is wrapping the backing array of this codec. - */ - public ByteBuffer getEncodedBuffer () - { - return ByteBuffer.wrap(_buffer,0,_position); - } -} diff --git a/java/management/client/src/main/java/org/apache/qpid/management/servlet/ConnectQManToBroker.java b/java/management/client/src/main/java/org/apache/qpid/management/servlet/ConnectQManToBroker.java new file mode 100644 index 0000000000..574e29de81 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/servlet/ConnectQManToBroker.java @@ -0,0 +1,77 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.servlet; + +import java.util.UUID; +import java.util.Map.Entry; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.muse.core.platform.mini.MiniServlet; +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; +import org.apache.qpid.management.configuration.BrokerConnectionData; +import org.apache.qpid.management.configuration.Configuration; +import org.apache.qpid.management.domain.services.QMan; +import org.apache.qpid.transport.util.Logger; + +/** + * When QMan is started and a configuration file is given (via system property) with + * initial broker connection data(s), this servlet simply sends connect command(s) to QMan in order + * to estabilish the connection(s) to the requested broker(s). + * + * @author Andrea Gazzarini + */ +public class ConnectQManToBroker extends MiniServlet +{ + private static final long serialVersionUID = 6149614872902682208L; + private final static Logger LOGGER = Logger.get(ConnectQManToBroker.class); + + /** + * Send one or more initial "connect" command(s) to QMan in order to estabilish a connection with broker found on the + * configuration file.. + * Note that this is done only if that configuration file is given (via system property) and It is valid. + */ + public void init() + { + Configuration configuration = Configuration.getInstance(); + if (configuration.hasOneOrMoreBrokersDefined()) + { + QMan qman = (QMan)getServletContext().getAttribute(Names.APPLICATION_NAME); + + LOGGER.info(Messages.QMAN_000003_CREATING_MANAGEMENT_CLIENTS); + for (Entry entry : Configuration.getInstance().getConnectionInfos()) + { + qman.createManagementClient(entry.getKey(), entry.getValue()); + } + } else { + LOGGER.info(Messages.QMAN_000022_NO_BROKER_CONFIGURED); + } + } + + @Override + public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException + { + throw new ServletException(); + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManLifeCycleManager.java b/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManLifeCycleManager.java new file mode 100644 index 0000000000..684221f91e --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManLifeCycleManager.java @@ -0,0 +1,72 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.servlet; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import org.apache.qpid.management.Names; +import org.apache.qpid.management.domain.services.QMan; +import org.apache.qpid.management.domain.services.StartupFailureException; + +/** + * QMan lifecycle management. + * + * @author Andrea Gazzarini + */ +public class QManLifeCycleManager implements ServletContextListener +{ + /** + * Stops QMan. + * + * @param event the application context event. + */ + public void contextDestroyed(ServletContextEvent event) + { + ServletContext context = event.getServletContext(); + + QMan qman = (QMan) context.getAttribute(Names.APPLICATION_NAME); + qman.stop(); + + context.setAttribute(Names.APPLICATION_NAME, qman); + } + + /** + * Starts QMan. + * + * @param event the application context event. + */ + public void contextInitialized(ServletContextEvent event) + { + try + { + QMan qman = new QMan(); + qman.start(); + + event.getServletContext().setAttribute(Names.APPLICATION_NAME, qman); + } catch (StartupFailureException exception) + { + // TODO : LOG ERROR. + exception.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManServlet.java b/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManServlet.java deleted file mode 100644 index f0d663701b..0000000000 --- a/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManServlet.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.management.servlet; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; - -import org.apache.qpid.management.domain.services.QMan; -import org.apache.qpid.management.domain.services.StartupFailureException; - -/** - * QMan initializer. - * - * @author Andrea Gazzarini - */ -public class QManServlet extends HttpServlet { - - private static final long serialVersionUID = 6149614872902682208L; - - // QMan instance - private QMan qman; - - /** - * Initializes QMan instance. - * - * @throws ServletException when It's not possibile to proceed with initialization. - */ - @Override - public void init() throws ServletException - { - qman = new QMan(); - try { - qman.start(); - } catch (StartupFailureException exception) - { - throw new ServletException(exception); - } - } - - /** - * Stops QMan instance. - */ - @Override - public void destroy() - { - qman.stop(); - } -} diff --git a/java/management/client/src/main/java/org/apache/qpid/management/servlet/WSDMAdapter.java b/java/management/client/src/main/java/org/apache/qpid/management/servlet/WSDMAdapter.java new file mode 100644 index 0000000000..f927ca131c --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/servlet/WSDMAdapter.java @@ -0,0 +1,114 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.servlet; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.muse.util.xml.XmlUtils; +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.wsdm.muse.engine.WSDMAdapterIsolationLayer; +import org.apache.qpid.qman.debug.XmlDebugger; +import org.apache.qpid.transport.util.Logger; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +/** + * QMan Adapter facade. + * This is the main requestor entry point of the WS-DM connector / adapter. + * All WSDM requests will be handled (at higher level) by this servlet. + * + * @author Andrea Gazzarini + */ +public class WSDMAdapter extends HttpServlet +{ + private static final long serialVersionUID = 6149614872902682208L; + private final static Logger LOGGER = Logger.get(WSDMAdapter.class); + private WSDMAdapterIsolationLayer _isolationLayer; + + @Override + public void init() throws ServletException { + _isolationLayer = new WSDMAdapterIsolationLayer(getServletContext()); + _isolationLayer.initialize(); + } + + /** + * Accepts http requests containing a soap envelope (request) and therefore + * acts as the main entry point of whole WS process. + * + * @param request the http request. + * @param response the http response. + * @throws ServletException in case of application failure. + * @throws IOException in case of generic I/O failure. + */ + @Override + protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException + { + PrintWriter writer = response.getWriter(); + + Document soapEnvelopeRequest = null; + String soapEnvelopeResposeAsString = null; + + try + { + soapEnvelopeRequest = XmlUtils.createDocument(request.getInputStream()); + + Document soapEnvelopeResponse = _isolationLayer.handleRequest(soapEnvelopeRequest); + soapEnvelopeResposeAsString = XmlUtils.toString(soapEnvelopeResponse,false,true); + + response.setContentType("text/xml"); + + writer.write(soapEnvelopeResposeAsString); + } catch (SAXException exception) + { + LOGGER.error( + exception, + Messages.QMAN_100019_REQ_OR_RES_MALFORMED); + throw new ServletException(exception); + } finally { + writer.flush(); + + XmlDebugger.debug(soapEnvelopeRequest); + XmlDebugger.debug(soapEnvelopeResposeAsString); + } + } + + /** + * Stops QMan Adapter. + */ + public void destroy() + { + try + { + _isolationLayer.shutdown(); + } catch (Exception exception) + { + LOGGER.error( + exception, + Messages.QMAN_100022_ISOLATION_LAYER_SHUTDOWN_FAILURE); + } + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ArtifactsNotAvailableException.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ArtifactsNotAvailableException.java new file mode 100644 index 0000000000..01463bc6d8 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ArtifactsNotAvailableException.java @@ -0,0 +1,66 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.capabilities; + +import javax.management.ObjectName; + +/** + * Thrown when the artifacts related to a specific resource cannot be built. + * + * @author Andrea Gazzarini + */ +public class ArtifactsNotAvailableException extends Exception +{ + private static final long serialVersionUID = -9010460152421791926L; + + private final WsArtifacts _artifacts; + private final ObjectName _objectName; + + public ArtifactsNotAvailableException(WsArtifacts artifacts,Throwable cause, ObjectName objectName) + { + super(cause); + this._artifacts = artifacts; + this._objectName = objectName; + } + + /** + * Returns a message that indicates which artifacts were built. + * + * @return a message that indicates which artifacts were built. + */ + @Override + public String getMessage() + { + StringBuilder builder = new StringBuilder(); + if (_artifacts == null) + { + return super.getMessage(); + } + + builder.append("Built artifacts for ") + .append(_objectName) + .append(" : ") + .append( (_artifacts.getWsdl() != null) ? "WSDL," : "") + .append( (_artifacts.getCapabilityClass() != null) ? "Capability Class," : "") + .append( (_artifacts.getResourceMetadataDescriptor() != null) ? "Resource Metadata Descriptor," : ""); + return builder.toString(); + } +} diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/BuilderException.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/BuilderException.java new file mode 100644 index 0000000000..f3c8077d46 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/BuilderException.java @@ -0,0 +1,41 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.capabilities; + +/** + * Thrown when a WSRF artifact (either WSDL or capability) cannot be built. + * + * @author Andrea Gazzarini + */ +public class BuilderException extends Exception +{ + private static final long serialVersionUID = -8267818907567906262L; + + /** + * Builds a new exception with the given cause. + * + * @param cause the exception cause. + */ + public BuilderException(Exception cause) + { + super(cause); + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/IArtifactBuilder.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/IArtifactBuilder.java new file mode 100644 index 0000000000..3e91e2f696 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/IArtifactBuilder.java @@ -0,0 +1,82 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.capabilities; + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanOperationInfo; +import javax.management.ObjectName; + +import org.apache.muse.core.Environment; + +/** + * Defines behaviour needed by WS-DM artifact builders. + * Each concrete implementor must provide its own parser implementation of the given + * JMX data. + * + * @author Andrea Gazzarini + */ +public interface IArtifactBuilder +{ + /** + * The build process begin and the given parameter is the object name of the + * corresponding JMX entity. + * + * @throws BuilderException when the initialization fails. + */ + void begin(ObjectName objectName) throws BuilderException; + + /** + * Processes an attribute (its metadata) of the current MBean. + * + * @param attributeMetadata the attribute metadata. + * @throws BuilderException when the builder cannot parse the given metadata. + */ + void onAttribute(MBeanAttributeInfo attributeMetadata) throws BuilderException; + + /** + * Processes an operation (its metadata) of the current MBean. + * + * @param operationMetadata the operation metadata. + * @throws BuilderException when the builder cannot parse the given metadata. + */ + void onOperation(MBeanOperationInfo operationMetadata) throws BuilderException; + + /** + * Ends of the attributes section. + * + * @throws BuilderException when the builder encounter a problem during this phase.. + */ + void endAttributes() throws BuilderException; + + /** + * Ends of the operations section. + * + * @throws BuilderException when the builder encounter a problem during this phase.. + */ + void endOperations() throws BuilderException; + + /** + * Injects the adapter enviroment on this builder. + * + * @param environment the adapter environment. + */ + void setEnvironment(Environment environment); +} \ No newline at end of file diff --git a/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 new file mode 100644 index 0000000000..aec022d093 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java @@ -0,0 +1,244 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.capabilities; + +import java.lang.management.ManagementFactory; +import java.lang.reflect.Array; + +import javax.management.Attribute; +import javax.management.AttributeNotFoundException; +import javax.management.InstanceNotFoundException; +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.wsdm.common.EntityInstanceNotFoundFault; +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; + +/** + * Abstract capability used for centralize common behaviour of the QMan + * resource(s) related capabilities. + * + * @author Andrea Gazzarini + */ +public abstract class MBeanCapability extends AbstractWsResourceCapability +{ + private static final Element[] _NO_VALUES = new Element[0]; + + protected final MBeanServer _mxServer; + protected ObjectName _objectName; + + /** + * Builds a new capability related to the given object name. + * + * @param objectName the name of the target object of this capability. + */ + public MBeanCapability() + { + _mxServer = ManagementFactory.getPlatformMBeanServer(); + } + + /** + * Injects on this capability the object name of the target mbean. + * + * @param objectName the object name of the target mbean. + */ + public void setResourceObjectName(ObjectName objectName) + { + this._objectName = objectName; + } + + /** + * Returns the attribute value of a QMan managed object instance. + * + * @param attributeName the name of the attribute to be requested. + * @return the value for the requested attribute. + * @throws NoSuchAttributeFault when the requested attribute cannot be found + * on the given entity instance. + * @throws EntityInstanceNotFoundFault when the requested entity instance cannot + * be found. + * @throws QManFault in case of internal system failure. + */ + protected Object getAttribute(String attributeName) throws QManFault + { + try + { + return _mxServer.getAttribute(_objectName, attributeName); + } catch (AttributeNotFoundException exception) + { + throw new NoSuchAttributeFault( + getWsResource().getEndpointReference(), + _objectName, + attributeName); + } catch (InstanceNotFoundException exception) + { + throw new EntityInstanceNotFoundFault( + getWsResource().getEndpointReference(), + _objectName); + } catch (Exception exception) + { + throw new QManFault( + getWsResource().getEndpointReference(), + exception); + } + } + + /** + * Sets the value for the given attribute on this MBean (proxy). + * + * @param objectName + * the object name of the target instance (excluding the domain + * name). + * @param attributeName + * the name of the attribute to be requested. + * @param value + * the value for the requested attribute. + * @throws NoSuchAttributeFault + * when the requested attribute cannot be found on the given + * entity instance. + * @throws EntityInstanceNotFoundFault + * when the requested entity instance cannot be found. + * @throws QManFault + * in case of internal system failure. + */ + protected void setAttribute(String attributeName, Object value) throws QManFault + { + try + { + _mxServer.setAttribute(_objectName, new Attribute(attributeName, + value)); + } catch (AttributeNotFoundException exception) + { + throw new NoSuchAttributeFault( + getWsResource().getEndpointReference(), + _objectName, + attributeName); + } catch (InstanceNotFoundException exception) + { + throw new EntityInstanceNotFoundFault( + getWsResource().getEndpointReference(), + _objectName); + } catch (Exception exception) + { + throw new QManFault( + getWsResource().getEndpointReference(), + exception); + } + } + + /** + * + * @param name + * @param value + * TODO TODO 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; + + if (value.getClass().isArray()) { + // TODO : 'sta porcheria non va bene. L'ho inserita perché se il + // value è un array non vivne + // utilizzato il mio ByteArraySerializer ma array serializer che fa + // il serial degli elementi uno a uno : quindi + // cercava un serializer per "byte" + 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 error) { + throw WsbfUtils.convertToFault(error); + } + } +} \ 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 new file mode 100644 index 0000000000..3c7c2a2a42 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java @@ -0,0 +1,181 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.capabilities; + +import javassist.ClassClassPath; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtField; +import javassist.CtMethod; +import javassist.CtNewMethod; + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanOperationInfo; +import javax.management.ObjectName; +import javax.xml.namespace.QName; + +import org.apache.muse.core.Environment; +import org.apache.qpid.management.Names; +import org.apache.qpid.management.wsdm.common.QManFault; + +public class MBeanCapabilityBuilder implements IArtifactBuilder{ + + private StringBuilder _properties = new StringBuilder("private static final QName[] PROPERTIES = new QName[]{ "); + private CtClass _capabilityClassDefinition; + private Class _capabilityClass; + + public void onAttribute(MBeanAttributeInfo attribute) throws BuilderException + { + String plainName = attribute.getName(); + + _properties.append("new QName(Names.NAMESPACE_URI, \"") + .append(attribute.getName()) + .append("\", Names.PREFIX),"); + + String type = attribute.getType(); + type = (type.startsWith("[B")) ? " byte[] " : type; + + StringBuilder buffer = new StringBuilder() + .append("private ") + .append(type) + .append(' ') + .append(attribute.getName()) + .append(';'); + try + { + CtField field= CtField.make(buffer.toString(),_capabilityClassDefinition); + _capabilityClassDefinition.addField(field); + + char firstLetter = Character.toUpperCase(plainName.charAt(0)); + String nameForAccessors = firstLetter + plainName.substring(1); + + if (attribute.isReadable()) + { + buffer = new StringBuilder() + .append("public ") + .append(type) + .append(' ') + .append("get") + .append(nameForAccessors) + .append("() throws QManFault { return (").append(type).append(") getAttribute(\"") + .append(plainName) + .append("\"); }"); + + CtMethod getter = CtNewMethod.make(buffer.toString(),_capabilityClassDefinition); + _capabilityClassDefinition.addMethod(getter); + } + + if (attribute.isWritable()) + { + buffer = new StringBuilder() + .append("public void ") + .append("set") + .append(nameForAccessors) + .append("(") + .append(type) + .append(" newValue) throws QManFault {") + .append(" setAttribute(\"") + .append(plainName) + .append("\", newValue); }"); + + CtMethod setter = CtNewMethod.make(buffer.toString(),_capabilityClassDefinition); + _capabilityClassDefinition.addMethod(setter); + } + } catch(Exception exception) + { + System.err.println(buffer); + throw new BuilderException(exception); + } + } + + /** + * First callback : this method is called at the begin of the director process. + * It contains builder initialization code. + * + * @throws BuilderException when the initialization fails. + */ + 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()); + _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 onOperation(MBeanOperationInfo operation) + { + // TODO + } + + public Class getCapabilityClass() + { + return _capabilityClass; + } + + public void endAttributes() throws BuilderException + { + try + { + _properties.deleteCharAt(_properties.length()-1); + _properties.append("};"); + + CtField properties = CtField.make(_properties.toString(), _capabilityClassDefinition); + _capabilityClassDefinition.addField(properties); + + CtMethod getPropertyNames = CtNewMethod.make( + "public QName[] getPropertyNames() { return PROPERTIES;}", + _capabilityClassDefinition); + _capabilityClassDefinition.addMethod(getPropertyNames); + } catch(Exception exception) + { + System.err.println(_properties); + throw new BuilderException(exception); + } + } + + @SuppressWarnings("unchecked") + public void endOperations() throws BuilderException + { + try + { + _capabilityClass = _capabilityClassDefinition.toClass(); + } catch (Exception exception) + { + throw new BuilderException(exception); + } + } + + public void setEnvironment(Environment environment) + { + // N.A. + } +} \ 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 new file mode 100644 index 0000000000..5c0afa4597 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java @@ -0,0 +1,156 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.capabilities; + +import java.lang.management.ManagementFactory; + +import javax.management.InstanceNotFoundException; +import javax.management.MBeanServer; +import javax.management.Notification; +import javax.management.NotificationFilterSupport; +import javax.management.NotificationListener; +import javax.management.ObjectName; + +import org.apache.muse.core.AbstractCapability; +import org.apache.muse.core.Resource; +import org.apache.muse.core.ResourceManager; +import org.apache.muse.core.serializer.SerializerRegistry; +import org.apache.muse.ws.addressing.soap.SoapFault; +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; +import org.apache.qpid.management.jmx.EntityLifecycleNotification; +import org.apache.qpid.management.wsdm.common.ThreadSessionManager; +import org.apache.qpid.management.wsdm.muse.serializer.ByteArraySerializer; +import org.apache.qpid.transport.util.Logger; + +/** + * MBean Server capabilty interface implementor. + * Providers all the operations of the MBeanServer interface using the platform MBeanServer. +*/ +public class QManAdapterCapability extends AbstractCapability +{ + private MBeanServer _mxServer; + private final static Logger LOGGER = Logger.get(QManAdapterCapability.class); + + private WsArtifactsFactory _artifactsFactory; + + private final NotificationListener listenerForNewInstances = new NotificationListener() + { + public void handleNotification(Notification notification, Object data) + { + EntityLifecycleNotification lifecycleNotification = (EntityLifecycleNotification) notification; + ObjectName eventSourceName = lifecycleNotification.getObjectName(); + ThreadSessionManager.getInstance().getSession().setObjectName(eventSourceName); + + try + { + LOGGER.debug(Messages.QMAN_200039_DEBUG_JMX_NOTIFICATION, notification); + + ResourceManager resourceManager = getResource().getResourceManager(); + Resource resource = resourceManager.createResource(Names.QMAN_RESOURCE_NAME); + + WsArtifacts artifacts = _artifactsFactory.getArtifactsFor(resource,eventSourceName); + MBeanCapability capability = _artifactsFactory.createCapability( + artifacts.getCapabilityClass(), + eventSourceName); + + + ThreadSessionManager.getInstance().getSession().setWsdlDocument(artifacts.getWsdl()); + ThreadSessionManager.getInstance().getSession().setResourceMetadataDescriptor(artifacts.getResourceMetadataDescriptor()); + +// ResourceManager resourceManager = getResource().getResourceManager(); +// +// Resource resource = resourceManager.createResource(Names.QMAN_RESOURCE_NAME); +// resource.setWsdlPortType(Names.QMAN_RESOURCE_PORT_TYPE_NAME); + resource.addCapability(capability); + resource.initialize(); + resourceManager.addResource(resource.getEndpointReference(), resource); + } catch (ArtifactsNotAvailableException exception) + { + LOGGER.error(exception,Messages.QMAN_100023_BUILD_WS_ARTIFACTS_FAILURE); + } catch (IllegalAccessException exception) + { + LOGGER.error(exception,Messages.QMAN_100024_CAPABILITY_INSTANTIATION_FAILURE,eventSourceName); + } catch (InstantiationException exception) + { + LOGGER.error(exception,Messages.QMAN_100024_CAPABILITY_INSTANTIATION_FAILURE,eventSourceName); + } catch (SoapFault exception) + { + LOGGER.error(exception,Messages.QMAN_100025_WSRF_FAILURE,eventSourceName); + } catch (Exception exception) + { + LOGGER.error(exception,Messages.QMAN_100025_WSRF_FAILURE,eventSourceName); + } + + } + }; + + private final NotificationListener listenerForRemovedInstances = new NotificationListener() + { + public void handleNotification(Notification notification, Object data) + { + LOGGER.warn("TBD : Notification Listener for removed instances has not yet implemeted!"); + } + }; + + @Override + public void initialize() throws SoapFault + { + super.initialize(); + + // Workaround : it seems that is not possibile to declare a serializer for a byte array using muse descriptor... + // What is the stringified name of the class? byte[].getClass().getName() is [B but is not working (ClassNotFound). + // So, at the end, this is hard-coded here! + SerializerRegistry.getInstance().registerSerializer(byte[].class, new ByteArraySerializer()); + + try + { + _mxServer = ManagementFactory.getPlatformMBeanServer(); + _artifactsFactory = new WsArtifactsFactory(getEnvironment(),_mxServer); + + NotificationFilterSupport filterForNewInstances = new NotificationFilterSupport(); + filterForNewInstances.enableType(EntityLifecycleNotification.INSTANCE_ADDED); + + NotificationFilterSupport filterForRemovedInstances = new NotificationFilterSupport(); + filterForNewInstances.enableType(EntityLifecycleNotification.INSTANCE_REMOVED); + + _mxServer.addNotificationListener(Names.QMAN_OBJECT_NAME, listenerForNewInstances, filterForNewInstances, null); + _mxServer.addNotificationListener(Names.QMAN_OBJECT_NAME, listenerForRemovedInstances, filterForRemovedInstances, null); + + try { + _mxServer.addNotificationListener(new ObjectName("A:A=1"), listenerForNewInstances, filterForNewInstances, null); + } catch (Exception exception) { + LOGGER.info(Messages.QMAN_000028_TEST_MODULE_NOT_FOUND); + } + + } catch(InstanceNotFoundException exception) + { + // throw new QManNotRunningFault + throw new SoapFault(exception); + } + } + + @SuppressWarnings("unchecked") + public void connect(String host, int port, String username, String password, String virtualHost) throws SoapFault + { + + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java new file mode 100644 index 0000000000..28ce2c1f67 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java @@ -0,0 +1,58 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.capabilities; + +import org.apache.muse.util.xml.XmlUtils; +import org.apache.muse.ws.resource.metadata.ext.WsrfMetadataExchange; +import org.apache.muse.ws.wsdl.WsdlUtils; +import org.apache.qpid.management.wsdm.muse.resources.QManWsResource; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * QMan resource metadata exchange. + * We cannot resuse the preexisting classes directly because the wsdl of the service instance + * is retrieved using a file path. + * Since the owner resource (QManWsResource) is dynamic (I mean, its interface is dynamic), the corresponding + * WSDL cannot defined at compile time but needs some changes when the resource is created. + * As part of that, the WSDL template found under wsdl folder is modified with the additional properties of the given + * resource. The metadata exchange capability must include those properties too. + * + * Note that this capability is appliable only to a QManWsResource. + * + * @author Andrea Gazzarini + */ +public class QManMetadataExchangeCapability extends WsrfMetadataExchange +{ + @Override + protected Element getWSDL() + { + QManWsResource resource = (QManWsResource) getResource(); + + Document wsdlDoc = resource.getWsdl(); + Element wsdl = XmlUtils.getFirstElement(wsdlDoc); + + WsdlUtils.removeWsdlReferences(wsdl); + WsdlUtils.removeSchemaReferences(wsdl); + + return wsdl; + } +} \ 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 new file mode 100644 index 0000000000..1bde65180d --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java @@ -0,0 +1,134 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.capabilities; + +import java.util.ArrayList; +import java.util.List; + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanOperationInfo; +import javax.management.ObjectName; + +import org.apache.muse.core.Environment; +import org.apache.muse.util.xml.XmlUtils; +import org.apache.muse.ws.resource.metadata.WsrmdConstants; +import org.apache.qpid.management.Names; +import org.apache.qpid.qman.debug.XmlDebugger; +import org.w3c.dom.Element; + +/** + * Resource Metadata Descriptor Builder. + * It is used for build the metadata descriptor for properties of the + * incoming jmx object. + * + * @author Andrea Gazzarini + */ +class RmdBuilder implements IArtifactBuilder +{ + private List _metadataDescriptor = new ArrayList(); + + private ObjectName _objectName; + + /** + * Nothing to be done here on this builder. + * Simply logs a message indicating the target object name. + * + * @param objectName the jmx name of the object that is going to be processed. + */ + public void begin(ObjectName objectName) + { + this._objectName = objectName; + } + + /** + * Nothing to be done here on this builder. + * + * @throws BuilderException never. + */ + public void endAttributes() + { + // N.A. for this builder. + } + + /** + * Nothing to be done here on this builder. + * + * @throws BuilderException never. + */ + public void endOperations() + { + // N.A. for this builder. + } + + /** + * Process a single attribute metadata. + * An attribute (that is, a property) represented by the corresponding incoming + * attribute metadata will generate an wsrmd:Property xml element with the constraints + * (initial values, static values, allowed values) contained on the metadata. + * + * @param attributeMetadata the attribute (jmx) metadata. + */ + public void onAttribute(MBeanAttributeInfo attributeMetadata) + { + Element property = XmlUtils.createElement(WsrmdConstants.PROPERTY_QNAME); + property.setAttribute(Names.NAME_ATTRIBUTE, Names.PREFIX+":"+attributeMetadata.getName()); + property.setAttribute(Names.MODIFIABILITY, + attributeMetadata.isWritable() + ? Names.READ_WRITE + : Names.READ_ONLY); + property.setAttribute(Names.MUTABILITY,Names.MUTABLE); + + XmlDebugger.debug(_objectName, property); + + _metadataDescriptor.add(property); + } + + /** + * Nothing to be done here on this builder. + * + * @throws BuilderException never. + */ + public void onOperation(MBeanOperationInfo operation) + { + // N.A. for this builder + } + + /** + * Nothing to be done here on this builder. + * + * @throws BuilderException never. + */ + public void setEnvironment(Environment environment) + { + // N.A. for this builder + } + + /** + * Nothing to be done here on this builder. + * + * @throws BuilderException never. + */ + public Element[] getResourceMetadataDescriptor() + { + Element [] properties = _metadataDescriptor.toArray(new Element[0]); + return properties; + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java new file mode 100644 index 0000000000..4c19475572 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java @@ -0,0 +1,195 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.capabilities; + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanOperationInfo; +import javax.management.ObjectName; + +import org.apache.muse.core.Environment; +import org.apache.muse.core.Resource; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * Director used for coordinate the building process of WS-DM artifacts. + * + * @author Andrea Gazzarini + */ +class WSDMArtifactsDirector +{ + private final ObjectName _eventSourceObjectName; + private final MBeanInfo _metadata; + + private final MBeanCapabilityBuilder _capabilityBuilder; + private final WsdlBuilder _wsdlBuilder; + private final RmdBuilder _rmdBuilder; + + /** + * Builds a new director with the given objectname and (jmx) metadata. + * + * @param eventSourceObjectName the object name of the event source mbean. + * @param metadata the jmx metadata of the corresponding mbean. + */ + WSDMArtifactsDirector(ObjectName eventSourceObjectName, MBeanInfo metadata) + { + this._eventSourceObjectName = eventSourceObjectName; + this._metadata = metadata; + + _wsdlBuilder = new WsdlBuilder(); + _capabilityBuilder = new MBeanCapabilityBuilder(); + _rmdBuilder = new RmdBuilder(); + } + + /** + * Starts the build process of this director. + * This method acts as a facade of the whole build process. + * + * @throws BuilderException when one step of the build process fails. + */ + void direct() throws BuilderException + { + processObjectName(); + processAttributes(); + endAttributes(); + processOperations(); + endOperations(); + } + + /** + * Notifiies builder that all the operations metadata have been transmitted. + * + * @throws BuilderException when one builder raises an exception during this operation. + */ + private void endOperations() throws BuilderException + { + _capabilityBuilder.endOperations(); + _wsdlBuilder.endOperations(); + _rmdBuilder.endOperations(); + } + + /** + * Notifiies builder that all the attributes metadata have been transmitted. + * + * @throws BuilderException when one builder raises an exception during this operation. + */ + private void endAttributes() throws BuilderException + { + _capabilityBuilder.endAttributes(); + _wsdlBuilder.endAttributes(); + _rmdBuilder.endAttributes(); + } + + /** + * Injects event source object name on all builders. + * + * @throws BuilderException when one builder raises an exception during this operation. + */ + void processObjectName() throws BuilderException + { + _capabilityBuilder.begin(_eventSourceObjectName); + _wsdlBuilder.begin(_eventSourceObjectName); + _rmdBuilder.begin(_eventSourceObjectName); + } + + /** + * Injects attributes metadata on all builders. + * + * @throws BuilderException when one builder raises an exception during this operation. + */ + void processAttributes() throws BuilderException + { + for (MBeanAttributeInfo attribute : _metadata.getAttributes()) + { + _capabilityBuilder.onAttribute(attribute); + _wsdlBuilder.onAttribute(attribute); + _rmdBuilder.onAttribute(attribute); + } + } + + /** + * Injects operations metadata on all builders. + * + * @throws BuilderException when one builder raises an exception during this operation. + */ + void processOperations() + { + for (MBeanOperationInfo operation : _metadata.getOperations()) + { + _capabilityBuilder.onOperation(operation); + _wsdlBuilder.onOperation(operation); + } + } + + /** + * Returns the capabilty class. + * + * @return the capability class. + */ + Class getCapabilityClass() + { + return _capabilityBuilder.getCapabilityClass(); + } + + /** + * Returns the wsdl. + * + * @return the wsdl. + */ + Document getWsdl() + { + return _wsdlBuilder.getWsdl(); + } + + /** + * Returns the resource metadata descriptor containing metadata (rules, constraints, etc) + * for the current resource. + * The returned object is an array of Element and each of them maps a resource property. + * + * @return the resource metadata descriptor (as an array of Element). + */ + Element [] getResourceMetadataDescriptor() + { + return _rmdBuilder.getResourceMetadataDescriptor(); + } + + /** + * Injects the environment on this director. + * + * @param environment the QMan environment. + */ + void setEnvironment(Environment environment) + { + _wsdlBuilder.setEnvironment(environment); + _capabilityBuilder.setEnvironment(environment); + _rmdBuilder.setEnvironment(environment); + } + + /** + * Injectcs the ws resource on this director. + * + * @param resource the ws resource. + */ + public void setResource(Resource resource) { + _wsdlBuilder.setWsdlPath(resource.getWsdlPath()); + } +} \ No newline at end of file diff --git a/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 new file mode 100644 index 0000000000..b8a4f7766f --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifacts.java @@ -0,0 +1,56 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.capabilities; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +class WsArtifacts { + + private final Class_capabilityClass; + private final Element[] _resourceMetadataDescriptor; + private final Document _wsdl; + + public WsArtifacts( + Class capabilityClass, + Element[] resourceMetadataDescriptor, + Document wsdl) + { + this._capabilityClass = capabilityClass; + this._resourceMetadataDescriptor = resourceMetadataDescriptor; + this._wsdl = wsdl; + } + + public Class getCapabilityClass() + { + return _capabilityClass; + } + + public Element[] getResourceMetadataDescriptor() + { + return _resourceMetadataDescriptor; + } + + public Document getWsdl() + { + return _wsdl; + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..0209ddb55e --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java @@ -0,0 +1,134 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.capabilities; + +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import javax.management.MBeanInfo; +import javax.management.MBeanServer; +import javax.management.ObjectName; + +import org.apache.muse.core.Environment; +import org.apache.muse.core.Resource; +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; +import org.apache.qpid.transport.util.Logger; + +/** + * Manager for all WS-* related artifacts. + * Basically it is a factory ehnanced with a _cache mechanism so each created resource + * (WSDL, capability class, descriptor) is created and its reference is returned when requested + * again. + * + * @author Andrea Gazzarini + */ +class WsArtifactsFactory +{ + private final static Logger LOGGER = Logger.get(WsArtifactsFactory.class); + + private final MBeanServer _mxServer; + private final Environment _environment; + private Map _cache; + + /** + * Builds a new factory with the given environment and mbean server. + * + * @param environment the builder environment. + * @param mxServer the management server. + */ + public WsArtifactsFactory(Environment environment, MBeanServer mxServer) + { + this._environment = environment; + this._mxServer = mxServer; + this._cache = new HashMap(); + } + + /** + * Returns the WS artifacts corresponding with the given resource. + * + * @param resource the WS resource. + * @param objectName the resource identifier (name). + * @return the WS artifacts corresponding with the given resource. + * @throws ArtifactsNotAvailableException when some problem occurs during artifacts generation. + */ + @SuppressWarnings("unchecked") + WsArtifacts getArtifactsFor(Resource resource, ObjectName objectName) throws ArtifactsNotAvailableException + { + WsArtifacts result = null; + try + { + Hashtable keyProperties = objectName.getKeyPropertyList(); + keyProperties.remove(Names.NAME_ATTRIBUTE); + keyProperties.remove(Names.OBJECT_ID); + + ObjectName searchKey = ObjectName.getInstance(objectName.getDomain(),keyProperties); + + LOGGER.debug( + Messages.QMAN_200041_INCOMING_OBJECT_NAME_AND_DERIVED_KEY, + objectName,searchKey); + + result = _cache.get(searchKey); + if (result == null) + { + MBeanInfo metadata = _mxServer.getMBeanInfo(objectName); + + WSDMArtifactsDirector director = new WSDMArtifactsDirector(objectName,metadata); + director.setEnvironment(_environment); + director.setResource(resource); + director.direct(); + + result = new WsArtifacts( + director.getCapabilityClass(), + director.getResourceMetadataDescriptor(), + director.getWsdl()); + + _cache.put(searchKey, result); + + LOGGER.debug(Messages.QMAN_200040_WS_ARTIFACTS_CACHED,searchKey); + } + + return result; + } catch(Exception exception) + { + throw new ArtifactsNotAvailableException(result,exception,objectName); + } + } + + /** + * Utility method for create concrete instance of the given capability class. + * + * @param capabilityClass the capability class. + * @param objectName the object name that will act as the target for this capability invocations. + * @return an initialized instance of the given capability class. + * @throws InstantiationException when the class cannot be instantiated. + * @throws IllegalAccessException when this method does not have access to + * the definition of the capability class. + */ + MBeanCapability createCapability(Class capabilityClass, ObjectName objectName) + throws InstantiationException, IllegalAccessException + { + MBeanCapability capability = capabilityClass.newInstance(); + capability.setResourceObjectName(objectName); + return capability; + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..194253bf25 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.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.net.InetAddress; + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanOperationInfo; +import javax.management.ObjectName; +import javax.xml.namespace.QName; + +import org.apache.muse.core.Environment; +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.transport.util.Logger; +import org.apache.xpath.XPathAPI; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +class WsdlBuilder implements IArtifactBuilder { + + private final static Logger LOGGER = Logger.get(WsdlBuilder.class); + + private Environment _environment; + private Document _document; + private Element schema; + + private ObjectSerializer serializer = new ObjectSerializer(); + + private ObjectName _objectName; + + public void onAttribute(MBeanAttributeInfo attributeMetadata) throws BuilderException + { + try + { + if (schema == null) + { + + schema = (Element) XPathAPI.selectSingleNode( + _document.getDocumentElement(), + "/wsdl:definitions/wsdl:types/xsd:schema[@targetNamespace='http://amqp.apache.org/qpid/management/qman']"); + + } + /* + + + + + + + + + + + + + + +*/ + if (attributeMetadata.getType().equals("java.util.Map")) + { + Element prop = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","element","xsd")); + prop.setAttribute("name",attributeMetadata.getName()); + + 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 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); + schema.appendChild(prop); + } else if ("java.util.UUID".equals(attributeMetadata.getType())) + { + Element prop = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","element","xsd")); + prop.setAttribute("name", attributeMetadata.getName()); + 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); + schema.appendChild(prop); + } else { + Element propertyDeclaration = XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","element","xsd")); + propertyDeclaration.setAttribute("name",attributeMetadata.getName()); + propertyDeclaration.setAttribute("type", serializer.getXmlType(Class.forName(attributeMetadata.getType()))); + schema.appendChild(propertyDeclaration); + } + + 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"); + + Element propertyRef= XmlUtils.createElement(_document, new QName("http://www.w3.org/2001/XMLSchema","element","xsd")); + propertyRef.setAttribute("ref", "qman:"+attributeMetadata.getName()); + + wsrpProperties.appendChild(propertyRef); + + } catch(Exception exception) + { + throw new BuilderException(exception); + } + } + + public void begin(ObjectName objectName) + { + this._objectName = objectName; + } + + public void onOperation(MBeanOperationInfo operation) + { + // TODO + } + + public void endAttributes() + { + // TODO + } + + public void endOperations() + { + // TODO + } + + public Document getWsdl() + { + XmlDebugger.debug(_objectName,_document); + return _document; + } + + public void setEnvironment(Environment environment) + { + this._environment = environment; + } + + public void setWsdlPath(String wsdlPath) + { + _document = WsdlUtils.createWSDL(_environment, wsdlPath, true); + try + { + Attr location = (Attr) XPathAPI.selectSingleNode(_document, "/wsdl:definitions/wsdl:service/wsdl:port/wsdl-soap:address/@location"); + + // TODO : come faccio a recuperare l'URL sul quale gira l'applicazione? + StringBuilder builder = new StringBuilder("http://") + .append(InetAddress.getLocalHost().getHostName()) + .append(':') + .append(System.getProperty(Names.ADAPTER_PORT,"8080")) + .append('/') + .append("qman") + .append('/') + .append("services/QManWsResource"); + location.setValue(builder.toString()); + } catch(Exception exception) + { + LOGGER.error(exception,Messages.QMAN_100026_SOAP_ADDRESS_REPLACEMENT_FAILURE); + } + } +} diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java new file mode 100644 index 0000000000..5d158aa683 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java @@ -0,0 +1,66 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.common; + +import javax.management.ObjectName; +import javax.xml.namespace.QName; + +import org.apache.muse.ws.addressing.EndpointReference; +import org.apache.qpid.management.Names; + +/** + * Thrown when some operation has been requested on an entity and the entity hasn't been found + * on the managed domain. + * + * @author Andrea Gazzarini + */ +public class EntityInstanceNotFoundFault extends QManFault +{ + private static final long serialVersionUID = -3772811863214553615L; + + private final static QName EXCEPTION_QNAME = new QName( + Names.NAMESPACE_URI, + "EntityInstanceNotFoundFault", + Names.PREFIX); + + /** + * Builds a new exception with the given endpoint reference and the object name of the entity + * that wasn't found. + * + * @param endpointReference the origin endpoint reference of this exception. + * @param targetEntityName the object name of the not found entity. + */ + public EntityInstanceNotFoundFault(EndpointReference endpointReference, ObjectName targetEntityName) + { + super(endpointReference,EXCEPTION_QNAME,createMessage(targetEntityName)); + } + + /** + * "Compose method" which creates the detail message for this exception. + * + * @param targetEntityName the object name. + * @return the detail message for this exception. + */ + private static String createMessage(ObjectName targetEntityName) + { + return String.format("Entity associated with name %s was not found.",targetEntityName); + } +} diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/NoSuchAttributeFault.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/NoSuchAttributeFault.java new file mode 100644 index 0000000000..81049ba460 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/NoSuchAttributeFault.java @@ -0,0 +1,68 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.common; + +import javax.management.ObjectName; +import javax.xml.namespace.QName; + +import org.apache.muse.ws.addressing.EndpointReference; +import org.apache.qpid.management.Names; + +/** + * This is the exception encapsulating the fault that will be thrown in case of + * method invocation failure. + * + * @author Andrea Gazzarini + */ +public class NoSuchAttributeFault extends QManFault +{ + private static final long serialVersionUID = 5977379710882983474L; + + /** + * Builds a new exception with the given endpoint reference and method invocation exception. + * This constructor will be used when the invocation thrown the MethodInvocationException. + * + * @param endpointReference the endpoint reference. + * @param exception the method invocation exception containing failure details. + */ + public NoSuchAttributeFault(EndpointReference endpointReference, ObjectName name, String attributeName) + { + super( + endpointReference, + new QName( + Names.NAMESPACE_URI, + "NoSuchAttributeFault", + Names.PREFIX), + createMessage(name, attributeName)); + } + + /** + * Creates the reason message for this fault. + * + * @param name the object name of the managed entity. + * @param attributeName the name of the attribute that wasn't found. + * @return the reason message for this fault. + */ + private static String createMessage(ObjectName name, String attributeName) + { + return String.format("Attribute %s was not found on entity %s",attributeName,name); + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ObjectNameIdFactory.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ObjectNameIdFactory.java new file mode 100644 index 0000000000..be3bbb48d1 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ObjectNameIdFactory.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.common; + +import javax.xml.namespace.QName; + +import org.apache.muse.core.routing.ResourceIdFactory; +import org.apache.muse.ws.addressing.WsaConstants; + +/** + * ResourceIdFactory implementation that is using an objectName as + * resource identifier. + * + * @author Andrea Gazzarini + */ +public class ObjectNameIdFactory implements ResourceIdFactory +{ + public QName getIdentifierName() + { + return WsaConstants.DEFAULT_RESOURCE_ID_QNAME; + } + + /** + * Returns the object name used as a resource identifier. + * Developer note : this factory is highly coupled with ThreadSessionManager stuff because + * the object name that will be used as identifier is supposed to be in the thread session. + * + * @return the object name used as a resource identifier. + */ + public String getNextIdentifier() + { + return ThreadSessionManager.getInstance().getSession().getObjectName().getCanonicalName(); + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManFault.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManFault.java new file mode 100644 index 0000000000..9c78dfa0bb --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManFault.java @@ -0,0 +1,72 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.common; + +import javax.xml.namespace.QName; + +import org.apache.muse.ws.addressing.EndpointReference; +import org.apache.muse.ws.resource.basefaults.BaseFault; +import org.apache.qpid.management.Names; + +/** + * Base class for QMan thrown faults. + * This should be thrown to denote a situation where a not-well cause could be determined. + */ +public class QManFault extends BaseFault +{ + private static final long serialVersionUID = 5977379710882983474L; + private final static QName SERVICE = new QName( + Names.NAMESPACE_URI, + "Service", + Names.PREFIX); + + private final static QName EXCEPTION_QNAME = new QName( + Names.NAMESPACE_URI, + "QManFault", + Names.PREFIX); + + /** + * Builds a new exception with the given endpoint reference and the exception cause. + * + * @param endpointReference the endpoint reference. + * @param cause the exception cause. + */ + public QManFault(EndpointReference endpointReference, Exception cause) + { + super(EXCEPTION_QNAME,cause.getMessage()); + setCode(SERVICE); + setOriginReference(endpointReference); + } + + /** + * Builds a new exception with the given endpoint reference, qname and detail message. + * + * @param endpointReference the endpoint reference. + * @param qname the qname of this exception. + * @param message the detail message of this exception. + */ + public QManFault(EndpointReference endpointReference, QName qname, String message) + { + super(qname,message); + setOriginReference(endpointReference); + setCode(SERVICE); + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java new file mode 100644 index 0000000000..bc214b8b25 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java @@ -0,0 +1,105 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.common; + +import javax.management.ObjectName; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + + +/** + * Thread-scoped session. + * + * @author Andrea Gazzarini + */ +public class ThreadSession +{ + private ObjectName _objectName; + private Document _wsdl; + private Element [] additionalProperties; + /** + * Empty constructor. + */ + ThreadSession() + { + } + + /** + * Gets the object name associated with this thread session. + * + * @return the object name associated with this thread session. + */ + public ObjectName getObjectName() + { + return _objectName; + } + + /** + * Sets the object name on this thread session. + * + * @param the object name of this thread session.. + */ + public void setObjectName(ObjectName objectName) + { + this._objectName = objectName; + } + + /** + * Sets the WSDL document on this thread session. + * + * @param the WSDL document of this thread session.. + */ + public void setWsdlDocument(Document wsdlDoc) + { + this._wsdl = wsdlDoc; + } + + /** + * Gets the WSDL document associated with this thread session. + * + * @return the WSDL document associated with this thread session. + */ + public Document getWsdlDocument() + { + return _wsdl; + } + + /** + * Gets the RDM elements associated with this thread session. + * + * @return the RDM elements associated with this thread session. + */ + public Element[] getResourceMetadataDescriptor() + { + return additionalProperties; + } + + /** + * Sets the WSDL elements on this thread session. + * + * @param the WSDL elements of this thread session.. + */ + public void setResourceMetadataDescriptor(Element[] rmd) + { + this.additionalProperties = rmd; + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSessionManager.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSessionManager.java new file mode 100644 index 0000000000..6a081bfec4 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSessionManager.java @@ -0,0 +1,68 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.common; + +/** + * Thread session manager used to handle thread-scoped sessions. + * + * @author Andrea Gazzarini + */ +public final class ThreadSessionManager +{ + private static ThreadSessionManager instance = new ThreadSessionManager(); + + private ThreadLocal sessions; + + /** + * Builds and initializes a new manager. + */ + private ThreadSessionManager() + { + this.sessions = new ThreadLocal(); + } + + /** + * Returns the singleton instance of this manager. + * + * @return the singleton instance of this manager. + */ + public static ThreadSessionManager getInstance() + { + return instance; + } + + /** + * Returns (or create and returns) the session associated with the + * current thread. + * + * @return the thread session. + */ + public ThreadSession getSession() + { + ThreadSession session = (ThreadSession) sessions.get(); + if (session == null) + { + session = new ThreadSession(); + sessions.set(session); + } + return session; + } +} \ No newline at end of file diff --git a/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 new file mode 100644 index 0000000000..0c70af437e --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java @@ -0,0 +1,81 @@ +package org.apache.qpid.management.wsdm.muse.engine; + +import java.io.File; +import java.net.InetAddress; +import java.net.URI; +import java.net.UnknownHostException; + +import javax.servlet.ServletContext; + +import org.apache.muse.core.AbstractEnvironment; +import org.apache.muse.util.FileUtils; +import org.apache.muse.ws.addressing.EndpointReference; +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; +import org.apache.qpid.transport.util.Logger; + +/** + * QMan Adapter enviroment implementation. + * + * @author Andrea Gazzarini + */ +public class WSDMAdapterEnvironment extends AbstractEnvironment +{ + private final static Logger LOGGER = Logger.get(WSDMAdapterEnvironment.class); + private final File _realDirectory; + + /** + * Builds a new qman environment with the given application context. + * + * @param servletContext the application context. + */ + public WSDMAdapterEnvironment(ServletContext servletContext) + { + String realDirectoryPath = servletContext.getRealPath(Names.WEB_APP_CLASSES_FOLDER); + + _realDirectory = (realDirectoryPath != null) + ? new File(realDirectoryPath) + : FileUtils.CURRENT_DIR; + + String host = null; + + try { + host = InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + host = "localhost"; + } + + String defaultURI = new StringBuilder() + .append("http://") + .append(host) + .append(":") + .append(System.getProperty(Names.ADAPTER_PORT)) + .append(servletContext.getContextPath()) + .append("/services/adapter") + .toString(); + + LOGGER.info(Messages.QMAN_000029_DEFAULT_URI, defaultURI); + + setDefaultURI(defaultURI); + } + + /** + * Returns the endpoint created starting by this application default URI. + * + * @return the endpoint created starting by this application default URI. + */ + public EndpointReference getDeploymentEPR() + { + return new EndpointReference(URI.create(getDefaultURI())); + } + + /** + * Returns the application classes folder. + * + * @return the application classes folder. + */ + public File getRealDirectory() + { + return _realDirectory; + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterIsolationLayer.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterIsolationLayer.java new file mode 100644 index 0000000000..0ca19bc727 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterIsolationLayer.java @@ -0,0 +1,36 @@ +package org.apache.qpid.management.wsdm.muse.engine; + +import javax.servlet.ServletContext; + +import org.apache.muse.core.Environment; +import org.apache.muse.core.platform.mini.MiniIsolationLayer; + +/** + * QMan specific implementation of the Apache Muse isolation layer. + * If you are a Muse expert you were wondering why don't we use the muse default implementation... + * well, + * + * @author Andrea Gazzarini + */ +public class WSDMAdapterIsolationLayer extends MiniIsolationLayer +{ + /** + * Builds a new isolation layer with the given application context. + * + * @param initialContext the application context. + */ + public WSDMAdapterIsolationLayer(ServletContext initialContext) + { + super(null, initialContext); + } + + /** + * WSDMAdapterEnvironment factory method. + * + * @return the environment. + */ + protected Environment createEnvironment() + { + return new WSDMAdapterEnvironment(getInitialContext()); + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..50b1c7cd33 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java @@ -0,0 +1,592 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.muse.resources; + +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import javax.xml.namespace.QName; + +import org.apache.muse.core.Capability; +import org.apache.muse.core.Environment; +import org.apache.muse.core.ResourceManager; +import org.apache.muse.core.routing.MessageHandler; +import org.apache.muse.util.xml.XmlUtils; +import org.apache.muse.ws.addressing.EndpointReference; +import org.apache.muse.ws.addressing.WsaConstants; +import org.apache.muse.ws.addressing.soap.SoapConstants; +import org.apache.muse.ws.addressing.soap.SoapFault; +import org.apache.muse.ws.addressing.soap.SoapUtils; +import org.apache.muse.ws.resource.WsResource; +import org.apache.muse.ws.resource.metadata.MetadataDescriptor; +import org.apache.muse.ws.resource.metadata.WsrmdConstants; +import org.apache.muse.ws.resource.metadata.impl.SimpleMetadataDescriptor; +import org.apache.muse.ws.resource.metadata.impl.WsrmdUtils; +import org.apache.muse.ws.resource.properties.ResourcePropertyCollection; +import org.apache.muse.ws.resource.properties.impl.SimpleResourcePropertyCollection; +import org.apache.muse.ws.resource.properties.impl.WsrpUtils; +import org.apache.muse.ws.resource.properties.schema.ResourcePropertiesSchema; +import org.apache.muse.ws.resource.properties.schema.impl.SimpleResourcePropertiesSchema; +import org.apache.muse.ws.wsdl.WsdlUtils; +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; +import org.apache.qpid.management.wsdm.common.ThreadSessionManager; +import org.apache.qpid.transport.util.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * QMan WS resource. + * This is the WS Resource wrapper of a QMan managed entity. + * + * @author Andrea Gazzarini + * TODO :Refactoring :: use STATE Pattern! + */ +@SuppressWarnings("unchecked") +public class QManWsResource implements WsResource +{ + private final static Logger LOGGER = Logger.get(QManWsResource.class); + + // Utility class for logging. + private final static class Log { + static void debugElement(String message,Element element) + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug(message, XmlUtils.toString(element)); + } + } + } + + private Map _capabilitiesByAction = new HashMap(); + private Map _capabilitiesByURI = new LinkedHashMap(); + + private String _contextPath; + private Environment _environment; + private EndpointReference _enpointReference; + + private boolean _hasBeenInitialized; + private boolean _hasBeenShutdown; + + private ResourceManager _resourceManager; + private ResourcePropertyCollection _properties; + + private Map _initParameters = Collections.EMPTY_MAP; + + private java.util.logging.Logger _logger; + + private Document _wsdl; + private String _wsdlPath; + private QName _wsdlPortType; + + /** + * Adds the given capability to this resource. + * + * @param capability the capability to be added. + */ + public void addCapability(Capability capability) + { + capability.setResource(this); + capability.setLog(getLog()); + capability.setEnvironment(getEnvironment()); + + String uri = capability.getCapabilityURI(); + _capabilitiesByURI.put(uri, capability); + + LOGGER.debug(Messages.QMAN_200033_CAPABILITY_CLASS_HAS_BEEN_ADDED, capability.getClass(),uri); + } + + /** + * Returns the capability associated with the given URI. + * + * @return the capability associated with the given URI. + */ + public final Capability getCapability(String capabilityURI) + { + 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 the capability associated with the given action. + * + * @param action the wsa:action of the requested capability. + * @return the capability associated with the given action. + */ + protected Capability getCapabilityForAction(String action) + { + return (Capability)_capabilitiesByAction.get(action); + } + + /** + * Returns a collection with all registered capability URIs. + * + * @return a collection with all registered capability URIs. + */ + public final Collection getCapabilityURIs() + { + return Collections.unmodifiableSet(_capabilitiesByURI.keySet()); + } + + /** + * Returns the context path of this resource. + * + * @return the context path of this resource. + */ + public final String getContextPath() + { + return _contextPath; + } + + /** + * Returns the endpoint reference of this resource. + * + * @return the endpoint reference of this resource. + */ + public EndpointReference getEndpointReference() + { + return _enpointReference; + } + + /** + * Returns the enviroment associated with this resource. + * + * @return the enviroment associated with this resource. + */ + public final Environment getEnvironment() + { + return _environment; + } + + /** + * Returns the initialization parameter of this resource associated with + * the given name. + * + * @param name the init parameter name. + * @return the initialization parameter associated with the given name. + */ + public final String getInitializationParameter(String name) + { + return (String)getInitializationParameters().get(name); + } + + /** + * Returns the map containing all init parameters of this resource. + * + * @return the map containing all init parameters of this resource. + */ + public final Map getInitializationParameters() + { + return _initParameters; + } + + /** + * N.A. This resource uses QMan logging instead of plain java.util.logger + * implementation. + */ + public final java.util.logging.Logger getLog() + { + return _logger; + } + + /** + * Returns the resource manager associated with this resource. + * + * @return the resource manager associated with this resource. + */ + public ResourceManager getResourceManager() + { + return _resourceManager; + } + + /** + * Returns the wsdl (relative) path of this resource. + * + * @return the wsdl (relative) path of this resource. + */ + public String getWsdlPath() + { + return _wsdlPath; + } + + /** + * Returns the port type of this resource. + * + * @return the port type of this resource. + */ + public final QName getWsdlPortType() + { + return _wsdlPortType; + } + + /** + * Returns true if this resource has been initialized, false otherwise. + * + * @return true if this resource has been initialized, false otherwise. + */ + public final boolean hasBeenInitialized() + { + return _hasBeenInitialized; + } + + /** + * Returns true if this resource has been shutdown, false otherwise. + * + * @return true if this resource has been shutdown, false otherwise. + */ + public final boolean hasBeenShutdown() + { + return _hasBeenShutdown; + } + + /** + * Checks if a capability with the given URI is available for this resource. + * + * @return true if a capability with the given URI is available for this resource, false otherwise. + */ + public final boolean hasCapability(String capabilityURI) + { + return getCapability(capabilityURI) != null; + } + + /** + * Creates a metadata descriptor for this resource. + * + * @param wsdl the WSDL document. + * @return a metadata descriptor for this resource. + * @throws SoapFault when it's not possible build the descriptor. + */ + protected MetadataDescriptor createMetadataDescriptor(Document wsdl) throws SoapFault + { + try + { + Element portTypeXML = WsdlUtils.getPortType(wsdl, getWsdlPortType()); + + String rmdName = XmlUtils.getAttribute(portTypeXML, WsrmdConstants.DESCRIPTOR_ATTR_QNAME); + String rmdPath = XmlUtils.getAttribute(portTypeXML, WsrmdConstants.DESCRIPTOR_LOCATION_ATTR_QNAME); + + LOGGER.debug(Messages.QMAN_200034_RMD_NAME, rmdName); + LOGGER.debug(Messages.QMAN_200035_RMD_PATH, rmdPath); + + Environment env = getEnvironment(); + String path = env.createRelativePath(getWsdlPath(), rmdPath); + Document rmdDoc = env.getDocument(path); + + Element[] additionalProperties = ThreadSessionManager.getInstance().getSession().getResourceMetadataDescriptor(); + Element metadataDescriptor = WsrmdUtils.getMetadataDescriptor(rmdDoc, rmdName); + + for (Element element : additionalProperties) + { + rmdDoc.adoptNode(element); + metadataDescriptor.appendChild(element); + + Log.debugElement(Messages.QMAN_200036_ADDITIONAL_RMD_PROPERTY,element); + } + + return new SimpleMetadataDescriptor(metadataDescriptor); + } + catch(Exception exception) + { + LOGGER.error(exception,Messages.QMAN_100021_RMD_BUID_FAILURE,getContextPath()); + throw new SoapFault(exception); + } + } + + /** + * Creates a WSRP document representing schema properties for this resource. + * + * @param wsdl the DOM document holding the resource's WSDL. + * @return the WSRP document schema. + */ + protected ResourcePropertiesSchema createPropertiesSchema(Document wsdl) + { + QName wsrpName = WsrpUtils.getPropertiesName(wsdl, getWsdlPortType()); + Element wsrpDoc = WsdlUtils.getElementDeclaration(wsdl, wsrpName); + return new SimpleResourcePropertiesSchema(wsrpName, wsrpDoc); + } + + /** + * Returns the collection containing all properties of this resource. + * + * @return the collection containing all properties of this resource. + */ + public final ResourcePropertyCollection getPropertyCollection() + { + return _properties; + } + + /** + * Return the WSDL document of this resource. + * + * @return the WSDL document of this resource. + */ + public Document getWsdl() + { + return _wsdl; + } + + /** + * Initializes this resources. + * + * @throws SoapFault when the initialization fails. + */ + public void initialize() throws SoapFault + { + _properties = new SimpleResourcePropertyCollection(); + _wsdl = ThreadSessionManager.getInstance().getSession().getWsdlDocument(); + + ResourcePropertiesSchema schema = createPropertiesSchema(_wsdl); + _properties.setSchema(schema); + + MetadataDescriptor metadata = createMetadataDescriptor(_wsdl); + _properties.setMetadata(metadata); + + initializeCapabilities(); + + _hasBeenInitialized = true; + + _properties.applyMetadata(); + + if (Boolean.parseBoolean(getInitializationParameter(Names.VALIDATE_WSRP_PARAM))) + { + _properties.validateSchema(); + } + + _properties.validateMetadata(); + } + + /** + * Initializes capabilities of this resource. + * + * @throws SoapFault when at least one capability fails to initialize. + */ + public void initializeCapabilities() throws SoapFault + { + for (Entry entry : _capabilitiesByURI.entrySet()) + { + Capability capability = entry.getValue(); + capability.initialize(); + + for (Object action : capability.getActions()) + { + _capabilitiesByAction.put((String)action, capability); + } + + capability.initializeCompleted(); + } + } + + /** + * Invokes the action specified in the given soap request on this resource. + * + * @param requestBody the SOAP body. + * @return the result of the invocation as org.w3c.dom.Element + */ + public Element invoke(Element requestBody) + { + String action = _environment.getAddressingContext().getAction(); + Capability capability = getCapabilityForAction(action); + + // Sanity check : is there a capability for the given action? + if (capability == null) + { + SoapFault wsaFault = new SoapFault(String.format(Messages.ACTION_NOT_SUPPORTED, action,getContextPath())); + + wsaFault.setCode(SoapConstants.SENDER_QNAME); + wsaFault.setSubCode(WsaConstants.ACTION_NOT_SUPPORTED_FAULT_QNAME); + + Element detail = XmlUtils.createElement(WsaConstants.PROBLEM_ACTION_QNAME); + XmlUtils.setElement(detail, WsaConstants.ACTION_QNAME, action); + wsaFault.setDetail(detail); + + LOGGER.error(Messages.QMAN_100020_ACTION_NOT_SUPPORTED, action,getContextPath()); + + return wsaFault.toXML(); + } + + MessageHandler handler = capability.getMessageHandler(action); + Method method = handler.getMethod(); + + try + { + Object[]parameters = handler.fromXML(requestBody); + Object result = method.invoke(capability, parameters); + return handler.toXML(result); + } + catch (Throwable throwable) + { + SoapFault response = SoapUtils.convertToFault( + (throwable.getCause()!= null) + ? throwable.getCause() + : throwable); + return response.toXML(); + } + } + + /** + * Sets the context path of this resource. + * + * @param contextPath the context path of this resource. + */ + public final void setContextPath(String contextPath) + { + _contextPath = contextPath; + } + + /** + * Sets the endpoint reference of this resource. + * + * @param endpointReference the endpoint reference of this resource. + */ + public final void setEndpointReference(EndpointReference endpointReference) + { + if (_enpointReference != null && hasBeenInitialized()) + throw new RuntimeException(("ExistingResourceEPR")); + + _enpointReference = endpointReference; + } + + /** + * Sets the context environment of this resource. + * + * @param environment the context environment of this resource. + */ + public final void setEnvironment(Environment environment) + { + _environment = environment; + } + + /** + * Sets the initialization parameters of this resource. + * + * @param parameters the init parameters of this resource. + */ + public final void setInitializationParameters(Map parameters) + { + _initParameters = (parameters != null) + ? parameters + : Collections.EMPTY_MAP; + } + + /** + * N.A. for this resource. QMan logging mechanism is used for that. + */ + public final void setLog(java.util.logging.Logger log) + { + _logger = log; + } + + /** + * Sets the resource manager owner of this resource. + * + * @param manager the resource manager of this resource. + */ + public void setResourceManager(ResourceManager manager) + { + _resourceManager = manager; + } + + /** + * Sets the WSDL (relative) path of this resource. + * + * @param wsdlPath the WSDL (relative) path of this resource. + */ + public final void setWsdlPath(String wsdlPath) + { + this._wsdlPath = wsdlPath; + } + + /** + * Sets the port type of this resource. + * + * @param wsdlPortType the port type of this resource. + */ + public final void setWsdlPortType(QName wsdlPortType) + { + _wsdlPortType = wsdlPortType; + } + + /** + * Shutdown procedure for this resource. + * + * @throws SoapFault when the shutdown procedure fails. + */ + public synchronized void shutdown() throws SoapFault + { + if (hasBeenShutdown()) + throw new SoapFault(("ResourceAlreadyDestroyed")); + + if (!hasBeenInitialized()) + throw new SoapFault(("ResourceNotInitialized")); + + _hasBeenShutdown = true; + + shutdownCapabilities(); + + ResourceManager manager = getResourceManager(); + + // + // remove resource visibility + // + if (manager.getResource(_enpointReference) != null) + manager.removeResource(_enpointReference); + } + + /** + * Shutdown procedure for all registered capabilities of this resource. + * + * @throws SoapFault when at least one capability shutdown fails. + */ + protected void shutdownCapabilities() throws SoapFault + { + for (Entry entry : _capabilitiesByURI.entrySet()) + { + Capability capabilty = entry.getValue(); + capabilty.prepareShutdown(); + capabilty.shutdown(); + } + } + + /** + * Returns a string representation of this resource. + * Basically the resource endpoint reference (as a string) is returned. + * + * @return the resource endpoint reference (as a string) is returned. + */ + public String toString() + { + return getEndpointReference().toString(); + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ByteArraySerializer.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ByteArraySerializer.java new file mode 100644 index 0000000000..88fbe5df6d --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ByteArraySerializer.java @@ -0,0 +1,85 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.muse.serializer; + +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; + +import org.apache.muse.core.serializer.Serializer; +import org.apache.muse.util.xml.XmlUtils; +import org.apache.muse.ws.addressing.soap.SoapFault; +import org.w3c.dom.Element; + +import sun.misc.BASE64Decoder; +import sun.misc.BASE64Encoder; + +/** + * Implementation of Muse Serializer for byte array type. + * + * @author Andrea Gazzarini + */ +public class ByteArraySerializer implements Serializer { + + /** + * Return a byte array representation of the given xml element. + * + * @param xml the element to unmarshal. + * @throws SoapFault when the unmarshalling fails. + */ + public Object fromXML(Element xml) throws SoapFault + { + try + { + return new BASE64Decoder().decodeBuffer(xml.getTextContent()); + } catch (Exception exception) + { + throw new SoapFault(exception); + } + } + + /** + * Returns the java type associated to this class. + * + * @return the java type associated to this class. + */ + public Class getSerializableType() + { + return byte[].class; + } + + /** + * Return an xml representation of the given byte array with the given name. + * + * @param object the byte array to marshal. + * @param qname the qualified (xml) name of the object to use in xml representation. + * @return the xml representation of the byte array. + * @throws SoapFault when the marshalling fails. + */ + public Element toXML(Object object, QName qname) throws SoapFault + { + Element element = XmlUtils.createElement( + qname, + new BASE64Encoder().encode((byte[]) object)); + element.setAttribute("xmlns:xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI); + element.setAttribute("xsi:type","xsd:base64Binary"); + return element; + } +} \ No newline at end of file diff --git a/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 new file mode 100644 index 0000000000..8a25baf4bd --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java @@ -0,0 +1,137 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.muse.serializer; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; + +import org.apache.muse.core.serializer.Serializer; +import org.apache.muse.core.serializer.SerializerRegistry; +import org.apache.muse.util.xml.XmlUtils; +import org.apache.muse.ws.addressing.soap.SoapFault; +import org.apache.qpid.management.Names; +import org.w3c.dom.Element; + +/** + * Implementation of Muse Serializer for Map type. + * + * + * + * + * + * + * + * + * @author Andrea Gazzarini + */ +public class MapSerializer implements Serializer +{ + + ByteArraySerializer byteArraySerializer = new ByteArraySerializer(); + + /** + * Return a map representation of the given xml element. + * + * @param xml the element to unmarshal. + * @throws SoapFault when the unmarshalling fails. + */ + public Object fromXML(Element xml) throws SoapFault + { + Map result = new HashMap(); + Element[] children = XmlUtils.getAllElements(xml); + Serializer objectDeserializer = SerializerRegistry.getInstance().getSerializer(Object.class); + + for (Element entry : children) + { + Element[] keysAndValues = XmlUtils.getAllElements(entry); + Object key = null; + Object value = null; + for (Element element : keysAndValues) + { + if (Names.KEY.equals(element.getNodeName())) + { + key = objectDeserializer.fromXML(element); + } else if (Names.VALUE.equals(element.getNodeName())) + { + if (value.getClass()==byte[].class) + { + value = byteArraySerializer.fromXML(element); + } else + { + value = objectDeserializer.fromXML(element); + } + } + } + result.put(key, value); + } + return result; + } + + /** + * Returns the java type associated to this class. + * + * @return the java type associated to this class. + */ + public Class getSerializableType() + { + return Map.class; + } + + /** + * Return an xml representation of the given Map with the given name. + * + * @param object the Map to marshal. + * @param qname the qualified (xml) name of the object to use in xml representation. + * @return the xml representation of the given Map. + * @throws SoapFault when the marshalling fails. + */ + public Element toXML(Object obj, QName qname) throws SoapFault + { + Serializer objectSerializer = SerializerRegistry.getInstance().getSerializer(Object.class); + Map data = (Map) obj; + + String namespaceURI = qname.getNamespaceURI(); + String prefix = qname.getPrefix(); + + QName entryQName = new QName(namespaceURI,Names.ENTRY,prefix); + QName keyQName = new QName(namespaceURI,Names.KEY,prefix); + QName valueQName = new QName(namespaceURI,Names.VALUE,prefix); + + 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)); + if (mapEntry.getValue().getClass() == byte[].class) { + entry.appendChild(byteArraySerializer.toXML(mapEntry.getValue(), valueQName)); + } else { + entry.appendChild(objectSerializer.toXML(mapEntry.getValue(), valueQName)); + } + root.appendChild(entry); + } + return root; + } +} \ No newline at end of file diff --git a/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 new file mode 100644 index 0000000000..7569ace181 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ObjectSerializer.java @@ -0,0 +1,175 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.muse.serializer; + +import java.net.URI; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; + +import org.apache.muse.core.serializer.Serializer; +import org.apache.muse.core.serializer.SerializerRegistry; +import org.apache.muse.ws.addressing.soap.SoapFault; +import org.apache.qpid.management.Names; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; + +/** + * Generic Serializer for objects. + * It is a general-purpose serializer used for encoding Object values. + */ +public class ObjectSerializer implements Serializer +{ + /** + * Mapping between xsd and java types. + */ + private Map> xml2Java = new HashMap>(); + { + 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:QName",QName.class); + xml2Java.put("xsd:element",Element.class); + xml2Java.put("xsd:base64Binary",byte[].class); + } + + private Map, String> java2Xml = new HashMap, String>(); + { + java2Xml.put(Long.class,"xsd:long"); + java2Xml.put(long.class,"xsd:long"); + java2Xml.put(Boolean.class,"xsd:boolean"); + java2Xml.put(Boolean.class,"xsd:boolean"); + java2Xml.put(Double.class,"xsd:double"); + java2Xml.put(Double.class,"xsd:double"); + java2Xml.put(Float.class,"xsd:float"); + java2Xml.put(Float.class,"xsd:float"); + java2Xml.put(Integer.class,"xsd:integer"); + java2Xml.put(Integer.class,"xsd:integer"); + java2Xml.put(Integer.class,"xsd:int"); + java2Xml.put(Integer.class,"xsd:int"); + 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"); + } + + /** + * Converts the incoming element into the appropriate Java type. + * The method will fail if : + * + *
1) The element has no xsi:type attribute; + *
2) The xsi:type attribute has no corresponding java type on this serializer mappings. + * + * @param elementData the xml element containing data to be unmarshalled.l + * @return the java object as result of xml element unmarshalling. + * @throws SoapFault when the marshalling fails. + */ + public Object fromXML(Element elementData) throws SoapFault + { + Attr typeAttribute = elementData.getAttributeNodeNS( + XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, + Names.TYPE); + + if (typeAttribute == null) + { + throw new SoapFault( + "No type attribute was found for the current element. " + + "If you are using this serializer, in order to unmarshal the opportune type the xsi:type must be specified."); + } + + Class clazz = xml2Java.get(typeAttribute.getValue()); + + if (clazz == null) + { + throw new SoapFault(String.format("No corresponding class was found on this serializer mappings for xsi:type %s.",typeAttribute)); + } + + if (clazz == byte[].class) { + return new ByteArraySerializer().fromXML(elementData); + } + + return SerializerRegistry.getInstance().getSerializer(clazz).fromXML(elementData); + } + + /** + * As this serializer is supposed to deal with generic object types, this method returns Object.class. + * + * @return Object.class + */ + public Class getSerializableType() + { + return Object.class; + } + + /** + * Converts the given object (with the given qname) in XML format. + * This method fails if there's no corresponding xml type for the given runtime type of the input object. + * + * @param obj the object to be marshalled. + * @param qname the qualified name that will be used in encoding. + */ + public Element toXML(Object obj, QName qname) throws SoapFault + { + Class clazz = obj.getClass(); + + Element result = null; + + if (clazz == byte[].class) { + result = new ByteArraySerializer().toXML(obj,qname); + } else { + result = SerializerRegistry.getInstance().getSerializer(clazz).toXML(obj,qname); + } + result.setAttribute(Names.XSI_TYPE, java2Xml.get(clazz)); + return result; + } + + /** + * Returns the xml type associated with the given class. + * + * @param clazz the class. + * @return the xml type associated with the given class. + */ + public String getXmlType(Class clazz) + { + return java2Xml.get(clazz); + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/UUIDSerializer.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/UUIDSerializer.java new file mode 100644 index 0000000000..408a8de6cf --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/UUIDSerializer.java @@ -0,0 +1,72 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.wsdm.muse.serializer; + +import java.util.UUID; + +import javax.xml.namespace.QName; + +import org.apache.muse.core.serializer.Serializer; +import org.apache.muse.util.xml.XmlUtils; +import org.apache.muse.ws.addressing.soap.SoapFault; +import org.w3c.dom.Element; + +/** + * Implementation of Muse Serializer for UUID type. + * + * @author Andrea Gazzarini + */ +public class UUIDSerializer implements Serializer +{ + /** + * Return a UUID representation of the given xml element. + * + * @param xml the element to unmarshal. + * @throws SoapFault when the unmarshalling fails. + */ + public Object fromXML(Element elementData) throws SoapFault + { + return UUID.fromString(elementData.getTextContent()); + } + + /** + * Returns the java type associated to this class. + * + * @return the java type associated to this class. + */ + public Class getSerializableType() + { + return UUID.class; + } + + /** + * Return an xml representation of the given UUID with the given name. + * + * @param object the UUID to marshal. + * @param qname the qualified (xml) name of the object to use in xml representation. + * @return the xml representation of the UUID. + * @throws SoapFault when the marshalling fails. + */ + public Element toXML(Object obj, QName qname) throws SoapFault + { + return XmlUtils.createElement(qname, String.valueOf(obj)); + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/org/apache/qpid/qman/debug/XmlDebugger.java b/java/management/client/src/main/java/org/apache/qpid/qman/debug/XmlDebugger.java new file mode 100644 index 0000000000..600bb51858 --- /dev/null +++ b/java/management/client/src/main/java/org/apache/qpid/qman/debug/XmlDebugger.java @@ -0,0 +1,92 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qman.debug; + +import javax.management.ObjectName; + +import org.apache.muse.util.xml.XmlUtils; +import org.apache.qpid.transport.util.Logger; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Utility class used for debbugging XML messages + * + * @author Andrea Gazzarini + */ +public class XmlDebugger { + public final static Logger LOGGER = Logger.get(XmlDebugger.class); + + /** + * Prints out to log the given node. + * + * @param node the xml node to be printed out. + */ + public static void debug(Node node) + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug(XmlUtils.toString(node, false,true)); + } + } + + /** + * Prints out to log the given node. + * + * @param node the xml node to be printed out. + */ + public static void debug(ObjectName resourceId, Node node) + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug(resourceId+" : "+XmlUtils.toString(node, false,true)); + } + } + + + /** + * Prints out to log the given element array. + * + * @param elements the element array to be printed out. + */ + public static void debug(Element [] elements) + { + if (LOGGER.isDebugEnabled()) + { + StringBuilder builder = new StringBuilder(); + for (Element element : elements) { + builder.append(XmlUtils.toString(element,false,true)); + builder.append(System.getProperty("line.separator")); + } + LOGGER.debug(builder.toString()); + } + } + + /** + * Prints out to log the given node. + * + * @param node the xml node to be printed out. + */ + public static void debug(String node) + { + LOGGER.debug(node); + } +} \ No newline at end of file diff --git a/java/management/client/src/main/java/router-entries/adapter/resource-instance-1.xml b/java/management/client/src/main/java/router-entries/adapter/resource-instance-1.xml new file mode 100644 index 0000000000..f7d72c2903 --- /dev/null +++ b/java/management/client/src/main/java/router-entries/adapter/resource-instance-1.xml @@ -0,0 +1,2 @@ + + diff --git a/java/management/client/src/main/java/wsdl/QManAdapter.rmd b/java/management/client/src/main/java/wsdl/QManAdapter.rmd new file mode 100644 index 0000000000..865fe87592 --- /dev/null +++ b/java/management/client/src/main/java/wsdl/QManAdapter.rmd @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/java/management/client/src/main/java/wsdl/QManAdapter.wsdl b/java/management/client/src/main/java/wsdl/QManAdapter.wsdl new file mode 100644 index 0000000000..a0ab85c321 --- /dev/null +++ b/java/management/client/src/main/java/wsdl/QManAdapter.wsdl @@ -0,0 +1,419 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Connects QMan with a new broker. + + + + + + + Returns an array containing values for the requested properties. + Note that using this method it's possibile to retrieve only the value of the QManService properties. + That is : this method is not supposed to be used for retrieve attributes of the QMan managed entities. For that, the GetManagedEntityAttributeValue must be used. + + + + + + + + + Returns resource's entire WS-RP document, with the most up-to-date values of all properties. Note that using this method it's possibile to retrieve only the value of the QManService properties. + That is : this method is not supposed to be used for retrieve attributes of the QMan managed entities. For that, the GetManagedEntityAttributeValue must be used. + + + + + + + + Returns the value of the given property. Note that using this method it's possibile to retrieve only the value of the QManService properties. + That is : this method is not supposed to be used for retrieve attributes of the QMan managed entities. For that, the GetManagedEntityAttributeValue must be used. + + + + + + + + + + Implementation of the WS-MetadataExchange GetMetadata port type. Note that the only supported metadata type (dialect) is WSDL. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/management/client/src/main/java/wsdl/QManWsResource.rmd b/java/management/client/src/main/java/wsdl/QManWsResource.rmd new file mode 100644 index 0000000000..397a134a79 --- /dev/null +++ b/java/management/client/src/main/java/wsdl/QManWsResource.rmd @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/java/management/client/src/main/java/wsdl/QManWsResource.wsdl b/java/management/client/src/main/java/wsdl/QManWsResource.wsdl new file mode 100644 index 0000000000..3603319281 --- /dev/null +++ b/java/management/client/src/main/java/wsdl/QManWsResource.wsdl @@ -0,0 +1,535 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/management/client/src/main/java/wsdl/SOAP-Envelope-1_2.xsd b/java/management/client/src/main/java/wsdl/SOAP-Envelope-1_2.xsd new file mode 100644 index 0000000000..5aba6591fe --- /dev/null +++ b/java/management/client/src/main/java/wsdl/SOAP-Envelope-1_2.xsd @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + Elements replacing the wildcard MUST be namespace qualified, but can be in the targetNamespace + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fault reporting structure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/client/src/main/java/wsdl/WS-Addressing-2005_08.xsd b/java/management/client/src/main/java/wsdl/WS-Addressing-2005_08.xsd new file mode 100644 index 0000000000..9bf9b10b7f --- /dev/null +++ b/java/management/client/src/main/java/wsdl/WS-Addressing-2005_08.xsd @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/client/src/main/java/wsdl/WS-BaseFaults-1_2.xsd b/java/management/client/src/main/java/wsdl/WS-BaseFaults-1_2.xsd new file mode 100644 index 0000000000..665797e486 --- /dev/null +++ b/java/management/client/src/main/java/wsdl/WS-BaseFaults-1_2.xsd @@ -0,0 +1,84 @@ + + + + + + + + + + Get access to the xml: attribute groups for xml:lang as declared on 'schema' + and 'documentation' below + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/client/src/main/java/wsdl/WS-MetadataExchange-2004_09.xsd b/java/management/client/src/main/java/wsdl/WS-MetadataExchange-2004_09.xsd new file mode 100644 index 0000000000..771a801f57 --- /dev/null +++ b/java/management/client/src/main/java/wsdl/WS-MetadataExchange-2004_09.xsd @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/client/src/main/java/wsdl/WS-Resource-1_2.xsd b/java/management/client/src/main/java/wsdl/WS-Resource-1_2.xsd new file mode 100644 index 0000000000..5d50284a33 --- /dev/null +++ b/java/management/client/src/main/java/wsdl/WS-Resource-1_2.xsd @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.xsd b/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.xsd new file mode 100644 index 0000000000..3338faf191 --- /dev/null +++ b/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.xsd @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/management/client/src/main/java/wsdl/WS-ResourceMetadataDescriptor-CD-01.xsd b/java/management/client/src/main/java/wsdl/WS-ResourceMetadataDescriptor-CD-01.xsd new file mode 100644 index 0000000000..2c5952264b --- /dev/null +++ b/java/management/client/src/main/java/wsdl/WS-ResourceMetadataDescriptor-CD-01.xsd @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To form a QName, the name of any MetadataDescriptor must be + unique within a Definitions element. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.xsd b/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.xsd new file mode 100644 index 0000000000..c408b36db1 --- /dev/null +++ b/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.xsd @@ -0,0 +1,394 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.xsd b/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.xsd new file mode 100644 index 0000000000..87238f90e5 --- /dev/null +++ b/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.xsd @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl b/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl new file mode 100644 index 0000000000..dc4581d8a8 --- /dev/null +++ b/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/client/src/main/java/wsdl/WsResource.rmd b/java/management/client/src/main/java/wsdl/WsResource.rmd new file mode 100644 index 0000000000..b15f7eca1c --- /dev/null +++ b/java/management/client/src/main/java/wsdl/WsResource.rmd @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/java/management/client/src/main/java/wsdl/WsResourceFactory.wsdl b/java/management/client/src/main/java/wsdl/WsResourceFactory.wsdl new file mode 100644 index 0000000000..83a7e5ad8c --- /dev/null +++ b/java/management/client/src/main/java/wsdl/WsResourceFactory.wsdl @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + diff --git a/java/management/client/src/main/java/wsdl/XML-Namespace-1998.xsd b/java/management/client/src/main/java/wsdl/XML-Namespace-1998.xsd new file mode 100644 index 0000000000..998a8001de --- /dev/null +++ b/java/management/client/src/main/java/wsdl/XML-Namespace-1998.xsd @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 5855a3e60b..56195b6f20 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 @@ -29,6 +29,9 @@ import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferO import org.apache.qpid.management.domain.model.DomainModel; import org.apache.qpid.management.domain.model.type.Binary; +/** + * Collects all literal constants used in test cases. + */ public interface TestConstants { UUID BROKER_ID = UUID.randomUUID(); diff --git a/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java b/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java index efd5990bd7..8e9c3ccd6b 100644 --- a/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java +++ b/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java @@ -36,8 +36,6 @@ import junit.framework.TestCase; /** * Test case for Configuration singleton. - * - * @author Andrea Gazzarini */ public class ConfigurationTest extends TestCase { @@ -74,11 +72,11 @@ public class ConfigurationTest extends TestCase { try { - Configuration.getInstance().getType(Integer.MIN_VALUE); + Configuration.getInstance().getType(TestConstants.VALID_CODE*10001); fail("If an unknwon code is supplied an exception must be thrown."); } catch (UnknownTypeCodeException expected) { - assertEquals(Integer.MIN_VALUE,expected.getCode()); + assertEquals(TestConstants.VALID_CODE*10001,expected.getCode()); } } @@ -107,11 +105,11 @@ public class ConfigurationTest extends TestCase { try { - Configuration.getInstance().getAccessMode(Integer.MIN_VALUE); + Configuration.getInstance().getAccessMode(TestConstants.VALID_CODE*1528); fail("If an unknwon code is supplied an exception must be thrown."); } catch (UnknownAccessCodeException expected) { - assertEquals(Integer.MIN_VALUE,expected.getCode()); + assertEquals(TestConstants.VALID_CODE*1528,expected.getCode()); } } @@ -178,29 +176,21 @@ public class ConfigurationTest extends TestCase *
postcondition : 2 management handlers are returned. */ public void testGetManagementQueueHandlersOk() - { - String i = "i"; - String c = "c"; - - String instrMessageHandlerClassName = InstrumentationMessageHandler.class.getName(); - String configMessageHandlerClassName = ConfigurationMessageHandler.class.getName(); - - MessageHandlerMapping instrMapping = new MessageHandlerMapping(); - MessageHandlerMapping configMapping = new MessageHandlerMapping(); - - instrMapping.setOpcode(i); - instrMapping.setMessageHandlerClass(instrMessageHandlerClassName); - - configMapping.setOpcode(c); - configMapping.setMessageHandlerClass(configMessageHandlerClassName); + { + IMessageHandler instrMessageHandler = new InstrumentationMessageHandler(); + IMessageHandler configMessageHandler = new ConfigurationMessageHandler(); + MessageHandlerMapping instrMapping = new MessageHandlerMapping('i',instrMessageHandler); + MessageHandlerMapping configMapping = new MessageHandlerMapping('c',configMessageHandler); + Configuration.getInstance().addManagementMessageHandlerMapping(instrMapping); Configuration.getInstance().addManagementMessageHandlerMapping(configMapping); Map handlerMappings = Configuration.getInstance().getManagementQueueHandlers(); - assertEquals(instrMessageHandlerClassName,handlerMappings.get(instrMapping.getOpcode()).getClass().getName()); - assertEquals(configMessageHandlerClassName,handlerMappings.get(configMapping.getOpcode()).getClass().getName()); + assertEquals(2,handlerMappings.size()); + assertEquals(instrMessageHandler,handlerMappings.get(instrMapping.getOpcode())); + assertEquals(configMessageHandler,handlerMappings.get(configMapping.getOpcode())); } /** @@ -211,19 +201,14 @@ public class ConfigurationTest extends TestCase */ public void testGetMethodReplyQueueHandlersOk() { - String s = "s"; - - String schemaMessageHandlerClassName = SchemaResponseMessageHandler.class.getName(); + IMessageHandler schemaMessageHandler = new SchemaResponseMessageHandler(); - MessageHandlerMapping schemaMapping = new MessageHandlerMapping(); + MessageHandlerMapping schemaMapping = new MessageHandlerMapping('s',schemaMessageHandler); - schemaMapping.setOpcode(s); - schemaMapping.setMessageHandlerClass(schemaMessageHandlerClassName); - Configuration.getInstance().addMethodReplyMessageHandlerMapping(schemaMapping); Map handlerMappings = Configuration.getInstance().getMethodReplyQueueHandlers(); - assertEquals(schemaMessageHandlerClassName,handlerMappings.get(schemaMapping.getOpcode()).getClass().getName()); + assertEquals(schemaMessageHandler,handlerMappings.get(schemaMapping.getOpcode())); } } diff --git a/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java b/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java index 6237f21cc9..1e464bf6ae 100644 --- a/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java +++ b/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java @@ -25,7 +25,6 @@ import java.util.UUID; import junit.framework.TestCase; -import org.apache.qpid.management.Names; import org.apache.qpid.management.Protocol; import org.apache.qpid.management.domain.handler.base.IMessageHandler; import org.apache.qpid.management.domain.handler.impl.ConfigurationMessageHandler; diff --git a/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java b/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java index 284f3841b8..9d6e176912 100644 --- a/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java +++ b/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java @@ -37,7 +37,7 @@ import org.apache.qpid.management.TestConstants; import org.apache.qpid.management.configuration.ConfigurationException; import org.apache.qpid.management.configuration.Configurator; import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject; -import org.apache.qpid.management.domain.model.QpidClass.QpidManagedObject; +import org.apache.qpid.management.domain.model.QpidClass.QManManagedObject; /** * Test case for Qpid Class. @@ -71,7 +71,7 @@ public class QpidClassTest extends TestCase "Nobody set instance #"+TestConstants.OBJECT_ID+" into this class so why is it there?", _class._objectInstances.containsKey(TestConstants.OBJECT_ID)); - QpidManagedObject instance = _class.getObjectInstance(TestConstants.OBJECT_ID, false); + QManManagedObject instance = _class.getObjectInstance(TestConstants.OBJECT_ID, false); assertTrue ( "Now the instance #"+TestConstants.OBJECT_ID+" should be there...", @@ -90,7 +90,7 @@ public class QpidClassTest extends TestCase public void testAddInstrumentationAndConfigurationDataBeforeSchemaInstallation() { _class._state = _class._schemaRequestedButNotYetInjected; - QpidManagedObject objectInstance = _class.getObjectInstance(TestConstants.OBJECT_ID,false); + QManManagedObject objectInstance = _class.getObjectInstance(TestConstants.OBJECT_ID,false); assertTrue( "This object instance is a new one so how is it possible that it has already instrumentation data? ", @@ -180,7 +180,7 @@ public class QpidClassTest extends TestCase } @Override - void updateInstanceWithConfigurationData(QpidManagedObject instance, byte[] rawData) + void updateInstanceWithConfigurationData(QManManagedObject instance, byte[] rawData) { // DO NOTHING Given raw data is not valid so it cannot be converted. } diff --git a/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java b/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java index 954a419787..4b36d9e5cc 100644 --- a/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java +++ b/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java @@ -36,7 +36,7 @@ import junit.framework.TestCase; import org.apache.qpid.management.TestConstants; import org.apache.qpid.management.configuration.ConfigurationException; import org.apache.qpid.management.configuration.Configurator; -import org.apache.qpid.management.domain.model.QpidEvent.QpidManagedEvent; +import org.apache.qpid.management.domain.model.QpidEvent.QManManagedEvent; /** * Test case for qpid class entity. @@ -68,7 +68,7 @@ public class QpidEventTest extends TestCase "A just created event should be empty. I mean there shouldn't be event instances inside.", _event.hasNoInstances()); - QpidManagedEvent instance = createEventInstance(); + QManManagedEvent instance = createEventInstance(); assertFalse ( "Now a new instance should be there...", @@ -136,7 +136,7 @@ public class QpidEventTest extends TestCase } @Override - void updateEventInstanceWithData(QpidManagedEvent instance) + void updateEventInstanceWithData(QManManagedEvent instance) { // DO NOTHING : otherwise we should supply a valid raw data to be converted. ;-) } @@ -269,7 +269,7 @@ public class QpidEventTest extends TestCase * * @return a new QpidManagedEvent with test data inside. */ - private QpidManagedEvent createEventInstance() + private QManManagedEvent createEventInstance() { return _event.createEventInstance( TestConstants.TEST_RAW_DATA, diff --git a/java/management/client/web.xml b/java/management/client/web.xml index 71ca74b2e5..30e982c383 100644 --- a/java/management/client/web.xml +++ b/java/management/client/web.xml @@ -1,32 +1,70 @@ - - - - - QManEE - Web Application used for integrating QMan onto an Application Server. - - QMan Servlet (Initializer) - QManServlet - org.apache.qpid.management.servlet.QManServlet - 1 - - + + + + + Q-Man is a Management bridge that exposes one (or several) Qpid + broker domain model as MBeans that are accessible through the + Java Management Extensions (JMX) and / or WS-DM. + + QManEE + + tapestry.app-package + org.apache.qpid.management.web.console + + + + Provides lifecycle management for QMan module. + + QMan Lifecycle manager + org.apache.qpid.management.servlet.QManLifeCycleManager + + + QMan Proxy Servlet + Proxy + org.apache.qpid.management.servlet.WSDMAdapter + 2 + + + + Connects QMAn to one or more brokers depending from what is + specified on the given (via system property) configuration + file. + + Connect QMan to Broker + ConnectQManToBroker + org.apache.qpid.management.servlet.ConnectQManToBroker + 1 + + + ConnectQManToBroker + /test/* + + + Proxy + /services/* + + + BASIC + + \ No newline at end of file -- cgit v1.2.1