diff options
Diffstat (limited to 'RC9/qpid/java/management')
276 files changed, 32727 insertions, 0 deletions
diff --git a/RC9/qpid/java/management/client/README.txt b/RC9/qpid/java/management/client/README.txt new file mode 100644 index 0000000000..0c2a702a46 --- /dev/null +++ b/RC9/qpid/java/management/client/README.txt @@ -0,0 +1,117 @@ +1)DESCRIPTION
+Q-Man is a Management bridge that exposes one (or several) Qpid broker domain model as MBeans that are accessible through the Java Management Extensions (JMX).
+The following README content could be read also in http://cwiki.apache.org/confluence/display/qpid/Qman+Tool
+
+2)HOW TO RUN Q-Man
+
+2.1)PREREQUISITES
+QMan is a standalone application that is packaged as qpid-management-client-<version>.jar. To run QMan you need to add the following jars in your CLASSPATH:
+
+log4j-1.2.12.jar
+slf4j-api-1.4.0.jar
+slf4j-log4j12-1.4.0.jar
+commons-pool-1.4.jar
+commons-codec-1.3.jar
+commons-lang-2.2.jar
+commons-collections-3.2.jar
+commons-configuration-1.2.jar
+qpid-client-<version>.jar (were <version> is the current qpid version)
+qpid-common-<version>.jar (were <version> is the current qpid version)
+
+alternatively you can run the following script (that add all the qpid jars to the CLASSPATH):
+
+> CLASSPATH=`find <lib-root> -name '*.jar' | tr '\n' ":"`
+
+Where <lib-root> is the directory containing the qpid jars (when qpid is built from source <lib-root> is equal to qpid/java/build/lib)
+
+You should have in your classpath a log4j.xml configuration file too with a category defined as this :
+
+<category name="org.apache.qpid.management">
+<priority value="INFO"/>
+</category>
+
+2.2) CONFIGURATION
+QMan can be connected at run time against any broker. However if you wish to automatically connect to one or several brokers you can do so by providing a configuration file as follows:
+
+<configuration>
+ <brokers>
+ <broker>
+ <host>localhost</host>
+ <port>5672</port>
+ <virtual-host>test</virtual-host>
+ <user>guest</user>
+ <password>guest</password>
+ <max-pool-capacity>4</max-pool-capacity>
+ <initial-pool-capacity>0</initial-pool-capacity>
+ <max-wait-timeout>-1</max-wait-timeout>
+ </broker>
+ <broker>
+ <host>myhost</host>
+ <port>5672</port>
+ <virtual-host>test</virtual-host>
+ <user>guest</user>
+ <password>guest</password>
+ <max-pool-capacity>4</max-pool-capacity>
+ <initial-pool-capacity>0</initial-pool-capacity>
+ <max-wait-timeout>-1</max-wait-timeout>
+ </broker>
+ </brokers>
+</configuration>
+The configuration above specifies that QMan should connect to two brokers, one on localhos and one on myhost, both listening on port 5672.
+
+The configuration file to use is specified through the JVM parameter "qman-config" that must point onto a valid configuration file.
+
+2.3)RUNNING Q-Man
+
+To run QMan in a console run the following command:
+
+> java -Dcom.sun.management.jmxremote org.apache.qpid.management.domain.services.QMan
+
+Messages similar to those should be displayed:
+
+... [org.apache.qpid.management.domain.services.QMan] <QMAN-000001> : Starting Q-Man...
+...
+Type "q" to quit.
+
+if you wish to use a configuration file <home>/myconfiguration.xml so QMan establishes a connection with one or several brokers, run the following command:
+
+java -Dqman-config="<home>/myconfiguration.xml" org.apache.qpid.management.domain.services.QMan
+
+
+2.4) STOPPING Q-Man
+Type "q" In the console from which QMan has been started.
+
+3) Browsing Manageable Beans using JConsole
+The jconsole tool (JMX-compliant graphical tool for monitoring a Java virtual machine) can be used for monitoring and QMan Mbeans. for more information see http://java.sun.com/javase/6/docs/technotes/guides/management/jconsole.html
+
+The jconsole executable can be found in JDK_HOME/bin, where JDK_HOME is the directory in which the JDK software is installed. If this directory is in your system path, you can start JConsole by simply typing jconsole in a console. Otherwise, you have to type the full path to the executable file.
+
+As jconsole needs to perform operations invocation you will need to add the QMan jar in jconsole classpath. In a console type:
+
+jconsole -J-Djava.class.path=$CLASSPATH:$JAVA_HOME/lib/jconsole.jar:$JAVA_HOME/lib/tools.jar
+Where CLASSPATH contains the QMan jars and JAVA_HOME point on your JDK home.
+
+NOte that in order to see QMan JVM on JConsole you need to add the following command line option to QMan launcher : -Dcom.sun.management.jmxremote
+
+4) Deploying Q-Man on JBoss
+QMan comes with a servlet that can be deployed in any application server. In the following we show how to deploy the qman servlet within JBoss application server.
+
+4.1) PREREQUISITES
+You mus install JBoss:
+
+- Download the latest stable version from: http://www.jboss.org/jbossas/downloads/
+- Unzip the download archive in <jboss-home>
+
+4.2) Deploying
+First you need to copy the provided qman.war in <jboss-home>/server/default/deploy/ (note that you can use another server configuration like for example minimal)
+
+Then run JBoss:
+
+Add the following option-Djboss.platform.mbeanserver to JAVA_OPTS (for example: export JAVA_OPTS=-Djboss.platform.mbeanserver)
+Execute <jboss-home>/binrun.sh (or run.bat on a windows platform)
+Notes:
+
+If you wish to configure QMan via a configuration file so QMan establishes a connection with one or several broker at starting time then add the options -Dqman-config=myconfigFile.xml to JAVA_OPTS.
+When Qpid is built form source, the war archive qman.war is located in qpid/java/build/management/client/servlet
+
+Enjoy!
diff --git a/RC9/qpid/java/management/client/bin/qman b/RC9/qpid/java/management/client/bin/qman new file mode 100755 index 0000000000..7352bb0388 --- /dev/null +++ b/RC9/qpid/java/management/client/bin/qman @@ -0,0 +1,31 @@ +#!/bin/sh + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +if [ "$QPID_LIB_PATH" = "" ] ; then + QPID_LIB_PATH=/usr/share/java +fi + +if [ "$QPID_CONFIG_PATH" = "" ] ; then + QPID_CONFIG_PATH=/etc +fi + +QMAN_CLASSPATH=`find $QPID_LIB_PATH | tr '\n' ":"` + +java -cp $QMAN_CLASSPATH -Dcom.sun.management.jmxremote -Dlog4j.configuration=qman.log4j -Dqman-config=$QPID_CONFIG_PATH/qman-config.xml org.apache.qpid.management.domain.services.QMan diff --git a/RC9/qpid/java/management/client/build.xml b/RC9/qpid/java/management/client/build.xml new file mode 100644 index 0000000000..bf32233214 --- /dev/null +++ b/RC9/qpid/java/management/client/build.xml @@ -0,0 +1,66 @@ +<!-- + - + - Licensed to the Apache Software Foundation (ASF) under one + - or more contributor license agreements. See the NOTICE file + - distributed with this work for additional information + - regarding copyright ownership. The ASF licenses this file + - to you under the Apache License, Version 2.0 (the + - "License"); you may not use this file except in compliance + - with the License. You may obtain a copy of the License at + - + - http://www.apache.org/licenses/LICENSE-2.0 + - + - Unless required by applicable law or agreed to in writing, + - software distributed under the License is distributed on an + - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + - KIND, either express or implied. See the License for the + - specific language governing permissions and limitations + - under the License. + - + --> +<project name="Qpid Management Client" default="build"> + + <property name="module.depends" value="client common"/> + + <import file="../../module.xml"/> + + + <property name="servlet.war" value="qman.war"/> + <property name="servlet.root" value="${module.build}/servlet"/> + <property name="servlet.web-inf" value="${servlet.root}/WEB-INF"/> + <property name="servlet.classes" value="${servlet.web-inf}/classes"/> + + + <target name="servlet-prepare"> + <mkdir dir="${servlet.root}"/> + <mkdir dir="${servlet.web-inf}"/> + <mkdir dir="${servlet.classes}"/> + <copy file="./web.xml" todir="${servlet.web-inf}" verbose="false"/> + <copy todir="${servlet.classes}" verbose="false"> + <fileset dir="${module.classes}"> + <include name="org/apache/qpid/management/servlet/*"/> + </fileset> + </copy> + <copy todir="${servlet.web-inf}"> + <fileset dir="${build}" includes="${module.libs}"/> + </copy> + <copy todir="${servlet.web-inf}/lib"> + <fileset dir="${build}/lib"> + <include name="qpid-client-*.jar"/> + <include name="qpid-common-*.jar"/> + <include name="qpid-management-client-*.jar"/> + </fileset> + </copy> + </target> + + <target name="servlet-clean"> + <delete dir="${servlet.root}"/> + </target> + + <target name="servlet"> + <jar destfile="${servlet.root}/${servlet.war}" basedir="${servlet.root}"/> + </target> + + <target name="postbuild" depends="servlet-clean,servlet-prepare,servlet" description="run after a build"/> + +</project> diff --git a/RC9/qpid/java/management/client/doc/man/qman b/RC9/qpid/java/management/client/doc/man/qman new file mode 100644 index 0000000000..cf4f90845c --- /dev/null +++ b/RC9/qpid/java/management/client/doc/man/qman @@ -0,0 +1,17 @@ +.TH qman +.SH NAME +qman is a Management bridge that exposes one (or several) Qpid broker domain model as MBeans that are accessible through the Java Management Extensions (JMX). Once you run qman you need to start a JMX Console such as JConsole to browse the MBeans exposed by Q-Man. +.SH SYNOPSIS +qman +.SH DESCRIPTION +For more information on customizing QMan for your own environment please read http://cwiki.apache.org/confluence/display/qpid/Qman+Tool +.SH Configuration +.SS Classpath +By default qman jars will be loaded from /usr/share/java. If you want to load from an alternative location you could specify it using QPID_LIB_PATH var. +.SS Config file +qman can be configured to connect to one or more brokers at startup by adding brokers in +.I /etc/qman-config.xml +If you want to load qman with qma-config.xml from a different location, you can specify it using QPID_CONFIG_PATH var. +.SS log4j configuration +qman expects qman.log4j file to be in the classpath. By default it will be put in +.I /usr/share/java diff --git a/RC9/qpid/java/management/client/etc/qman-config.xml b/RC9/qpid/java/management/client/etc/qman-config.xml new file mode 100644 index 0000000000..68ca3c6edf --- /dev/null +++ b/RC9/qpid/java/management/client/etc/qman-config.xml @@ -0,0 +1,47 @@ +<!-- + - + - Licensed to the Apache Software Foundation (ASF) under one + - or more contributor license agreements. See the NOTICE file + - distributed with this work for additional information + - regarding copyright ownership. The ASF licenses this file + - to you under the Apache License, Version 2.0 (the + - "License"); you may not use this file except in compliance + - with the License. You may obtain a copy of the License at + - + - http://www.apache.org/licenses/LICENSE-2.0 + - + - Unless required by applicable law or agreed to in writing, + - software distributed under the License is distributed on an + - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + - KIND, either express or implied. See the License for the + - specific language governing permissions and limitations + - under the License. + - + --> + +<configuration> + <brokers> + <broker> + <host>localhost</host> + <port>5672</port> + <virtual-host>test</virtual-host> + <user>guest</user> + <password>guest</password> + <max-pool-capacity>4</max-pool-capacity> + <initial-pool-capacity>0</initial-pool-capacity> + <max-wait-timeout>-1</max-wait-timeout> + </broker> +<!-- + <broker> + <host>myhost</host> + <port>5672</port> + <virtual-host>test</virtual-host> + <user>guest</user> + <password>guest</password> + <max-pool-capacity>4</max-pool-capacity> + <initial-pool-capacity>0</initial-pool-capacity> + <max-wait-timeout>-1</max-wait-timeout> + </broker> +--> + </brokers> +</configuration> diff --git a/RC9/qpid/java/management/client/etc/qman.log4j b/RC9/qpid/java/management/client/etc/qman.log4j new file mode 100644 index 0000000000..c2d0b050bb --- /dev/null +++ b/RC9/qpid/java/management/client/etc/qman.log4j @@ -0,0 +1,30 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +log4j.rootLogger=${root.logging.level} + +log4j.logger.org.apache.qpid=ERROR, console +log4j.additivity.org.apache.qpid=false + +log4j.logger.org.apache.qpid.management.client=DEBUG, console + +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.Threshold=error +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%t %d %p [%c{4}] %m%n + diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java new file mode 100644 index 0000000000..579b00c2db --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java @@ -0,0 +1,119 @@ +/*
+*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.management;
+
+/**
+ * Enumerative interfaces containing all QMan messages.
+ *
+ * @author Andrea Gazzarini
+ */
+public interface Messages
+{
+ // INFO
+ String QMAN_000001_STARTING_QMAN = "<QMAN-000001> : Starting Q-Man...";
+ String QMAN_000002_READING_CONFIGURATION = "<QMAN-000002> : Reading Q-Man configuration...";
+ String QMAN_000003_CREATING_MANAGEMENT_CLIENTS = "<QMAN-000003> : Creating management client(s)...";
+ String QMAN_000004_MANAGEMENT_CLIENT_CONNECTED = "<QMAN-000004> : Management client for broker %s successfully connected.";
+ String QMAN_000005_TYPE_MAPPING_CONFIGURED = "<QMAN-000005> : Type mapping : code = %s associated to %s (validator class is %s)";
+ String QMAN_000006_ACCESS_MODE_MAPPING_CONFIGURED = "<QMAN-000006> : Access Mode mapping : code = %s associated to %s";
+ String QMAN_000007_MANAGEMENT_HANDLER_MAPPING_CONFIGURED = "<QMAN-000007> : Management Queue Message Handler Mapping : opcode = %s associated with %s";
+ String QMAN_000008_METHOD_REPLY_HANDLER_MAPPING_CONFIGURED = "<QMAN-000008> : Method-Reply Queue Message Handler Mapping : opcode = %s associated with %s";
+ String QMAN_000009_BROKER_DATA_CONFIGURED = "<QMAN-000009> : Broker configuration %s: %s";
+ String QMAN_000010_INCOMING_SCHEMA = "<QMAN-000010> : Incoming schema for %s::%s.%s";
+ String QMAN_000011_SHUTDOWN_INITIATED = "<QMAN-000011> : The shutdown sequence has been initiated for management client connected with broker %s";
+ String QMAN_000012_MANAGEMENT_CLIENT_SHUT_DOWN = "<QMAN-000012> : Management client connected with broker %s shut down successfully.";
+ String QMAN_000013_METHOD_REPLY_CONSUMER_INSTALLED = "<QMAN-000013> : Method-reply queue consumer has been successfully installed and bound on broker %s.";
+ String QMAN_000014_MANAGEMENT_CONSUMER_INSTALLED ="<QMAN-000014> : Management queue consumer has been successfully installed and bound on broker %s.";
+ String QMAN_000015_MANAGEMENT_QUEUE_DECLARED = "<QMAN-000015> : Management queue with name %s has been successfully declared and bound on broker %s.";
+ String QMAN_000016_METHOD_REPLY_QUEUE_DECLARED = "<QMAN-000016> : Method-reply queue with name %s has been successfully declared and bound on broker %s.";
+ String QMAN_000017_CONSUMER_HAS_BEEN_REMOVED = "<QMAN-000017> : Consumer %s has been removed from broker %s.";
+ String QMAN_000018_QUEUE_UNDECLARED = "<QMAN-000018> : Queue %s has been removed from broker %s.";
+ String QMAN_000019_QMAN_STARTED = "<QMAN-000019> : Q-Man open for e-business.";
+ String QMAN_000020_SHUTTING_DOWN_QMAN = "<QMAN-000020> : Shutting down Q-Man...";
+ String QMAN_000021_SHUT_DOWN = "<QMAN-000021> : Q-Man shut down.";
+ String QMAN_000022_NO_BROKER_CONFIGURED = "<QMAN-000022> : Q-Man has no configured broker : in order to connect with a running one use Q-Man Administration interface.";
+ String QMAN_000023_QMAN_REGISTERED_AS_MBEAN = "<QMAN-000023> : Q-Man service is now available on MBeanServer.";
+
+ // DEBUG
+ String QMAN_200001_INCOMING_MESSAGE_HAS_BEEN_RECEIVED = "<QMAN-200001> : New incoming message has been received. Message content is %s";
+ String QMAN_200002_OPCODE_HANDLER_ASSOCIATION = "<QMAN-200002> : \"%s\" opcode is associated to handler %s";
+ String QMAN_200003_MESSAGE_FORWARDING = "<QMAN-200003> : Incoming message with \"%s\" as opcode will be forwarded to %s for processing.";
+ String QMAN_200004_MANAGEMENT_QUEUE_NAME = "<QMAN-200004> : Management queue name : %s";
+ String QMAN_200005_METHOD_REPLY_QUEUE_NAME = "<QMAN-200005> : Method-reply queue name : %s";
+ String QMAN_200006_QPID_CONNECTION_RELEASED = "<QMAN-200006> : Connection %s returned to the pool.";
+ String QMAN_200007_TEST_CONNECTION_ON_RESERVE = "<QMAN-200007> : Test connection on reserve. Is valid? %s";
+ String QMAN_200008_CONNECTION_DESTROYED = "<QMAN-200008> : Connection has been destroyed.";
+ String QMAN_200009_CONNECTION_DESTROY_FAILURE = "<QMAN-200009> : Unable to destroy a connection object.";
+ String QMAN_200010_EVENT_MBEAN_REGISTERED = "<QMAN-200010> : Event instance %s::%s::%s successfully registered with MBean Server with name %s";
+ String QMAN_200011_OBJECT_MBEAN_REGISTERED = "<QMAN-200011> : Object instance %s::%s::%s:%s successfully registered with MBean Server with name %s";
+ String QMAN_200012_OBJECT_MBEAN_UNREGISTERED = "<QMAN-200012> : Object instance %s::%s::%s:%s successfully unregistered from MBean Server. Name was %s";
+ String QMAN_200013_ARGUMENT_VALUE_ENCODED = "<QMAN-200013> : Encoded value %S for argument %s. Type is %s";
+ String QMAN_200014_INCOMING_INSTRUMENTATION_DATA = "<QMAN-200014> : Incoming instrumentation data for %s::%s.%s.%s";
+ String QMAN_200015_INCOMING_CONFIGURATION_DATA = "<QMAN-200015> : Incoming configuration data for %s::%s.%s.%s";
+ String QMAN_200016_PROPERTY_DEFINITION_HAS_BEEN_BUILT = "<QMAN-200016> : Property definition for %s::%s.%s has been built.";
+ String QMAN_200017_STATISTIC_DEFINITION_HAS_BEEN_BUILT = "<QMAN-200017> : Statistic definition for %s::%s.%s has been built.";
+ String QMAN_200018_OPTIONAL_PROPERTIES_INFO = "<QMAN-200018> : Class %s::%s.%s has %s optional properties.";
+ String QMAN_200019_EVENT_ARGUMENT_DEFINITION_HAS_BEEN_BUILT = "<QMAN-200019> : Event argument definition for %s::%s.%s has been built.";
+ String QMAN_200020_ENTITY_DEFINITION_HAS_BEEN_BUILT = "<QMAN-200020> : Entity definition has been built (without schema) for %s::%s.%s";
+ String QMAN_200021_INCOMING_EVENT_DATA = "<QMAN-200021> : Incoming data for event %s::%s.%s";
+ String QMAN_200022_VALIDATOR_INSTALLED = "<QMAN-200022> : Validator %s for type %s successfully installed.";
+ String QMAN_200023_VALIDATOR_NOT_FOUND = "<QMAN-200023> : No validator was found for type %s. The default (empty) validator will be used.";
+ String QMAN_200024_MANAGEMENT_MESSAGE_HAS_BEEN_SENT = "<QMAN-200024> : Message has been sent to management exchange. Message content : %s";
+ String QMAN_200025_SUBSCRIPTION_DECLARED = "<QMAN-200025> : New subscription between queue %s and destination %s has been declared.";
+ String QMAN_200026_SUBSCRIPTION_REMOVED = "<QMAN-200026> : Subscription named %s has been removed from remote broker.";
+ String QMAN_200027_QUEUE_DECLARED = "<QMAN-200027> : New queue with name %s has been declared.";
+ String QMAN_200028_QUEUE_REMOVED= "<QMAN-200028> : New queue with name %s has been undeclared.";
+ String QMAN_200029_BINDING_DECLARED = "<QMAN-200029> : New binding with %s as routing key has been declared between queue %s and exchange %s.";
+ String QMAN_200030_BINDING_REMOVED = "<QMAN-200030> : Binding with %s as routing key has been removed between queue %s and exchange %s.";
+ String QMAN_200031_COMPOUND_MESSAGE_CONTAINS = "<QMAN-200031> : Incoming compound message contains %s message(s).";
+ String QMAN_200032_COMMAND_MESSAGE_ROUTING_KEY = "<QMAN-200032> : Command message routing key : %s";
+
+ // WARNING
+ String QMAN_300001_MESSAGE_DISCARDED = "<QMAN-300001> : No handler has been configured for processing messages with \"%s\" as opcode. Message will be discarded.";
+ String QMAN_300002_UNKNOWN_SEQUENCE_NUMBER = "<QMAN-300002> : Unable to deal with incoming message because it contains a unknown sequence number (%s).";
+ String QMAN_300003_BROKER_ALREADY_CONNECTED = "<QMAN-300003> : Unable to enlist given broker connection data : QMan is already connected with broker %s";
+ String QMAN_300004_INVALID_CONFIGURATION_FILE = "<QMAN-300004> : The given configuration file (%s) is not valid (it doesn't exist or cannot be read)";
+
+ // ERROR
+ String QMAN_100001_BAD_MAGIC_NUMBER_FAILURE = "<QMAN-100001> : Message processing failure : incoming message contains a bad magic number (%s) and therefore will be discaded.";
+ String QMAN_100002_MESSAGE_READ_FAILURE = "<QMAN-100002> : Message I/O failure : unable to read byte message content and therefore it will be discarded.";
+ String QMAN_100003_MESSAGE_PROCESS_FAILURE = "<QMAN-100003> : Message processing failure : unknown exception; see logs for more details.";
+ String QMAN_100004_HANDLER_INITIALIZATION_FAILURE = "<QMAN-100004> : Message handler configured for opcode %s thrown an exception in initialization and therefore will be discarded.";
+ String QMAN_100005_CLASS_SCHEMA_PROCESSING_FAILURE = "<QMAN-100005> : Q-Man was unable to process the schema response message.";
+ String QMAN_100006_EVENT_SCHEMA_PROCESSING_FAILURE = "<QMAN-100006> : Q-Man was unable to process the schema response message.";
+ String QMAN_100007_UNABLE_TO_CONNECT_WITH_BROKER = "<QMAN-100007> : Unable to connect with broker located on %s. This broker will be ignored.";
+ String QMAN_100008_MANAGEMENT_MESSAGE_HANDLER_NOT_AVAILABLE = "<QMAN-100008> : Management Message Handler configured for opcode %s is not available and therefore will be discarded.";
+ String QMAN_100009_METHOD_REPLY_MESSAGE_HANDLER_NOT_AVAILABLE = "<QMAN-100009> :Method-Reply Message Handler configured for opcode %s is not available and therefore will be discarded.";
+ String QMAN_100010_METHOD_INVOCATION_RESULT_FAILURE = "<QMAN-100010> : an exception occurred while storing the result of a method invocation. Sequence number was %s";
+ String QMAN_100011_UNKNOWN_CLASS_KIND = "<QMAN-100011> : Unknwon class kind : %s).";
+ String QMAN_100012_SCHEMA_MESSAGE_PROCESSING_FAILURE = "<QMAN-100012> : Q-Man was unable to process the schema response message.";
+ String QMAN_100013_MBEAN_REGISTRATION_FAILURE = "<QMAN-100013> : Unable to unregister object instance %s.";
+ String QMAN_100014_ATTRIBUTE_DECODING_FAILURE = "<QMAN-100014> : Unable to decode value for attribute %s";
+ String QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST = "<QMAN-100015> : Unable to send a schema request schema for %s.%s";
+ String QMAN_100016_UNABLE_TO_DECODE_FEATURE_VALUE = "<QMAN-100016> : Unable to decode value for %s::%s::%s";
+ String QMAN_100017_UNABLE_TO_CONNECT = "<QMAN-100017>: Cannot connect to broker %s on %s";
+ String QMAN_100018_UNABLE_TO_STARTUP_CORRECTLY = "<QMAN-100018> : Q-Man was unable to startup correctly : see logs for further details.";
+
+ // MESSAGES
+ String EVENT_SEVERITY_ATTRIBUTE_DESCRIPTION = "Severity level for this event.";
+ String EVENT_TIMESTAMP_ATTRIBUTE_DESCRIPTION = "Current timestamp of this event.";
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java new file mode 100644 index 0000000000..7ed0f8b24d --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java @@ -0,0 +1,57 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management; + +/** + * Enumeration of literal strings to avoid code duplication. + * + * @author Andrea Gazzarini + */ +public interface Names +{ + /** Name of the qpid management exchange. */ + String MANAGEMENT_EXCHANGE = "qpid.management"; + String MANAGEMENT_ROUTING_KEY = "console.#"; + + String MANAGEMENT_QUEUE_PREFIX = "management."; + String METHOD_REPLY_QUEUE_PREFIX = "reply."; + + String AMQ_DIRECT_QUEUE = "amq.direct"; + String AGENT_ROUTING_KEY_PREFIX = "agent."; + String AGENT_ROUTING_KEY = AGENT_ROUTING_KEY_PREFIX+"1.0"; + + // Attributes + String PACKAGE = "package"; + String CLASS = "class"; + String OBJECT_ID="objectID"; + String BROKER_ID = "brokerID"; + String DOMAIN_NAME = "Q-MAN"; + + String ARG_COUNT_PARAM_NAME = "argCount"; + String DEFAULT_PARAM_NAME ="default"; + + String NUMBER_VALIDATOR = "org.apache.qpid.management.domain.model.QpidProperty$NumberValidator"; + String STRING_VALIDATOR = "org.apache.qpid.management.domain.model.QpidProperty$StringValidator"; + + String QMAN_CONFIG_OPTION_NAME = "qman-config"; + + String ADD_BROKER_OPERATION_NAME = "addBroker"; +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java new file mode 100644 index 0000000000..5b41785b11 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java @@ -0,0 +1,47 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management; + +/** + * Protocol defined constants. + * + * @author Andrea Gazzarini + */ +public interface Protocol +{ + String MAGIC_NUMBER = "AM2"; + + char SCHEMA_REQUEST_OPCODE = 'S'; + char SCHEMA_RESPONSE_OPCODE = Character.toLowerCase(SCHEMA_REQUEST_OPCODE); + + char OPERATION_INVOCATION_REQUEST_OPCODE = 'M'; + char OPERATION_INVOCATION_RESPONSE_OPCODE = Character.toLowerCase(OPERATION_INVOCATION_REQUEST_OPCODE); + + char INSTRUMENTATION_CONTENT_RESPONSE_OPCODE = 'i'; + char CONFIGURATION_CONTENT_RESPONSE_OPCDE = 'c'; + char EVENT_CONTENT_RESPONSE_OPCDE = 'e'; + char INSTR_AND_CONFIG_CONTENT_RESPONSE_OPCODE = 'g'; + + char HEARTBEAT_INDICATION_RESPONSE_OPCODE = 'h'; + + int CLASS = 1; + int EVENT = 2; +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/AccessModeMapping.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/AccessModeMapping.java new file mode 100644 index 0000000000..af6aaa36bf --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/AccessModeMapping.java @@ -0,0 +1,83 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +import org.apache.qpid.management.domain.model.AccessMode; + +/** + * Class used to encapsulate a mapping between an access mode and a code. + * + * @author Andrea Gazzarini + */ +class AccessModeMapping +{ + private final int _code; + private final AccessMode _accessMode; + + /** + * Builds a new access mode mapping with the given parameters. + * + * @param code the access code. + * @param accessMode the access mode. + */ + AccessModeMapping(int code, AccessMode accessMode) + { + this._code = code; + this._accessMode = accessMode; + } + + /** + * Returns the access mode of this mapping. + * + * @return the access mode of this mapping. + */ + AccessMode getAccessMode () + { + return _accessMode; + } + + /** + * Returns the code of this mapping. + * + * @return the code of this mapping. + */ + int getCode () + { + return _code; + } + + /** + * Returns a string representation of this mapping. + * The returned string is indicating the code and the corresponding access mode. + * + * @return a string representation of this mapping. + */ + @Override + public String toString () + { + return new StringBuilder() + .append("AccessMode mapping (") + .append(_code) + .append(',') + .append(_accessMode) + .append(')').toString(); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerAlreadyConnectedException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerAlreadyConnectedException.java new file mode 100644 index 0000000000..f23bf9d25e --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerAlreadyConnectedException.java @@ -0,0 +1,53 @@ +/*
+*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.management.configuration;
+
+/**
+ * Thrown when an attempt is made in order to connect QMan with an already connected broker.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BrokerAlreadyConnectedException extends Exception {
+
+ private static final long serialVersionUID = -5082431738056504669L;
+
+ private BrokerConnectionData _connectionData;
+
+ /**
+ * Builds a new exception with the given data.
+ *
+ * @param connectionData the broker connection data.
+ */
+ public BrokerAlreadyConnectedException(BrokerConnectionData connectionData) {
+ this._connectionData = connectionData;
+ }
+
+ /**
+ * Returns the connection data of the connected broker.
+ *
+ * @return the connection data of the connected broker.
+ */
+ public BrokerConnectionData getBrokerConnectionData()
+ {
+ return _connectionData;
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java new file mode 100644 index 0000000000..be04c67555 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java @@ -0,0 +1,270 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +/** + * Value object which is holding connection data for a specific broker. + * + * @author Andrea Gazzarini + */ +public class BrokerConnectionData +{ + private String _host; + private int _port; + private String _virtualHost; + private String _username; + private String _password; + private int _maxPoolCapacity; + private int _initialPoolCapacity; + private long _maxWaitTimeout; + + /** + * Builds a connection data with the given parameters. + * + * @param host the hostname where the broker is running. + * @param port the port where the broker is running. + * @param username the username for connecting with the broker. + * @param password the password for connecting with the broker. + * @param virtualHost the virtual host. + * @param initialPoolCapacity the number of the connection that must be immediately opened. + * @param maxPoolCapacity the maximum number of opened connection. + * @param maxWaitTimeout the maximum amount of time that a client will wait for obtaining a connection. + */ + public BrokerConnectionData( + String host, + int port, + String virtualHost, + String username, + String password, + int initialPoolCapacity, + int maxPoolCapacity, + long waitTimeout) { + + this._host = host; + this._port = port; + this._virtualHost = virtualHost; + this._username = username; + this._password = password; + _maxPoolCapacity = maxPoolCapacity; + _initialPoolCapacity = initialPoolCapacity; + _maxWaitTimeout = waitTimeout; + } + + /** + * Builds a new empty broker connection data object. + */ + BrokerConnectionData() + { + } + + /** + * Sets the value of host property for this connection data. + * + * @param host the host name. + */ + void setHost (String host) + { + this._host = host; + } + + /** + * Sets the value of port property for this connection data. + * + * @param port the port. + */ + void setPort (String port) + { + this._port = Integer.parseInt(port); + } + + /** + * Sets the value of virtual host property for this connection data. + * + * @param virtualHost the virtual host. + */ + void setVirtualHost (String virtualHost) + { + this._virtualHost = virtualHost; + } + + /** + * Sets the value of username property for this connection data. + * + * @param username the username. + */ + void setUsername(String username) + { + this._username = username; + } + + /** + * Sets the value of password property for this connection data. + * + * @param password the password. + */ + void setPassword(String password) + { + this._password = password; + } + + /** + * Returns the value of the host property. + * + * @return the value of the host property. + */ + public String getHost () + { + return _host; + } + + /** + * Returns the value of the port property. + * + * @return the value of the port property. + */ + public int getPort () + { + return _port; + } + + /** + * Returns the value of the virtual host property. + * + * @return the value of the virtual host property. + */ + public String getVirtualHost () + { + return _virtualHost; + } + + /** + * Returns the value of the username property. + * + * @return the value of the username property. + */ + public String getUsername () + { + return _username; + } + + /** + * Returns the value of the password property. + * + * @return the value of the password property. + */ + public String getPassword () + { + return _password; + } + + // sofia:5663@pippo/sung1 + @Override + public String toString () + { + return new StringBuilder() + .append(_host) + .append(':') + .append(_port) + .append('@') + .append(_virtualHost) + .toString(); + } + + /** + * Sets the max number of allowed connections that can be opened. + * + * @param value the max number of allowed connections that can be opened. + * @throws NumberFormatException if the given value is not a valid integer. + */ + public void setMaxPoolCapacity (String value) + { + _maxPoolCapacity = Integer.parseInt(value); + } + + /** + * Sets the max wait timeout for retrieving an available connections from the pool. + * + * @param value the max wait timeout for retrieving an available connections from the pool.. + * @throws NumberFormatException if the given value is not a valid long. + */ + public void setMaxWaitTimeout (String value) + { + this._maxWaitTimeout = Long.parseLong(value); + } + + /** + * Returns the max number of allowed connections that can be opened. + * + * @return the max number of allowed connections that can be opened. + */ + public int getMaxPoolCapacity () + { + return _maxPoolCapacity; + } + + /** + * Returns the max wait timeout for retrieving an available connections from the pool. + * + * @return the max wait timeout for retrieving an available connections from the pool. + */ + public long getMaxWaitTimeout () + { + return _maxWaitTimeout; + } + + /** + * Sets the initial connection pool capacity. + * + * @param capacity the initial connection pool capacity. + */ + public void setInitialPoolCapacity (String capacity) + { + _initialPoolCapacity = Integer.parseInt(capacity); + } + + /** + * Returns the initial connection pool capacity. + * + * @return the initial connection pool capacity. + */ + public int getInitialPoolCapacity () + { + return _initialPoolCapacity; + } + + @Override + public boolean equals(Object object) { + try + { + BrokerConnectionData connectionData = (BrokerConnectionData) object; + return (_host.equals(connectionData._host) ) + && (_port == connectionData._port) + && (_virtualHost.equals(connectionData._virtualHost)); + } catch (Exception exception) { + return false; + } + } + + @Override + public int hashCode() { + return _host.hashCode()+_port+_virtualHost.hashCode(); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.java new file mode 100644 index 0000000000..368970af00 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.java @@ -0,0 +1,137 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +import java.util.UUID; + +import org.apache.qpid.management.Messages; +import org.apache.qpid.transport.util.Logger; + +/** + * Parser used for building access mode mappings. + * For each access-mode-mappings/mapping element found in the configuration file, a new access mode mapping + * is built and injected into the bridge configuration. + * + <broker> + <host>192.168.148.131</host> + <port>5672</port> + <virtual-host>test</virtual-host> + <user>guest</user> + <password>guest</password> + <max-pool-capacity>4</max-pool-capacity> + <initial-pool-capacity>4</initial-pool-capacity> + <max-wait-timeout>-1</max-wait-timeout> + </broker> + * + * @author Andrea Gazzarini + */ +class BrokerConnectionDataParser implements IParser +{ + private final static Logger LOGGER = Logger.get(Configuration.class); + private BrokerConnectionData _connectionData = new BrokerConnectionData(); + private String _currentValue; + + /** + * Callback : the given value is the text content of the current node. + */ + public void setCurrrentAttributeValue (String value) + { + this._currentValue = value; + } + + /** + * Callback: each time the end of an element is reached this method is called. + * It's here that the built mapping is injected into the configuration. + * <broker> + <host>192.168.61.130</host> + <port>5673</port> + <virtual-host>test</virtual-host> + <user>andrea</user> + <password>andrea</password> + </broker> + */ + public void setCurrentAttributeName (String name) + { + switch (Tag.get(name)) + { + case HOST: + { + _connectionData.setHost(_currentValue); + break; + } + case PORT : + { + _connectionData.setPort(_currentValue); + break; + } + case VIRTUAL_HOST: + { + _connectionData.setVirtualHost(_currentValue); + break; + } + case USER : + { + _connectionData.setUsername(_currentValue); + break; + } + case MAX_POOL_CAPACITY: + { + _connectionData.setMaxPoolCapacity (_currentValue); + break; + } + case INITIAL_POOL_CAPACITY: + { + _connectionData.setInitialPoolCapacity(_currentValue); + break; + } + case MAX_WAIT_TIMEOUT: + { + _connectionData.setMaxWaitTimeout(_currentValue); + break; + } + case PASSWORD: + { + _connectionData.setPassword(_currentValue); + break; + } + case BROKER: + { + try + { + Configuration.getInstance().addBrokerConnectionData(getUUId(),_connectionData); + } catch(Exception exception) + { + LOGGER.error(exception, Messages.QMAN_100007_UNABLE_TO_CONNECT_WITH_BROKER, _connectionData); + } + _connectionData = new BrokerConnectionData(); + break; + } + } + } + + /** + * Gets an uuid in order to associate current connection data with a broker. + * @return + */ + UUID getUUId(){ + return UUID.randomUUID(); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionException.java new file mode 100644 index 0000000000..9294cf740e --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionException.java @@ -0,0 +1,42 @@ +/*
+*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.management.configuration;
+
+/**
+ * Thrown when a connection to a broker cannot be estabilished.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BrokerConnectionException extends Exception
+{
+ private static final long serialVersionUID = 8170112238862494025L;
+
+ /**
+ * Builds a new exception with the given cause.
+ *
+ * @param cause the exception cause.
+ */
+ BrokerConnectionException(Throwable cause)
+ {
+ super(cause);
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java new file mode 100644 index 0000000000..12b3c6be9e --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java @@ -0,0 +1,383 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.Map.Entry; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.SynchronousQueue; + +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; +import org.apache.qpid.management.domain.handler.base.IMessageHandler; +import org.apache.qpid.management.domain.handler.impl.InvocationResult; +import org.apache.qpid.management.domain.model.AccessMode; +import org.apache.qpid.management.domain.model.type.Type; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.ReplyTo; +import org.apache.qpid.transport.util.Logger; + +/** + * Qpid Management bridge configuration. + * Basically iy is a singleton that is holding all the configurtion data loaded at startup. + * + * @author Andrea Gazzarini + */ +public final class Configuration +{ + private final static Logger LOGGER = Logger.get(Configuration.class); + private static Configuration INSTANCE = new Configuration(); + + Map<Integer, Type> _typeMappings = new HashMap<Integer,Type>(); + Map<Integer,AccessMode> _accessModes = new HashMap<Integer, AccessMode>(); + Map<Type,String> _validators = new HashMap<Type, String>(); + + Map<UUID,BrokerConnectionData> _brokerConnectionInfos = new HashMap<UUID, BrokerConnectionData>(); + + Map<Character, String> _managementQueueHandlers = new HashMap<Character, String>(); + Map<Character, String> _methodReplyQueueHandlers = new HashMap<Character, String>(); + + private String _managementQueueName; + private String _methodReplyQueueName; + + private Header _headerForCommandMessages; + private DeliveryProperties _deliveryProperties = new DeliveryProperties(); + private MessageProperties _messageProperties = new MessageProperties(); + public BlockingQueue<InvocationResult> _resultExchangeChannel = new SynchronousQueue<InvocationResult>(); + + // Private constructor. + private Configuration() + { + defineQueueNames(); + createHeaderForCommandMessages(); + } + + /** + * Returns the singleton instance. + * + * @return the singleton instance. + */ + public static Configuration getInstance () + { + return INSTANCE; + } + + /** + * Returns true if this configuration has at least one broker connection data. + * + * @return true if this configuration has at least one broker connection data. + */ + public boolean hasOneOrMoreBrokersDefined() + { + return !_brokerConnectionInfos.isEmpty(); + } + + /** + * Returns the type associated to the given code. + * + * @param code the code used as search criteria. + * @return the type associated to the given code. + * @throws UnknownTypeCodeException when the given code is not associated to any type. + */ + public Type getType(int code) throws UnknownTypeCodeException + { + Type result = _typeMappings.get(code); + if (result == null) + { + throw new UnknownTypeCodeException(code); + } + return result; + } + + /** + * Returns the access mode associated to the given code. + * + * @param code the code used as search criteria. + * @return the access mode associated to the given code. + * @throws UnknownAccessCodeException when the given code is not associated to any access mode. + */ + public AccessMode getAccessMode(int code) throws UnknownAccessCodeException + { + AccessMode result = _accessModes.get(code); + if (result == null) + { + throw new UnknownAccessCodeException(code); + } + return result; + } + + /** + * Returns the validator class name associated to the given type. + * + * @param type the type. + * @return the validator class name associated to the given type. + */ + public String getValidatorClassName (Type type) + { + return _validators.get(type); + } + + /** + * Gets from this configuration the list of known broker (I mean, only their connection data). + * + * @return the list of known broker + */ + public Set<Entry<UUID, BrokerConnectionData>> getConnectionInfos(){ + return _brokerConnectionInfos.entrySet(); + } + + /** + * Gets from this configuration the connection data of the broker associated with the given id. + * + * @param brokerId the broker identifier. + * @return the connection data of the broker associated with the given id. + * @throws UnknownBrokerException when the given id is not associated with any broker. + */ + public BrokerConnectionData getBrokerConnectionData (UUID brokerId) throws UnknownBrokerException + { + BrokerConnectionData connectionData = _brokerConnectionInfos.get(brokerId); + if (connectionData == null) + { + throw new UnknownBrokerException(brokerId); + } + return _brokerConnectionInfos.get(brokerId); + } + + /** + * Returns the name of the management queue. + * + * @return the name of the management queue. + */ + public String getManagementQueueName() { + return _managementQueueName; + } + + /** + * Returns the name of the method-reply queue. + * + * @return the name of the method-reply queue. + */ + public String getMethodReplyQueueName() { + return _methodReplyQueueName; + } + + /** + * Returns a map containing all the configured management message handlers. + * A management message handler it is a basically a processor for a management queue incoming message associated + * with a specific opcode. + * + * @return a map containing all the configured management message handlers. + */ + public Map<Character, IMessageHandler> getManagementQueueHandlers() + { + Map<Character, IMessageHandler> result = new HashMap<Character, IMessageHandler>(); + + for (Entry<Character, String> entry : _managementQueueHandlers.entrySet()) + { + Character opcode = entry.getKey(); + String className = entry.getValue(); + try + { + result.put(opcode, (IMessageHandler)Class.forName(className).newInstance()); + } catch(Exception exception) + { + LOGGER.error(exception,Messages.QMAN_100008_MANAGEMENT_MESSAGE_HANDLER_NOT_AVAILABLE,opcode); + } + } + return result; + } + + /** + * Returns a map containing all the configured method-reply message handlers. + * A management message handler it is a basically a processor for a method-reply queue incoming message associated + * with a specific opcode. + * + * @return a map containing all the configured method-reply message handlers. + */ + public Map<Character, IMessageHandler> getMethodReplyQueueHandlers() + { + Map<Character, IMessageHandler> result = new HashMap<Character, IMessageHandler>(); + + for (Entry<Character, String> entry : _methodReplyQueueHandlers.entrySet()) + { + Character opcode = entry.getKey(); + String className = entry.getValue(); + try + { + result.put(opcode, (IMessageHandler)Class.forName(className).newInstance()); + } catch(Exception exception) + { + LOGGER.error(exception,Messages.QMAN_100009_METHOD_REPLY_MESSAGE_HANDLER_NOT_AVAILABLE,opcode); + } + } + return result; + } + + /** + * Returns the message header used for sending command message on management queue. + * + * @return the message header used for sending command message on management queue. + */ + public Header getCommandMessageHeader () + { + return _headerForCommandMessages; + } + + /** + * Returns the command message properties. + * + * @return the command message properties. + */ + public MessageProperties getCommandMessageProperties () + { + return _messageProperties; + } + + /** + * Returns the command message delivery properties. + * + * @return the command message delivery properties. + */ + public DeliveryProperties getCommandDeliveryProperties () + { + return _deliveryProperties; + } + + /** + * Adds a new type mapping to this configuration. + * + * @param mapping the type mapping that will be added. + */ + void addTypeMapping(TypeMapping mapping) { + int code = mapping.getCode(); + Type type = mapping.getType(); + String validatorClassName = mapping.getValidatorClassName(); + _typeMappings.put(code, type); + _validators.put(type, validatorClassName); + + LOGGER.info(Messages.QMAN_000005_TYPE_MAPPING_CONFIGURED, code,type,validatorClassName); + } + + /** + * Adds a new access mode mapping to this configuration. + * + * @param mapping the mapping that will be added. + */ + void addAccessModeMapping(AccessModeMapping mapping){ + int code = mapping.getCode(); + AccessMode accessMode = mapping.getAccessMode(); + _accessModes.put(code, accessMode); + + LOGGER.info(Messages.QMAN_000006_ACCESS_MODE_MAPPING_CONFIGURED, code,accessMode); + } + + /** + * Adds a new management message handler to this configuration. + * The incoming mapping object will contains an opcode and the class (as a string) of the message handler that will be used + * for processing incoming messages with that opcode. + * + * @param mapping the message handler mapping. + */ + void addManagementMessageHandlerMapping (MessageHandlerMapping mapping) + { + Character opcode = mapping.getOpcode(); + String handlerClass = mapping.getMessageHandlerClass(); + _managementQueueHandlers.put(opcode, handlerClass); + + LOGGER.info(Messages.QMAN_000007_MANAGEMENT_HANDLER_MAPPING_CONFIGURED, opcode,handlerClass); + } + + /** + * Adds a new method-reply message handler to this configuration. + * The incoming mapping object will contains an opcode and the class (as a string) of the message handler that will be used + * for processing incoming messages with that opcode. + * + * @param mapping the message handler mapping. + */ + void addMethodReplyMessageHandlerMapping (MessageHandlerMapping mapping) + { + Character opcode = mapping.getOpcode(); + String handlerClass = mapping.getMessageHandlerClass(); + _methodReplyQueueHandlers.put(opcode, handlerClass); + + LOGGER.info(Messages.QMAN_000008_METHOD_REPLY_HANDLER_MAPPING_CONFIGURED, opcode,handlerClass); + } + + /** + * Adds to this configuration a new broker connection data. + * + * @param brokerId the broker identifier. + * @param connectionData the connection data. + * @throws BrokerAlreadyConnectedException when the broker is already connected. + * @throws BrokerConnectionException when a connection cannot be estabilished. + */ + void addBrokerConnectionData (UUID brokerId, BrokerConnectionData connectionData) throws BrokerAlreadyConnectedException, BrokerConnectionException + { + if (_brokerConnectionInfos.containsValue(connectionData)) + { + throw new BrokerAlreadyConnectedException(connectionData); + } + + try + { + QpidDatasource.getInstance().addConnectionPool(brokerId, connectionData); + _brokerConnectionInfos.put(brokerId,connectionData); + + LOGGER.info(Messages.QMAN_000009_BROKER_DATA_CONFIGURED,brokerId,connectionData); + } catch(Exception exception) + { + throw new BrokerConnectionException(exception); + } + + } + + /** + * Header for command messages is created once because it only contains static values. + */ + private void createHeaderForCommandMessages () + { + ReplyTo replyTo=new ReplyTo(); + replyTo.setRoutingKey(_methodReplyQueueName); + _messageProperties.setReplyTo(replyTo); + _deliveryProperties.setRoutingKey(Names.AGENT_ROUTING_KEY); + _headerForCommandMessages = new Header(_deliveryProperties, _messageProperties); + } + + /** + * Creates the name of the queues used by this service. + * This is done because if a broker should be managed by one or more management client, then each of them + * must have its own channels to communicate with. + */ + private void defineQueueNames() + { + UUID uuid = UUID.randomUUID(); + _managementQueueName = Names.MANAGEMENT_QUEUE_PREFIX+uuid; + _methodReplyQueueName = Names.METHOD_REPLY_QUEUE_PREFIX+uuid; + + LOGGER.debug(Messages.QMAN_200004_MANAGEMENT_QUEUE_NAME,_managementQueueName); + LOGGER.debug(Messages.QMAN_200005_METHOD_REPLY_QUEUE_NAME,_methodReplyQueueName); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/ConfigurationException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/ConfigurationException.java new file mode 100644 index 0000000000..6eed515e11 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/ConfigurationException.java @@ -0,0 +1,51 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +/** + * Thrown when a problem is encountered during building the configuration. + * + * @author Andrea Gazzarini + */ +public class ConfigurationException extends Exception +{ + private static final long serialVersionUID = 8238481177714286259L; + + public ConfigurationException(String msg) + { + super(msg); + } + + /** + * Builds a new ConfigurationException with the given cause. + * + * @param exception the exception cause. + */ + public ConfigurationException(Exception exception) + { + super(exception); + } + + public ConfigurationException(String msg,Exception exception) + { + super(msg,exception); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java new file mode 100644 index 0000000000..0051b19c99 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java @@ -0,0 +1,287 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.util.UUID; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; +import org.apache.qpid.management.Protocol; +import org.apache.qpid.management.domain.handler.impl.ConfigurationMessageHandler; +import org.apache.qpid.management.domain.handler.impl.EventContentMessageHandler; +import org.apache.qpid.management.domain.handler.impl.HeartBeatIndicationMessageHandler; +import org.apache.qpid.management.domain.handler.impl.InstrumentationMessageHandler; +import org.apache.qpid.management.domain.handler.impl.MethodResponseMessageHandler; +import org.apache.qpid.management.domain.handler.impl.SchemaResponseMessageHandler; +import org.apache.qpid.management.domain.model.AccessMode; +import org.apache.qpid.management.domain.model.type.AbsTime; +import org.apache.qpid.management.domain.model.type.DeltaTime; +import org.apache.qpid.management.domain.model.type.Int16; +import org.apache.qpid.management.domain.model.type.Int32; +import org.apache.qpid.management.domain.model.type.Int64; +import org.apache.qpid.management.domain.model.type.Int8; +import org.apache.qpid.management.domain.model.type.ObjectReference; +import org.apache.qpid.management.domain.model.type.Str16; +import org.apache.qpid.management.domain.model.type.Str8; +import org.apache.qpid.management.domain.model.type.Uint16; +import org.apache.qpid.management.domain.model.type.Uint32; +import org.apache.qpid.management.domain.model.type.Uint64; +import org.apache.qpid.management.domain.model.type.Uint8; +import org.apache.qpid.transport.util.Logger; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * Director used for coordinating the build process of configuration. + * This is the only component which has a read-write permission on Configuration object. + * + * @author Andrea Gazzarini + */ +public class Configurator extends DefaultHandler +{ + private final static Logger LOGGER = Logger.get(Configurator.class); + + /** + * Default (empty) parser used when there's no need to process data (non relevant elements). + */ + final static IParser DEFAULT_PARSER = new IParser() { + + public void setCurrrentAttributeValue (String value) + { + } + + public void setCurrentAttributeName (String name) + { + } + }; + + IParser _brokerConfigurationParser = new BrokerConnectionDataParser(); + IParser _currentParser = DEFAULT_PARSER; + + /** + * Delegates the processing to the current parser. + */ + @Override + public void characters (char[] ch, int start, int length) throws SAXException + { + String value = new String(ch,start,length).trim(); + if (value.length() != 0) { + _currentParser.setCurrrentAttributeValue(value); + } + } + + /** + * Here is defined what parser needs to be used for processing the current data. + */ + @Override + public void startElement (String uri, String localName, String name, Attributes attributes) throws SAXException + { + switch(Tag.get(name)) { + case BROKERS: + { + _currentParser = _brokerConfigurationParser; + break; + } + } + } + + @Override + public void endElement (String uri, String localName, String name) throws SAXException + { + _currentParser.setCurrentAttributeName(name); + } + + /** + * Builds whole configuration. + * + * @throws ConfigurationException when the build fails. + */ + public void configure() throws ConfigurationException + { + BufferedReader reader = null; + try + { + String initialConfigFileName = System.getProperty(Names.QMAN_CONFIG_OPTION_NAME); + if (initialConfigFileName != null && initialConfigFileName.trim().length() != 0) + { + File initialConfigurationFile = new File(initialConfigFileName); + if (initialConfigurationFile.canRead()) + { + SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); + reader = new BufferedReader(new InputStreamReader(new FileInputStream(initialConfigFileName))); + InputSource source = new InputSource(reader); + parser.parse(source, this); + } else { + LOGGER.warn(Messages.QMAN_300004_INVALID_CONFIGURATION_FILE, initialConfigFileName); + throw new ConfigurationException(String.format(Messages.QMAN_300004_INVALID_CONFIGURATION_FILE, initialConfigFileName)); + } + } + + addTypeMappings(); + addAccessModeMappings(); + + addMandatoryManagementMessageHandlers(); + addMandatoryMethodReplyMessageHandlers(); + } catch (Exception exception) + { + throw new ConfigurationException(exception); + } finally + { + try + { + reader.close(); + } catch (Exception ignore) + { + } + } + } + + /** + * Creates and return a value object (BrokerConnectionData) with the given parameters. + * Note that that object will be stored on configuration and it could be used to set a connection with the broker. + * This happens when the "initialPoolCapacity" is greater than 0 : in this case the caller is indicatinf that it wants to open + * one or more connections immediately at startup and therefore Q-Man will try to do that. + * + * @param host the hostname where the broker is running. + * @param port the port where the broker is running. + * @param username the username for connecting with the broker. + * @param password the password for connecting with the broker. + * @param virtualHost the virtual host. + * @param initialPoolCapacity the number of the connection that must be immediately opened. + * @param maxPoolCapacity the maximum number of opened connection. + * @param maxWaitTimeout the maximum amount of time that a client will wait for obtaining a connection. + * @return the value object containing the data above. + * @throws BrokerAlreadyConnectedException when the broker is already connected. + * @throws BrokerConnectionException when a connection cannot be estabilished. + */ + public BrokerConnectionData createAndReturnBrokerConnectionData( + UUID brokerId, + String host, + int port, + String username, + String password, + String virtualHost, + int initialPoolCapacity, + int maxPoolCapacity, + long maxWaitTimeout) throws BrokerAlreadyConnectedException, BrokerConnectionException + { + BrokerConnectionData data = new BrokerConnectionData( + host, + port, + virtualHost, + username, + password, + initialPoolCapacity, + maxPoolCapacity, + maxWaitTimeout); + Configuration.getInstance().addBrokerConnectionData(brokerId, data); + return data; + } + + /** + * Configures access mode mappings. + * An access mode mapping is an association between a code and an access mode. + */ + private void addAccessModeMappings() { + Configuration configuration = Configuration.getInstance(); + configuration.addAccessModeMapping(new AccessModeMapping(1,AccessMode.RC)); + configuration.addAccessModeMapping(new AccessModeMapping(2,AccessMode.RW)); + configuration.addAccessModeMapping(new AccessModeMapping(3,AccessMode.RO)); + } + + /** + * Configures type mappings. + * A type mapping is an association between a code and a management type. + */ + private void addTypeMappings() + { + Configuration configuration = Configuration.getInstance(); + configuration.addTypeMapping(new TypeMapping(1,new Uint8(),Names.NUMBER_VALIDATOR)); + configuration.addTypeMapping(new TypeMapping(2,new Uint16(),Names.NUMBER_VALIDATOR)); + configuration.addTypeMapping(new TypeMapping(3,new Uint32(),Names.NUMBER_VALIDATOR)); + configuration.addTypeMapping(new TypeMapping(4,new Uint64(),Names.NUMBER_VALIDATOR)); + configuration.addTypeMapping(new TypeMapping(6,new Str8(),Names.STRING_VALIDATOR)); + configuration.addTypeMapping(new TypeMapping(7,new Str16(),Names.STRING_VALIDATOR)); + configuration.addTypeMapping(new TypeMapping(8,new AbsTime())); + configuration.addTypeMapping(new TypeMapping(9,new DeltaTime())); + configuration.addTypeMapping(new TypeMapping(10,new ObjectReference())); + configuration.addTypeMapping(new TypeMapping(11,new org.apache.qpid.management.domain.model.type.Boolean())); + configuration.addTypeMapping(new TypeMapping(12,new org.apache.qpid.management.domain.model.type.Float(),Names.NUMBER_VALIDATOR)); + configuration.addTypeMapping(new TypeMapping(13,new org.apache.qpid.management.domain.model.type.Double(),Names.NUMBER_VALIDATOR)); + configuration.addTypeMapping(new TypeMapping(14,new org.apache.qpid.management.domain.model.type.Uuid())); + configuration.addTypeMapping(new TypeMapping(15,new org.apache.qpid.management.domain.model.type.Map())); + configuration.addTypeMapping(new TypeMapping(16,new Int8(),Names.NUMBER_VALIDATOR)); + configuration.addTypeMapping(new TypeMapping(17,new Int16(),Names.NUMBER_VALIDATOR)); + configuration.addTypeMapping(new TypeMapping(18,new Int32(),Names.NUMBER_VALIDATOR)); + configuration.addTypeMapping(new TypeMapping(19,new Int64(),Names.NUMBER_VALIDATOR)); + } + + /** + * Configures the mandatory management message handlers. + */ + private void addMandatoryMethodReplyMessageHandlers () + { + Configuration.getInstance().addMethodReplyMessageHandlerMapping( + new MessageHandlerMapping( + Protocol.OPERATION_INVOCATION_RESPONSE_OPCODE, + MethodResponseMessageHandler.class.getName())); + + Configuration.getInstance().addMethodReplyMessageHandlerMapping( + new MessageHandlerMapping( + Protocol.SCHEMA_RESPONSE_OPCODE, + SchemaResponseMessageHandler.class.getName())); + } + + /** + * Configures the mandatory management message handlers. + */ + private void addMandatoryManagementMessageHandlers () + { + Configuration.getInstance().addManagementMessageHandlerMapping( + new MessageHandlerMapping( + Protocol.INSTRUMENTATION_CONTENT_RESPONSE_OPCODE, + InstrumentationMessageHandler.class.getName())); + + Configuration.getInstance().addManagementMessageHandlerMapping( + new MessageHandlerMapping( + Protocol.CONFIGURATION_CONTENT_RESPONSE_OPCDE, + ConfigurationMessageHandler.class.getName())); + + Configuration.getInstance().addManagementMessageHandlerMapping( + new MessageHandlerMapping( + Protocol.EVENT_CONTENT_RESPONSE_OPCDE, + EventContentMessageHandler.class.getName())); + + Configuration.getInstance().addManagementMessageHandlerMapping( + new MessageHandlerMapping( + Protocol.HEARTBEAT_INDICATION_RESPONSE_OPCODE, + HeartBeatIndicationMessageHandler.class.getName())); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/IParser.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/IParser.java new file mode 100644 index 0000000000..a221686765 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/IParser.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +/** + * Interface definition for configuration parser + * Concrete implementors are responsible for parsing a specific XML part of configuration data. + * + * @author Andrea Gazzarini + */ +interface IParser +{ + /** + * Main director callback : Sets the name of the current attribute. + * + * @param name the name of the current attribute. + */ + void setCurrentAttributeName(String name); + + /** + * Main director callback : sets the value of the current attribute. + * + * @param value the value of the current attribute. + */ + void setCurrrentAttributeValue(String value); +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java new file mode 100644 index 0000000000..5e38346a2d --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java @@ -0,0 +1,90 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +/** + * Message Handler mapping used for associating an opcode with a message handler. + * + * @author Andrea Gazzarini + */ +class MessageHandlerMapping +{ + private Character _opcode; + private String _handlerClass; + + /** + * Builds an empty message handler mapping. + */ + MessageHandlerMapping() + { + } + + /** + * Builds a new mapping with the given opcode and handler class. + * + * @param opcode the opcode. + * @param handlerClass the handler class. + */ + MessageHandlerMapping(Character opcode, String handlerClass) { + this._opcode = opcode; + this._handlerClass = handlerClass; + } + + /** + * Returns the opcode of this mapping. + * + * @return the code of this mapping. + */ + Character getOpcode () + { + return _opcode; + } + + /** + * Sets the opcode for this mapping. + * + * @param codeAsString the opcode as a string. + */ + void setOpcode (String codeAsString) + { + this._opcode = codeAsString.charAt(0); + } + + /** + * Returns the message handler for this mapping. + * + * @return the message handler for this mapping. + */ + String getMessageHandlerClass() + { + return _handlerClass; + } + + /** + * Sets the message handler of this mapping. + * + * @param handlerClass the handler class as a string. + */ + void setMessageHandlerClass(String handlerClass) + { + this._handlerClass = handlerClass; + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/QpidDatasource.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/QpidDatasource.java new file mode 100644 index 0000000000..569a65a782 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/QpidDatasource.java @@ -0,0 +1,249 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.commons.pool.BasePoolableObjectFactory; +import org.apache.commons.pool.ObjectPool; +import org.apache.commons.pool.impl.GenericObjectPool; +import org.apache.commons.pool.impl.GenericObjectPoolFactory; +import org.apache.qpid.management.Messages; +import org.apache.qpid.transport.Connection; +import org.apache.qpid.transport.ConnectionException; +import org.apache.qpid.transport.util.Logger; + +/** + * Qpid datasource. + * Basically it is a connection pool manager used for optimizing broker connections usage. + * + * @author Andrea Gazzarini + */ +public final class QpidDatasource +{ + private final static Logger LOGGER = Logger.get(QpidDatasource.class); + + /** + * A connection decorator used for adding pool interaction behaviour to an existing connection. + * + * @author Andrea Gazzarini + */ + class PooledConnection extends Connection + { + private final UUID _brokerId; + private boolean _valid; + + /** + * Builds a new decorator with the given connection. + * + * @param brokerId the broker identifier. + */ + private PooledConnection(UUID brokerId) + { + this._brokerId = brokerId; + _valid = true; + } + + /** + * Returns true if the underlying connection is still valid and can be used. + * + * @return true if the underlying connection is still valid and can be used. + */ + boolean isValid() + { + return _valid; + } + + void reallyClose() + { + super.close(); + } + + /** + * Returns the connection to the pool. That is, marks this connections as available. + * After that, this connection will be available for further operations. + */ + public void close() + { + try + { + pools.get(_brokerId).returnObject(this); + + LOGGER.debug(Messages.QMAN_200006_QPID_CONNECTION_RELEASED, this); + } + catch (Exception e) + { + throw new ConnectionException(e); + } + } + + public void exception(Throwable t) + { + //super.exception(t); + _valid = false; + } + } + + /** + * This is the connection factory, that is, the factory used to manage the lifecycle (create, validate & destroy) of + * the broker connection(s). + * + * @author Andrea Gazzarini + */ + class QpidConnectionFactory extends BasePoolableObjectFactory + { + private final BrokerConnectionData _connectionData; + private final UUID _brokerId; + + /** + * Builds a new connection factory with the given parameters. + * + * @param brokerId the broker identifier. + * @param connectionData the connecton data. + */ + private QpidConnectionFactory(UUID brokerId, BrokerConnectionData connectionData) + { + this._connectionData = connectionData; + this._brokerId = brokerId; + } + + /** + * Creates a new underlying connection. + */ + @Override + public Connection makeObject () throws Exception + { + PooledConnection connection = new PooledConnection(_brokerId); + connection.connect( + _connectionData.getHost(), + _connectionData.getPort(), + _connectionData.getVirtualHost(), + _connectionData.getUsername(), + _connectionData.getPassword(), + false); + return connection; + } + + /** + * Validates the underlying connection. + */ + @Override + public boolean validateObject (Object obj) + { + PooledConnection connection = (PooledConnection) obj; + boolean isValid = connection.isValid(); + + LOGGER.debug(Messages.QMAN_200007_TEST_CONNECTION_ON_RESERVE,isValid); + + return isValid; + } + + /** + * Closes the underlying connection. + */ + @Override + public void destroyObject (Object obj) throws Exception + { + try + { + PooledConnection connection = (PooledConnection) obj; + connection.reallyClose(); + + LOGGER.debug(Messages.QMAN_200008_CONNECTION_DESTROYED); + } catch (Exception exception) + { + LOGGER.debug(exception, Messages.QMAN_200009_CONNECTION_DESTROY_FAILURE); + } + } + } + + // Singleton instance. + private static QpidDatasource instance = new QpidDatasource(); + + // Each entry contains a connection pool for a specific broker. + private Map<UUID, ObjectPool> pools = new HashMap<UUID, ObjectPool>(); + + // Private constructor. + private QpidDatasource() + { + } + + /** + * Gets an available connection from the pool of the given broker. + * + * @param brokerId the broker identifier. + * @return a valid connection to the broker associated with the given identifier. + */ + public Connection getConnection(UUID brokerId) throws Exception + { + return (Connection) pools.get(brokerId).borrowObject(); + } + + /** + * Entry point method for retrieving the singleton instance of this datasource. + * + * @return the qpid datasource singleton instance. + */ + public static QpidDatasource getInstance() + { + return instance; + } + + /** + * Adds a connection pool to this datasource. + * + * @param brokerId the broker identifier that will be associated with the new connection pool. + * @param connectionData the broker connection data. + * @throws Exception when the pool cannot be created. + */ + void addConnectionPool(UUID brokerId,BrokerConnectionData connectionData) throws Exception + { + GenericObjectPoolFactory factory = new GenericObjectPoolFactory( + new QpidConnectionFactory(brokerId,connectionData), + connectionData.getMaxPoolCapacity(), + GenericObjectPool.WHEN_EXHAUSTED_BLOCK, + connectionData.getMaxWaitTimeout(),-1, + true, + false); + + ObjectPool pool = factory.createPool(); + + // Open connections at startup according to initial capacity param value. + int howManyConnectionAtStartup = connectionData.getInitialPoolCapacity(); + Object [] openStartupList = new Object[howManyConnectionAtStartup]; + + // Open... + for (int index = 0; index < howManyConnectionAtStartup; index++) + { + openStartupList[index] = pool.borrowObject(); + } + + // ...and immediately return them to pool. In this way the pooled connection has been opened. + for (int index = 0; index < howManyConnectionAtStartup; index++) + { + pool.returnObject(openStartupList[index]); + } + + pools.put(brokerId,pool); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.java new file mode 100644 index 0000000000..7ff23c9d13 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.java @@ -0,0 +1,51 @@ +/* +* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.management.configuration; + +/** + * Configuration Tag catalogue. + * + * @author Andrea Gazzarini + */ +public enum Tag { + CONFIGURATION { @Override public String toString() { return "configuration"; }}, + BROKER { @Override public String toString() { return "broker"; }}, + HOST { @Override public String toString() { return "host"; }}, + PORT { @Override public String toString() { return "port"; }}, + MAX_POOL_CAPACITY { @Override public String toString() { return "max-pool-capacity"; }}, + MAX_WAIT_TIMEOUT { @Override public String toString() { return "max-wait-timeout"; }}, + INITIAL_POOL_CAPACITY { @Override public String toString() { return "initial-pool-capacity"; }}, + VIRTUAL_HOST { @Override public String toString() { return "virtual-host"; }}, + USER { @Override public String toString() { return "user"; }}, + PASSWORD { @Override public String toString() { return "password"; }}, + BROKERS { @Override public String toString() { return "brokers"; }}; + + /** + * Returns the enum entry associated to the given tag name. + * + * @param name the name of tag. + * @return the enum entry associated to the given tag name. + */ + public static Tag get(String name) { + return valueOf(name.replaceAll("-", "_").toUpperCase()); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/TypeMapping.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/TypeMapping.java new file mode 100644 index 0000000000..2c0a460c1a --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/TypeMapping.java @@ -0,0 +1,90 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +import org.apache.qpid.management.domain.model.type.Type; + +/** + * Type Mapping used for associating a code with a management type. + * + * @author Andrea Gazzarini + */ +class TypeMapping +{ + private final int _code; + private final Type _type; + private final String _validatorClass; + + /** + * Builds a new type mapping with the given parameters and no validator. + * + * @param code the code. + * @param type the management type. + */ + TypeMapping(int code, Type type) + { + this(code,type,null); + } + + /** + * Builds a new type mapping with the given parameters. + * + * @param code the code. + * @param type the management type. + * @param validatorClassName the class name of the validator to be used. + */ + TypeMapping(int code, Type type, String validatorClassName) + { + this._code = code; + this._type = type; + this._validatorClass = validatorClassName; + } + + /** + * Returns the code of this mapping. + * + * @return the code of this mapping. + */ + int getCode () + { + return _code; + } + + /** + * Returns the type for this mapping. + * + * @return the type for this mapping. + */ + Type getType () + { + return _type; + } + + /** + * Returns the validator class of this mapping. + * + * @return the validator class (as a string) of this mapping. + */ + public String getValidatorClassName() + { + return _validatorClass; + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownAccessCodeException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownAccessCodeException.java new file mode 100644 index 0000000000..b7f1c0a7ec --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownAccessCodeException.java @@ -0,0 +1,53 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +/** + * Thrown when no access mode is found in configuration associated to the given code. + * + * @author Andrea Gazzarini + */ +public class UnknownAccessCodeException extends Exception +{ + private static final long serialVersionUID = 2350963503092509119L; + private final int _code; + + /** + * Builds a new UnknownAccessCodeException with the given code. + * + * @param code the access code. + */ + UnknownAccessCodeException(int code) + { + super(String.valueOf(code)); + this._code = code; + } + + /** + * Returns the unknown code. + * + * @return the unknown code. + */ + public int getCode () + { + return _code; + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownBrokerException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownBrokerException.java new file mode 100644 index 0000000000..5b08e09c24 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownBrokerException.java @@ -0,0 +1,43 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +import java.util.UUID; + +/** + * Thrown when someone requests connection data for an unknown broker. + * + * @author Andrea Gazzarini + */ +public class UnknownBrokerException extends Exception +{ + private static final long serialVersionUID = 4965395428832158924L; + + /** + * Builds a new UnknownBrokerException with the given broker id. + * + * @param brokerId the broker identifier. + */ + UnknownBrokerException(UUID brokerId) + { + super(String.valueOf(brokerId)); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownTypeCodeException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownTypeCodeException.java new file mode 100644 index 0000000000..57005d21e5 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownTypeCodeException.java @@ -0,0 +1,53 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +/** + * Thrown when no type is found in configuration associated to the given code. + * + * @author Andrea Gazzarini + */ +public class UnknownTypeCodeException extends Exception +{ + private static final long serialVersionUID = 5440934037645111591L; + private int _code; + + /** + * Builds a new UnknownTypeCodeException with the given code. + * + * @param code the access code. + */ + UnknownTypeCodeException(int code) + { + super(String.valueOf(code)); + this._code = code; + } + + /** + * Returns the unknown code. + * + * @return the unknown code. + */ + public int getCode () + { + return _code; + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/BaseMessageHandler.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/BaseMessageHandler.java new file mode 100644 index 0000000000..798e835ff4 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/BaseMessageHandler.java @@ -0,0 +1,54 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.handler.base; + +import org.apache.qpid.management.domain.model.DomainModel; +import org.apache.qpid.transport.util.Logger; + +/** + * Base class for all message handlers. + * A message handler is an handler for a specific type of message. + * Message type is defined by the opcode. + * + * @author Andrea Gazzarini + */ +public abstract class BaseMessageHandler implements IMessageHandler +{ + /** + * Logger used for logging. + */ + protected final Logger _logger = Logger.get(getClass()); + + /** + * Managed broker domain model. + */ + protected DomainModel _domainModel; + + /** + * Sets the broker domain model. + * + * @param domainModel the broker domain model. + */ + public void setDomainModel(DomainModel domainModel) + { + this._domainModel = domainModel; + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandler.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandler.java new file mode 100644 index 0000000000..be000e9a05 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandler.java @@ -0,0 +1,114 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.handler.base; + +import org.apache.qpid.management.domain.model.type.Binary; +import org.apache.qpid.transport.codec.Decoder; + +/** + * Base class for content indication message handlers. + * + * @author Andrea Gazzarini + */ +public abstract class ContentIndicationMessageHandler extends BaseMessageHandler +{ + /** + * Processes the income message. + * + * @param decoder the decoder used to parse the message. + * @param sequenceNumber the sequence number of the message. + */ + public final void process (Decoder decoder, int sequenceNumber) + { + String packageName = decoder.readStr8(); + String className = decoder.readStr8(); + Binary classHash = new Binary(decoder.readBin128()); + + long timeStampOfCurrentSample = decoder.readDatetime(); + long timeObjectWasCreated = decoder.readDatetime(); + long timeObjectWasDeleted = decoder.readDatetime(); + + Binary objectId = new Binary(decoder.readBin128()); + + if (objectHasBeenRemoved(timeObjectWasDeleted, timeStampOfCurrentSample)) + { + removeObjectInstance(packageName,className,classHash,objectId); + } else + { + updateDomainModel( + packageName, + className, + classHash, + objectId, + timeStampOfCurrentSample, + timeObjectWasCreated, + timeObjectWasDeleted, + decoder.readReaminingBytes()); + } + } + + /** + * Removes an object instance from the domain model. + * + * @param packageName the package name. + * @param className the class name. + * @param classHash the class hash. + * @param objectId the object identifier. + */ + void removeObjectInstance(String packageName, String className,Binary classHash, Binary objectId) + { + _domainModel.removeObjectInstance(packageName,className,classHash,objectId); + } + + /** + * Checks if the timestamps contained in the message indicate that the object has been removed. + * + * @param deletionTimestamp time object was deleted. + * @param now timestamp of the current message. + * @return true if the object has been removed, false otherwise. + */ + boolean objectHasBeenRemoved(long deletionTimestamp, long now) { + return (deletionTimestamp != 0) && (now > deletionTimestamp); + } + + /** + * Updates domain model with the incoming data. + * This is a template method that each concrete subclass must implement in order to update the domain model + * with the incoming data. + * + * @param packageName the name of the package. + * @param className the name of the class. + * @param objectId the object identifier. + * @param timeStampOfCurrentSample timestamp of current sample. + * @param timeObjectWasCreated time object was created. + * @param timeObjectWasDeleted time object was deleted. + * @param contentData object instance incoming data. + */ + protected abstract void updateDomainModel( + String packageName, + String className, + Binary classHash, + Binary objectId, + long timeStampOfCurrentSample, + long timeObjectWasCreated, + long timeObjectWasDeleted, + byte []contentData ); +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/IMessageHandler.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/IMessageHandler.java new file mode 100644 index 0000000000..c120334d30 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/IMessageHandler.java @@ -0,0 +1,52 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.handler.base; + +import org.apache.qpid.management.domain.model.DomainModel; +import org.apache.qpid.transport.codec.Decoder; + +/** + * Interface definition for a processor able to deal with a specific message. + * The concrete implementor must define what has to be done with the supplied (incoming) stream and the sequence + * number. + * + * @author Andrea Gazzarini. + */ +public interface IMessageHandler +{ + /** + * Processes the (incoming) stream message. + * Note that the main controller (the component that is controlling this handler) has already read the magic number and + * the sequence number so here concrete implementors must start from that point (that is, just after the sequence + * number). + * + * @param decoder the stream decoder. + * @param sequenceNumber the sequence number of the message. + */ + void process (Decoder decoder, int sequenceNumber); + + /** + * Injects the domain model into this handler. + * + * @param domainModel the domain model. + */ + void setDomainModel(DomainModel domainModel); +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/ConfigurationMessageHandler.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/ConfigurationMessageHandler.java new file mode 100644 index 0000000000..3158138172 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/ConfigurationMessageHandler.java @@ -0,0 +1,57 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.handler.impl; + +import org.apache.qpid.management.domain.handler.base.ContentIndicationMessageHandler; +import org.apache.qpid.management.domain.model.type.Binary; + +/** + * Schema Response message handler. + * This handler is responsible to process 'c'(opcode) messages sent by the management broker. + * + * @author Andrea Gazzarini + */ +public class ConfigurationMessageHandler extends ContentIndicationMessageHandler +{ + /** + * Broker domain model is going to be updated with incoming configuration data. + * + * @param packageName the name of the package. + * @param className the name of the class. + * @param objectId the object identifier. + * @param timeStampOfCurrentSample the timestamp of incoming data. + * @param timeObjectWasCreated time object was created. + * @param timeObjectWasDeleted time object was deleted. + */ + @Override + protected void updateDomainModel ( + String packageName, + String className, + Binary classHash, + Binary objectId, + long timeStampOfCurrentSample, + long timeObjectWasCreated, + long timeObjectWasDeleted, + byte[] contentData) + { + _domainModel.addConfigurationRawData(packageName,className,classHash,objectId,contentData); + } + } diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java new file mode 100644 index 0000000000..0a590d2836 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java @@ -0,0 +1,51 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.handler.impl;
+
+import org.apache.qpid.management.domain.handler.base.BaseMessageHandler;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * Base class for content indication message handlers.
+ *
+ * @author Andrea Gazzarini
+ */
+public class EventContentMessageHandler extends BaseMessageHandler
+{
+ /**
+ * Processes the income message.
+ *
+ * @param decoder the decoder used to parse the message.
+ * @param sequenceNumber the sequence number of the message.
+ */
+ public final void process (Decoder decoder, int sequenceNumber)
+ {
+ String packageName = decoder.readStr8();
+ String eventName = decoder.readStr8();
+ Binary eventHash = new Binary(decoder.readBin128());
+ long timeStampOfCurrentSample = decoder.readDatetime();
+ int severity = decoder.readUint8();
+ byte[] argumentsData = decoder.readReaminingBytes();
+
+ _domainModel.addEventRawData(packageName, eventName, eventHash, argumentsData,timeStampOfCurrentSample,severity);
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/HeartBeatIndicationMessageHandler.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/HeartBeatIndicationMessageHandler.java new file mode 100644 index 0000000000..08c4f1bc5d --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/HeartBeatIndicationMessageHandler.java @@ -0,0 +1,39 @@ +/*
+*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.management.domain.handler.impl;
+
+import org.apache.qpid.management.domain.handler.base.BaseMessageHandler;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * This is the handler responsible for processing the heartbeat indication response messages.
+ * At the moment it simply updates the last refresh update timestamp of the domain model.
+ *
+ * @author Andrea Gazzarini.
+ */
+public class HeartBeatIndicationMessageHandler extends BaseMessageHandler
+{
+ public void process(Decoder decoder, int sequenceNumber)
+ {
+ _domainModel.updateLastRefreshDate();
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/IMethodInvocationListener.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/IMethodInvocationListener.java new file mode 100644 index 0000000000..4ce64dd339 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/IMethodInvocationListener.java @@ -0,0 +1,41 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.handler.impl; + +import java.util.EventListener; + +import org.apache.qpid.management.domain.model.InvocationEvent; + +/** + * Listener interface used to denote a component interested in method invocation events. + * + * @author Andrea Gazzarini + */ +public interface IMethodInvocationListener extends EventListener +{ + /** + * An operation is going to be invoked on a specific object instance. + * This lets this listener to be informed about the imminent invocation. + * + * @param event the invocation event. + */ + void operationIsGoingToBeInvoked(InvocationEvent event); +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InstrumentationMessageHandler.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InstrumentationMessageHandler.java new file mode 100644 index 0000000000..e86a44f829 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InstrumentationMessageHandler.java @@ -0,0 +1,57 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.handler.impl; + +import org.apache.qpid.management.domain.handler.base.ContentIndicationMessageHandler; +import org.apache.qpid.management.domain.model.type.Binary; + +/** + * Schema Response message handler. + * This handler is responsible to process 'i'(opcode) messages sent by the management broker. + * + * @author Andrea Gazzarini + */ +public class InstrumentationMessageHandler extends ContentIndicationMessageHandler +{ + /** + * Broker domain model is going to be updated with incoming instrumentation data. + * + * @param packageName the name of the package. + * @param className the name of the class. + * @param objectId the object identifier. + * @param timeStampOfCurrentSample the timestamp of incoming data. + * @param timeObjectWasCreated time object was created. + * @param timeObjectWasDeleted time object was deleted. + */ + @Override + protected void updateDomainModel ( + String packageName, + String className, + Binary classHash, + Binary objectId, + long timeStampOfCurrentSample, + long timeObjectWasCreated, + long timeObjectWasDeleted, + byte[] contentData) + { + _domainModel.addInstrumentationRawData(packageName,className,classHash,objectId,contentData); + } + } diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java new file mode 100644 index 0000000000..d188d20976 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java @@ -0,0 +1,157 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.handler.impl; + +import java.io.Serializable; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.qpid.management.domain.services.MethodInvocationException; + +/** + * Value object used for storing an invocation method result. + * This is done in order to accomplish multiple return value requirement. + * As we know, it's not possible to do that only with method signature and therefore this value object / struct is used. + * + * @author Andrea Gazzarini + */ +public class InvocationResult implements Serializable +{ + private static final long serialVersionUID = 2062662997326399693L; + + private final long _returnCode; + private final String _statusText; + private final byte [] _outputAndBidirectionalArgumentValues; + private Map<String, Object> _outputSection; + + /** + * Builds an invocation result with the given status code and status text. + * + * @param statusCode the status code. + * @param statusText the status text. + */ + InvocationResult(long statusCode, String statusText,byte [] outputAndBidirectionalArgumentValues) + { + this._returnCode = statusCode; + this._statusText = statusText; + this._outputAndBidirectionalArgumentValues = outputAndBidirectionalArgumentValues; + } + + /** + * Checks if this result contains an error return code. + * + * @return true if this result object contains an error return code. + */ + public boolean isException () + { + return _returnCode != 0; + } + + /** + * Simply throws a new MethodInvocationException. + * Usually this method is called in conjunction with the isException() method in order to raise an exception if + * the wrapped return code means that there was an error. + * + * @throws MethodInvocationException always. + */ + public void createAndThrowException() throws MethodInvocationException + { + throw new MethodInvocationException(_returnCode, _statusText); + } + + @Override + public String toString () + { + StringBuilder builder = new StringBuilder() + .append("Status code : ") + .append(_returnCode) + .append(",") + .append("Status Text : ") + .append(_statusText); + if (_outputSection != null && !_outputSection.isEmpty()) + { + builder.append(". Parameters : "); + for (Entry<String, Object> outputEntry : _outputSection.entrySet()) + { + builder.append(outputEntry.getKey()).append('=').append(outputEntry.getValue()); + builder.append(','); + } + } + return builder.toString(); + } + + /** + * Returns the return code of this invocation result. + * + * @return the return code of this invocation result. + */ + public long getReturnCode () + { + return _returnCode; + } + + /** + * Contains the status text of this invocation result. + * + * @return the status text of this invocation result. + */ + public String getStatusText () + { + return _statusText; + } + + /** + * Returns the output and bidirectional argument values in raw format (byte []) + * + * @return the output and bidirectional argument values in raw format (byte []) + */ + public byte [] getOutputAndBidirectionalArgumentValues() + { + return _outputAndBidirectionalArgumentValues; + } + + /** + * Sets the output section (decoded) of this invocation result. + * When an incoming message arrives, the output section (output and bidirectional argument values) are + * initially stored in raw format. + * After that, their values need to be converted. + * The final result is a map containing (for each Output or Input/Output parameter) the name of the argument as key + * and its value as value. + * + * @param output a map containing outptu and bidirectional values (not in schema order). + */ + public void setOutputSection (Map<String, Object> outputSection) + { + this._outputSection = outputSection; + } + + /** + * Returns the output section of this invocation result. + * The output section consists in output and bidirectional argument values. + * Note that the order of the arguments is not guaranteed. + * + * @param outputSection the output section of this invocation result; + */ + public Map<String, Object> getOutputSection () + { + return _outputSection; + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodOrEventDataTransferObject.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodOrEventDataTransferObject.java new file mode 100644 index 0000000000..bc6a77d804 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodOrEventDataTransferObject.java @@ -0,0 +1,68 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.handler.impl; + +import java.util.List; +import java.util.Map; + +/** + * Simple transfer object used for holding method / event definition data. + * + * @author Andrea Gazzarini + */ +public class MethodOrEventDataTransferObject +{ + private final Map<String, Object> _definition; + private List<Map<String, Object>> _argumentDefinitions; + + /** + * Builds a new trasfer object with the given parameters. + * + * @param definition the method definition. + * @param argumentDefinitions the arguments definitions. + */ + public MethodOrEventDataTransferObject( + Map<String, Object> definition, + List<Map<String, Object>> argumentDefinitions) + { + this._definition = definition; + this._argumentDefinitions = argumentDefinitions; + } + + /** + * Returns the method definition. + * + * @return the method definition. + */ + public Map<String, Object> getDefinition() { + return _definition; + } + + /** + * Returns the arguemnts definitions. + * + * @return the arguemnts definitions. + */ + public List<Map<String, Object>> getArgumentsDefinitions() + { + return _argumentDefinitions; + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodResponseMessageHandler.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodResponseMessageHandler.java new file mode 100644 index 0000000000..9c99eb09aa --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodResponseMessageHandler.java @@ -0,0 +1,106 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.handler.impl; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.BlockingQueue; + +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.domain.handler.base.BaseMessageHandler; +import org.apache.qpid.management.domain.model.DomainModel; +import org.apache.qpid.management.domain.model.InvocationEvent; +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.util.Logger; + +/** + * Message handler for method response messages. + * This handler is installed on domain model as a method invocation result listener. + * When a method is going to be invoked this listener is notified with the exchange channel that will be used between it and + * the event (method invocation) source object. + * + * @author Andrea Gazzarini + * + */ +public class MethodResponseMessageHandler extends BaseMessageHandler +{ + private final static Logger LOGGER = Logger.get(MethodResponseMessageHandler.class); + + private Map<Integer, BlockingQueue<InvocationResult>> _exchangeChannels = new HashMap<Integer, BlockingQueue<InvocationResult>>(); + + /** + * This is the listener installed on domain model for method invocations. + */ + private final IMethodInvocationListener methodInvocationListener = new IMethodInvocationListener() + { + /** + * Event source callback. + * A method is going to be invoked and this method lets this listener take the exchange channel that will be used + * with the event source for synchronous communication. + * + * @param event the operation invocation event. + */ + public void operationIsGoingToBeInvoked (InvocationEvent event) + { + _exchangeChannels.put(event.getSequenceNumber(), event.getExchangeChannel()); + } + }; + + /** + * Processes the incoming message. + * + * @param decoder the decoder used for parsing incoming data. + * @param sequenceNumber the sequence number of the incoming message. + */ + public void process (Decoder decoder, int sequenceNumber) + { + InvocationResult result = new InvocationResult(decoder.readUint32(), decoder.readStr16(),decoder.readReaminingBytes()); + BlockingQueue<InvocationResult> exchangeChannel = _exchangeChannels.remove(sequenceNumber); + if (exchangeChannel != null) + { + try + { + exchangeChannel.put(result); + } catch (InterruptedException exception) + { + LOGGER.error(exception,Messages.QMAN_100010_METHOD_INVOCATION_RESULT_FAILURE,sequenceNumber); + } + } else + { + LOGGER.warn( + "Unable to deal with incoming message because it contains a unknown sequence number (%s).", + sequenceNumber); + } + } + + /** + * Sets the domain model on this handler. + * In addiction, this handler registers a method invocation listener on the domain model. + * + * @param domainModel the managed broker domain model. + */ + @Override + public void setDomainModel (DomainModel domainModel) + { + super.setDomainModel(domainModel); + domainModel.setMethodInvocationListener(methodInvocationListener); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java new file mode 100644 index 0000000000..ee5efe2af6 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java @@ -0,0 +1,217 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.handler.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; +import org.apache.qpid.management.Protocol; +import org.apache.qpid.management.domain.handler.base.BaseMessageHandler; +import org.apache.qpid.management.domain.model.type.Binary; +import org.apache.qpid.transport.codec.Decoder; + +/** + * Schema Response message handler. + * This handler is responsible to process 'S'(opcode) messages sent by the management broker containing the full + * schema details for a class. + * + * @author Andrea Gazzarini + */ +public class SchemaResponseMessageHandler extends BaseMessageHandler +{ + /** + * Behavioural interface for classes that are responsible to deal with schema messages. + * + * @author Andrea Gazzarini + */ + interface IProcessor + { + /** + * Processes the incoming message using the given decoder. + * + * @param decoder the decoder used for dealing with incoming message. + */ + void process(Decoder decoder); + } + + /** + * Processor responsible to deal with class schema related messages. + */ + final IProcessor _classSchemaProcessor = new IProcessor() + { + public void process(Decoder decoder) + { + try + { + String packageName = decoder.readStr8(); + String className = decoder.readStr8(); + + Binary schemaHash = new Binary(decoder.readBin128()); + + int howManyProperties = decoder.readUint16(); + int howManyStatistics = decoder.readUint16(); + int howManyMethods = decoder.readUint16(); + + _domainModel.addSchema( + packageName, + className, + schemaHash, + getAttributes(decoder, howManyProperties), + getAttributes(decoder, howManyStatistics), + getMethods(decoder, howManyMethods)); + } catch(Exception exception) + { + _logger.error(exception,Messages.QMAN_100005_CLASS_SCHEMA_PROCESSING_FAILURE); + } + } + }; + + /** + * Processor responsible to deal with class event related messages. + */ + final IProcessor _eventSchemaProcessor = new IProcessor() + { + public void process(Decoder decoder) + { + try + { + String packageName = decoder.readStr8(); + String className = decoder.readStr8(); + Binary hash = new Binary(decoder.readBin128()); + int howManyArguments = decoder.readUint16(); + + _domainModel.addEventSchema( + packageName, + className, + hash, + getAttributes(decoder, howManyArguments)); + } catch(Exception exception) + { + _logger.error(exception,Messages.QMAN_100006_EVENT_SCHEMA_PROCESSING_FAILURE); + } + } + }; + + /** + * Processes an incoming schema response. + * This will be used for building the corresponding class definition. + * + * @param decoder the decoder used for parsing the incoming stream. + * @param sequenceNumber the sequence number of the incoming message. + */ + public void process (Decoder decoder, int sequenceNumber) + { + try + { + int classKind = decoder.readUint8(); + switch(classKind) + { + case Protocol.CLASS : + { + _classSchemaProcessor.process(decoder); + break; + } + case Protocol.EVENT : + { + _eventSchemaProcessor.process(decoder); + break; + } + default : + { + _logger.error(Messages.QMAN_100011_UNKNOWN_CLASS_KIND,classKind); + } + } + } catch(Exception exception) + { + _logger.error(exception,Messages.QMAN_100012_SCHEMA_MESSAGE_PROCESSING_FAILURE); + } + } + + /** + * Reads from the incoming message stream the properties definitions. + * + * @param decoder the decoder used for decode incoming data. + * @param howManyProperties the number of properties to read. + * @return a list of maps. Each map contains a property definition. + */ + List<Map<String, Object>> getAttributes(Decoder decoder,int howMany) + { + List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(howMany); + for (int i = 0; i < howMany; i++ ) + { + result.add(decoder.readMap()); + } + return result; + } + + /** + * Reads the methods definitions from the incoming message stream. + * + * @param decoder the decoder used for decode incoming data. + * @param howManyMethods the number of methods to read. + * @return a list method definitions. + */ + List<MethodOrEventDataTransferObject> getMethods(Decoder decoder, int howManyMethods) + { + List<MethodOrEventDataTransferObject> result = new ArrayList<MethodOrEventDataTransferObject>(howManyMethods); + for (int i = 0; i < howManyMethods; i++) + { + Map<String,Object> method = decoder.readMap(); + int howManyArguments = (Integer) method.get(Names.ARG_COUNT_PARAM_NAME); + + List<Map<String,Object>> arguments = new ArrayList<Map<String,Object>>(howManyArguments); + for (int argIndex = 0; argIndex < howManyArguments; argIndex++) + { + arguments.add(decoder.readMap()); + } + result.add(new MethodOrEventDataTransferObject(method,arguments)); + } + return result; + } + + /** + * Reads the events definitions from the incoming message stream. + * + * @param decoder the decoder used for decode incoming data. + * @param howManyEvents the number of events to read. + * @return a list event definitions. + */ + List<MethodOrEventDataTransferObject> getEvents(Decoder decoder, int howManyEvents) + { + List<MethodOrEventDataTransferObject> result = new ArrayList<MethodOrEventDataTransferObject>(howManyEvents); + for (int i = 0; i < howManyEvents; i++) + { + Map<String,Object> method = decoder.readMap(); + int howManyArguments = (Integer) method.get(Names.ARG_COUNT_PARAM_NAME); + + List<Map<String,Object>> arguments = new ArrayList<Map<String,Object>>(howManyArguments); + for (int argIndex = 0; argIndex < howManyArguments; argIndex++) + { + arguments.add(decoder.readMap()); + } + result.add(new MethodOrEventDataTransferObject(method,arguments)); + } + return result; + } + }
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/AccessMode.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/AccessMode.java new file mode 100644 index 0000000000..6d1426c122 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/AccessMode.java @@ -0,0 +1,33 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +/** + * Enumeration for Access modes. + * + * @author Andrea Gazzarini + */ +public enum AccessMode +{ + RC { @Override public String toString() { return "Read-Create"; }}, + RO { @Override public String toString() { return "Read-Only"; }}, + RW { @Override public String toString() { return "Read-Write"; }} +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/Direction.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/Direction.java new file mode 100644 index 0000000000..8166c35eb6 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/Direction.java @@ -0,0 +1,33 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +/** + * Enumeration of allowed method argument direction codes. + * + * @author Andrea Gazzarini + */ +public enum Direction +{ + I{ @Override public String toString() { return "Input"; }}, + O{ @Override public String toString() { return "Output"; }}, + IO{ @Override public String toString() { return "Input-Output"; }}; +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java new file mode 100644 index 0000000000..5a0ebaf1f7 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java @@ -0,0 +1,239 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.management.domain.handler.impl.IMethodInvocationListener; +import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject; +import org.apache.qpid.management.domain.model.type.Binary; + +/** + * Broker domain model. + * This is the local representation of a remote broker domain model. + * + * @author Andrea Gazzarini + */ +public class DomainModel +{ + private final UUID _id; + + /** Here the known packages of the remote broker are stored. */ + Map<String,QpidPackage> _packages = new HashMap<String, QpidPackage>(); + + private Date _lastRefreshDate = new Date(); + + private IMethodInvocationListener _methodInvocationListener; + + /** + * Builds a new domain model with the given broker identifier. + * + * @param brokerId the broker identifier. + */ + public DomainModel(UUID brokerId) + { + this._id = brokerId; + } + + /** + * Returns the identifier of the broker associated with this domain model. + * + * @return the identifier of the broker associated with this domain model. + */ + public UUID getBrokerId() + { + return _id; + } + + /** + * Adds the specified schema to this domain model. + * + * @param packageName the package name. + * @param className the class name. + * @param classHash the class schema hash. + * @param properties the class properties. + * @param statistics the class statistics. + * @param methods the class methods. + * @throws UnableToBuildFeatureException + */ + public void addSchema( + String packageName, + String className, + Binary classHash, + List<Map<String, Object>> properties, + List<Map<String, Object>> statistics, + List<MethodOrEventDataTransferObject> methods) throws UnableToBuildFeatureException + { + QpidPackage qpidPackage = getPackageByName(packageName); + qpidPackage.addClassDefinition(className,classHash,properties,statistics,methods); + } + + /** + * Updates the last refresh date. + */ + public void updateLastRefreshDate() + { + this._lastRefreshDate = new Date(); + } + + /** + * Returns the last refresh date. + * + * @return the last refresh date. + */ + public Date getLastRefreshDate() + { + return _lastRefreshDate; + } + + /** + * Adds the specified schema to this domain model. + * + * @param packageName the package name. + * @param className the class name. + * @param classHash the class schema hash. + * @param properties the class properties. + * @param statistics the class statistics. + * @param methods the class methods. + * @throws UnableToBuildFeatureException + */ + public void addEventSchema( + String packageName, + String className, + Binary classHash, + List<Map<String, Object>> arguments) throws UnableToBuildFeatureException + { + QpidPackage qpidPackage = getPackageByName(packageName); + qpidPackage.addEventDefinition(className,classHash,arguments); + } + + /** + * Gets the package with the specified name. + * Note that if the package doesn't exist a new one will be created and returned. + * + * @param packageName the name of the package. + * @return the package. + */ + QpidPackage getPackageByName (String packageName) + { + QpidPackage qpidPackage = _packages.get(packageName); + if (qpidPackage == null) + { + qpidPackage = new QpidPackage(packageName,this); + _packages.put(packageName, qpidPackage); + } + return qpidPackage; + } + + /** + * Returns true if a package with the specified name already exists on this domain model. + * + * @param packageName the name of the package. + * @return true if the package exists, false otherwise. + */ + boolean containsPackage (String packageName) + { + return _packages.containsKey(packageName); + } + + /** + * Adds the given instrumentation data (raw format) to this domain model. + * Note that this data is belonging to a specific object instance. + * + * @param packageName the name of the ower package. + * @param className the name of the owner class. + * @param classHash the schema hash for this class. + * @param objectId the object instance identifier. + * @param rawData the instrumentation data. + */ + public void addInstrumentationRawData (String packageName, String className,Binary classHash, Binary objectId, byte[] rawData) + { + QpidPackage qpidPackage = getPackageByName(packageName); + qpidPackage.setObjectInstanceInstrumentationRawData(className,classHash,objectId,rawData); + } + + public void addEventRawData ( + String packageName, + String eventName, + Binary eventHash, + byte[] rawData, + long currentTimestamp, + int severity) + { + QpidPackage qpidPackage = getPackageByName(packageName); + qpidPackage.setEventInstanceRawData(eventName,eventHash,rawData,currentTimestamp,severity); + } + + /** + * Adds the given configuration data (raw format) to this domain model. + * Note that this data is belonging to a specific object instance. + * + * @param packageName the name of the ower package. + * @param className the name of the owner class. + * @param classHash the schema hash for this class. + * @param objectId the object instance identifier. + * @param rawData the configuration data. + */ + public void addConfigurationRawData (String packageName, String className, Binary classHash,Binary objectId, byte[] rawData) + { + QpidPackage qpidPackage = getPackageByName(packageName); + qpidPackage.setObjectInstanceConfigurationRawData(className,classHash,objectId,rawData); + } + + /** + * Removes the object instance associated to the given parameters. + * + * @param packageName the owner package. + * @param className the class definition of the object instance. + * @param classHash the class hash + * @param objectId the object identifier. + */ + public void removeObjectInstance (String packageName, String className, Binary classHash, Binary objectId) + { + QpidPackage qpidPackage = getPackageByName(packageName); + qpidPackage.removeObjectInstance(className, classHash, objectId); + } + + /** + * Releases all the resources kept by domain model entitiies. + */ + public void releaseResources() + { + for (QpidPackage qpidPackage : _packages.values()) + { + qpidPackage.releaseResources(); + } + } + + public void setMethodInvocationListener(IMethodInvocationListener listener) + { + this._methodInvocationListener = listener; + } + + IMethodInvocationListener getMethodInvocationListener () + { + return _methodInvocationListener; + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/IValidator.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/IValidator.java new file mode 100644 index 0000000000..1ede559145 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/IValidator.java @@ -0,0 +1,38 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +/** + * Interface definition for attribute validators. + * + * @author Andrea Gazzarini + */ +interface IValidator +{ + /** + * Validates the given value according to the rules definied by this validator. + * + * @param value the value be checked. + * + * @throws ValidationException when the value is violating validator's rules. + */ + void validate(Object value) throws ValidationException; +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/InvocationEvent.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/InvocationEvent.java new file mode 100644 index 0000000000..d84a018346 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/InvocationEvent.java @@ -0,0 +1,76 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import java.util.EventObject; +import java.util.concurrent.BlockingQueue; + +import org.apache.qpid.management.domain.handler.impl.InvocationResult; + +/** + * Operation invocation event. + * This encapsulates all the information that a method invocation listener needs to know about an operation which is + * going to be invoked. + * + * @author Andrea Gazzarini + */ +public class InvocationEvent extends EventObject +{ + private static final long serialVersionUID = 240229490753008597L; + + private final int _sequenceNumber; + private final BlockingQueue<InvocationResult> _exchangeChannel; + + /** + * Builds a new invocation event with the given data. + * + * @param source the event source. + * @param sequenceNumber the sequence number of the method invocation. + * @param exchangeChannel the exchange channel for synchronous communication. + */ + InvocationEvent(Object source, int sequenceNumber, BlockingQueue<InvocationResult> exchangeChannel) + { + super(source); + this._sequenceNumber = sequenceNumber; + this._exchangeChannel = exchangeChannel; + } + + /** + * Returns the sequence number that will be / has been used for method invocation. + * + * @return the sequence number that will be / has been used for method invocation. + */ + public int getSequenceNumber() + { + return _sequenceNumber; + } + + /** + * Returns the exchange channel that will be used between event source and event listener for synchronous + * communication. + * + * @return the exchange channel that will be used for synchronous communication. + */ + public BlockingQueue<InvocationResult> getExchangeChannel() + { + return _exchangeChannel; + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java new file mode 100644 index 0000000000..d919fdacae --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java @@ -0,0 +1,348 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import java.lang.management.ManagementFactory; +import java.util.Set; +import java.util.UUID; + +import javax.management.MBeanException; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; + +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; +import org.apache.qpid.management.domain.model.QpidClass.QpidManagedObject; +import org.apache.qpid.management.domain.model.QpidEvent.QpidManagedEvent; +import org.apache.qpid.management.domain.model.type.Binary; +import org.apache.qpid.management.domain.services.QMan; +import org.apache.qpid.transport.util.Logger; + +/** + * A simple facade used to perform operations on Mbean server. + * + * @author Andrea Gazzarini + */ +public class JmxService +{ + private final static Logger LOGGER = Logger.get(JmxService.class); + MBeanServer _mxServer = ManagementFactory.getPlatformMBeanServer(); + + /** + * Registers QMan with the MBeanServer. + * After that QMan management interface will be JMX-exposed. + * + * @param qman QMan + * @throws MBeanException when some error occurs during registration. + */ + public void registerQManService(QMan qman) throws MBeanException + { + ObjectName name = createQManName(); + if (!_mxServer.isRegistered(name)) + { + try { + _mxServer.registerMBean(qman, name); + } catch (Exception exception) { + throw new MBeanException(exception); + } + } + } + + void registerEventInstance( + QpidManagedEvent eventInstance, + UUID brokerId, + String packageName, + String eventClassName) + { + ObjectName name = createEventName(brokerId, packageName, eventClassName); + if (!_mxServer.isRegistered(name)) + { + try + { + _mxServer.registerMBean(eventInstance, name); + + LOGGER.debug( + Messages.QMAN_200010_EVENT_MBEAN_REGISTERED, + brokerId, + packageName, + eventClassName, + name); + } catch (Exception exception) + { + throw new RuntimeException(exception); + } + } +} + + /** + * Registers a pre-existing object instance as an MBean with the MBean + * server. + * + * @param instance the object instance. + * @param brokerId the broker identifier. + * @param packageName the name of the package containing this instance. + * @param className the name of the owner class of this instance. + * @param objectId the object instance identifier. + */ + void registerObjectInstance( + QpidManagedObject instance, + UUID brokerId, + String packageName, + String className, + Binary objectId) + { + ObjectName name = createObjectName(brokerId, packageName, className, objectId); + if (!_mxServer.isRegistered(name)) + { + try + { + _mxServer.registerMBean(instance, name); + + LOGGER.debug( + Messages.QMAN_200011_OBJECT_MBEAN_REGISTERED, + brokerId, + packageName, + className, + objectId, + name); + } catch (Exception exception) + { + throw new RuntimeException(exception); + } + } + } + + /** + * Removes / unregisters a managed object instance from the MBean Server. + * + * @param brokerId the broker identifier. + * @param packageName the name of the package containing this instance. + * @param className the name of the owner class of this instance. + * @param objectId the object instance identifier. + */ + void unregisterObjectInstance( + UUID brokerId, + String packageName, + String className, + Binary objectId) + { + ObjectName name = createObjectName(brokerId, packageName, className, objectId); + if (_mxServer.isRegistered(name)) + { + try + { + _mxServer.unregisterMBean(name); + + LOGGER.debug( + Messages.QMAN_200012_OBJECT_MBEAN_UNREGISTERED, + brokerId, + packageName, + className, + objectId, + name); + } catch (Exception exception) + { + LOGGER.error(exception,Messages.QMAN_100013_MBEAN_REGISTRATION_FAILURE,name); + } + } + } + + /** + * Removes (unregister) all events from MBean Server. + */ + void unregisterEvents() + { + for (ObjectName name : getEventMBeans()) + { + try + { + _mxServer.unregisterMBean(name); + } catch(Exception ignore) + { + } + } + } + + Set<ObjectName> getEventMBeans() + { + return _mxServer.queryNames(createEventSearchName(),null); + } + + /** + * Removes (unregister) all object instances from MBean Server. + */ + void unregisterObjectInstances() + { + Set<ObjectName> names = _mxServer.queryNames(createObjectInstanceSearchName(),null); + for (ObjectName name : names) + { + try + { + _mxServer.unregisterMBean(name); + } catch(Exception ignore) + { + } + } + } + + /** + * Factory method for ObjectNames. + * + * @param brokerId the broker identifier. + * @param packageName the name of the package containing this instance. + * @param className the name of the owner class of this instance. + * @param objectId the object instance identifier. + * @return the object name built according to the given parameters. + */ + private ObjectName createObjectName(UUID brokerId, String packageName, String className, Binary objectId) + { + String asString = new StringBuilder() + .append(Names.DOMAIN_NAME) + .append(':') + .append(Names.BROKER_ID) + .append('=') + .append(brokerId) + .append(",type=Object,") + .append(Names.PACKAGE) + .append('=') + .append(packageName) + .append(',') + .append(Names.CLASS) + .append('=') + .append(className) + .append(',') + .append(Names.OBJECT_ID) + .append('=') + .append(objectId) + .toString(); + try + { + return new ObjectName(asString); + } catch (MalformedObjectNameException exception) + { + throw new RuntimeException(exception); + } + } + + /** + * Creates an object name that will be used for searching all registered events. + * + * @return the object name that will be used for searching all registered events. + */ + ObjectName createEventSearchName() + { + String asString = new StringBuilder() + .append(Names.DOMAIN_NAME) + .append(':') + .append('*') + .append(",type=Event") + .toString(); + try + { + return new ObjectName(asString); + } catch (MalformedObjectNameException exception) + { + throw new RuntimeException(exception); + } + } + + /** + * Creates an object name that will be used for searching all registered object instances. + * + * @return the object name that will be used for searching all registered object instances. + */ + private ObjectName createObjectInstanceSearchName() + { + String asString = new StringBuilder() + .append(Names.DOMAIN_NAME) + .append(':') + .append('*') + .append(",type=Object") + .toString(); + try + { + return new ObjectName(asString); + } catch (MalformedObjectNameException exception) + { + throw new RuntimeException(exception); + } + } + + /** + * Factory method for ObjectNames. + * + * @param brokerId the broker identifier. + * @param packageName the name of the package containing this instance. + * @param className the name of the owner class of this instance. + * @return the object name built according to the given parameters. + */ + private ObjectName createEventName(UUID brokerId, String packageName, String className) + { + String asString = new StringBuilder() + .append(Names.DOMAIN_NAME) + .append(':') + .append(Names.BROKER_ID) + .append('=') + .append(brokerId) + .append(",type=Event,") + .append(Names.PACKAGE) + .append('=') + .append(packageName) + .append(',') + .append(Names.CLASS) + .append('=') + .append(className) + .append(',') + .append(Names.OBJECT_ID) + .append('=') + .append(UUID.randomUUID()) + .toString(); + try + { + return new ObjectName(asString); + } catch (MalformedObjectNameException exception) + { + throw new RuntimeException(exception); + } + } + + /** + * Creates the QMan object name. + * + * @return the QMan object name. + */ + private ObjectName createQManName() + { + String asString = new StringBuilder() + .append(Names.DOMAIN_NAME) + .append(':') + .append("Type=Service") + .toString(); + try + { + return new ObjectName(asString); + } catch (MalformedObjectNameException exception) + { + throw new RuntimeException(exception); + } + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/MissingFeatureAttributesException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/MissingFeatureAttributesException.java new file mode 100644 index 0000000000..160054059b --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/MissingFeatureAttributesException.java @@ -0,0 +1,35 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import java.util.List; + +import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute; + +public class MissingFeatureAttributesException extends UnableToBuildFeatureException +{ + private static final long serialVersionUID = 671471705085787235L; + + public MissingFeatureAttributesException(List<Attribute> missingAttributeList) + { + super(String.valueOf(missingAttributeList)); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java new file mode 100644 index 0000000000..1e90479c0b --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java @@ -0,0 +1,82 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import org.apache.qpid.management.Messages; +import org.apache.qpid.transport.codec.Encoder; +import org.apache.qpid.transport.util.Logger; + +class QpidArgument extends QpidProperty +{ + private final static Logger LOGGER = Logger.get(QpidArgument.class); + + private Object _defaultValue; + + private Direction _direction; + + public void setDirection(String code) + { + this._direction = Direction.valueOf(code); + } + + public Direction getDirection() + { + return _direction; + } + + public void setDefaultValue(Object defaultValue) + { + this._defaultValue = defaultValue; + } + + public Object getDefaultValue() + { + return _defaultValue; + } + + public boolean isInput(){ + return _direction != Direction.O; + } + + @Override + public String toString () + { + return new StringBuilder() + .append(getJavaType().getName()) + .append(' ') + .append(_name) + .append("(") + .append(_direction) + .append(")") + .toString(); + } + + public void encode(Object value,Encoder encoder) + { + _type.encode(value, encoder); + LOGGER.debug(Messages.QMAN_200013_ARGUMENT_VALUE_ENCODED,value,_name,_type); + } + + public Object decode(org.apache.qpid.transport.codec.Decoder decoder) + { + return _type.decode(decoder); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidAttribute.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidAttribute.java new file mode 100644 index 0000000000..6712a14075 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidAttribute.java @@ -0,0 +1,105 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.domain.model.type.Type; +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.util.Logger; + +/** + * Layer supertype for qpid properties and statistics. + * + * @author Andrea Gazzarini + */ +class QpidAttribute extends QpidFeature +{ + private final static Logger LOGGER = Logger.get(QpidAttribute.class); + + /** feature type */ + protected Type _type; + + /** feature unit */ + protected String _unit; + + /** + * Returns the units used for numeric values (i.e. seconds, bytes, etc.) + * + * @return the units used for numeric values (i.e. seconds, bytes, etc.) + */ + String getUnit () + { + return _unit; + } + + /** + * Sets the unit for this property. + * + * @param unit the unit of this property. + */ + void setUnit (String unit) + { + this._unit = unit; + } + + /** + * Returns the java type (class) of this feature. + * + * @return the java type (class) of this feature. + */ + Class<?> getJavaType () + { + return _type.getJavaType(); + } + + /** + * Sets the type of this feature. + * + * @param type the type of this feature. + */ + void setType (Type type) + { + this._type = type; + } + + /** + * Gets the value of this feature according to its type definition. + * + * @param decoder the decoder used to extract the value. + * @return the value of this feature according to its type definition + */ + Object decodeValue(Decoder decoder) + { + try { + return _type.decode(decoder); + } catch(RuntimeException exception) + { + LOGGER.error(exception,Messages.QMAN_100014_ATTRIBUTE_DECODING_FAILURE,this); + throw exception; + } + } + + @Override + public String toString () + { + return super.toString()+",type="+_type; + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java new file mode 100644 index 0000000000..c7dfcb033c --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java @@ -0,0 +1,768 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.InvalidAttributeValueException; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanRegistration; +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.management.ReflectionException; +import javax.management.RuntimeOperationsException; + +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.domain.handler.impl.IMethodInvocationListener; +import org.apache.qpid.management.domain.handler.impl.InvocationResult; +import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject; +import org.apache.qpid.management.domain.model.type.Binary; +import org.apache.qpid.management.domain.services.SequenceNumberGenerator; +import org.apache.qpid.transport.codec.BBDecoder; +import org.apache.qpid.transport.util.Logger; + +/** + * Qpid Class definition. + * A type definition for a manageable object. + * This class is also responsible to manage incoming obejct instance data (configuration & instrumentation). + * How can we handle data before schema is injected into this class? simply we must retain that data in raw format. + * This class has 2 states : + * 1) first state is when schema is not yet injected. In this case the incoming object data is retained as is (in raw format); + * 2) second state is when schema is injected. In this case each injection of data will result in an update / create / delete of + * the corresponding object instance. In addition, the first time the state change, the old retained raw data is cnverted in + * object instance(s). + * + * @author Andrea Gazzarini + */ +class QpidClass extends QpidEntity +{ + /** + * State interface for this class definition. + * Each state is responsible to handle the injection of the data and / or schema. + * + * @author Andrea Gazzarini + */ + interface State + { + /** + * Adds configuration data for the object instance associated to the given object identifier. + * + * @param objectId the object identifier. + * @param rawData the raw configuration data. + */ + void addInstrumentationData (Binary objectId, byte[] rawData); + + /** + * Adds instrumentation data for the object instance associated to the given object identifier. + * + * @param objectId the object identifier. + * @param rawData the raw instrumentation data. + */ + void addConfigurationData (Binary objectId, byte[] rawData); + + /** + * Inject the schema into this class definition. + * + * @param propertyDefinitions + * @param statisticDefinitions + * @param methodDefinitions + * @throws UnableToBuildFeatureException when it's not possibile to parse schema and build the class definition. + */ + public void setSchema ( + List<Map<String, Object>> propertyDefinitions, + List<Map<String, Object>> statisticDefinitions, + List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException; + }; + + /** + * This is the initial state of every qpid class. + * The class definition instance is created but its schema has not been injected. + * Incoming configuration & instrumentation data will be stored in raw format because we don't know how to + * parse it until the schema arrives. + * In addition, this state is responsible (when data arrives) to request its schema. + */ + final State _schemaNotRequested = new State() { + + /** + * Stores the incoming data in raw format and request the schema for this class. + * After that a transition to the next state is made. + * + * @param objectId the object instance identifier. + * @param rawData incoming configuration data. + */ + public synchronized void addConfigurationData (Binary objectId, byte[] rawData) + { + try + { + requestSchema(); + _state = _schemaRequestedButNotYetInjected; + } catch (Exception e) + { + _logger.error( + Messages.QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST, + _parent.getName(), + _name); + } finally { + QpidManagedObject instance = getObjectInstance(objectId,false); + instance._rawConfigurationData.add(rawData); + } + } + + /** + * Stores the incoming data in raw format and request the schema for this class. + * After that a transition to the next state is made. + * + * @param objectId the object instance identifier. + * @param rawData incoming instrumentation data. + */ + public synchronized void addInstrumentationData (Binary objectId, byte[] rawData) + { + try + { + requestSchema(); + _state = _schemaRequestedButNotYetInjected; + } catch (Exception e) + { + _logger.error( + Messages.QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST, + _parent.getName(), + _name); + } finally { + QpidManagedObject instance = getObjectInstance(objectId,false); + instance._rawConfigurationData.add(rawData); + } + } + + /** + * This method only throws an illegal state exception because when a schema arrives + * this state is no longer valid. + */ + public void setSchema ( + List<Map<String, Object>> propertyDefinitions, + List<Map<String, Object>> statisticDefinitions, + List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException + { + throw new IllegalStateException("When a schema arrives it's not possible for this class to be in this state."); + } + }; + + /** + * This is the first state of this class definition : the schema is not yet injected so each injection of object data will be + * retained in raw format. + */ + final State _schemaRequestedButNotYetInjected = new State() + { + /** + * Stores the incoming data in raw format. + * + * @param objectId the object instance identifier. + * @param rawData incoming configuration data. + */ + public void addConfigurationData (Binary objectId, byte[] rawData) + { + QpidManagedObject instance = getObjectInstance(objectId,false); + instance._rawConfigurationData.add(rawData); + } + + /** + * Stores the incoming data in raw format. + * + * @param objectId the object instance identifier. + * @param rawData incoming instrumentation data. + */ + public void addInstrumentationData (Binary objectId, byte[] rawData) + { + QpidManagedObject instance = getObjectInstance(objectId,false); + instance._rawInstrumentationData.add(rawData); + } + + /** + * When a schema is injected into this defintiion the following should happen : + * 1) the incoming schema is parsed and the class definition is built; + * 2) the retained raw data is converted into object instance(s) + * 3) the internal state of this class changes; + * + * If someting is wrong during that process the schema is not built and the state don't change. + */ + public synchronized void setSchema ( + List<Map<String, Object>> propertyDefinitions, + List<Map<String, Object>> statisticDefinitions, + List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException + { + + MBeanAttributeInfo [] attributesMetadata = new MBeanAttributeInfo[propertyDefinitions.size()+statisticDefinitions.size()]; + MBeanOperationInfo [] operationsMetadata = new MBeanOperationInfo[methodDefinitions.size()]; + + buildAttributes(propertyDefinitions,statisticDefinitions,attributesMetadata); + buildMethods(methodDefinitions,operationsMetadata); + + _metadata = new MBeanInfo(_name,_name,attributesMetadata,null,operationsMetadata,null); + + // Converting stored object instances into JMX MBean and removing raw instance data. + for (Entry<Binary, QpidManagedObject> instanceEntry : _objectInstances.entrySet()) + { + Binary objectId = instanceEntry.getKey(); + QpidManagedObject instance = instanceEntry.getValue(); + + for (Iterator<byte[]> iterator = instance._rawInstrumentationData.iterator(); iterator.hasNext();) + { + updateInstanceWithInstrumentationData(instance,iterator.next()); + iterator.remove(); + } + + for (Iterator<byte[]> iterator = instance._rawConfigurationData.iterator(); iterator.hasNext();) + { + updateInstanceWithConfigurationData(instance, iterator.next()); + iterator.remove(); + } + + JMX_SERVICE.registerObjectInstance(instance,_parent.getOwnerId(),_parent.getName(),_name,objectId); + } + _state = _schemaInjected; + } + }; + + /** + * After a schema is built into this definition this is the current state of the class. + */ + final State _schemaInjected = new State() + { + /** + * Updates the configuration state of the object instance associates with the given object identifier. + * + * @param objectId the object identifier. + * @param rawData the configuration data (raw format). + */ + public void addConfigurationData (Binary objectId, byte[] rawData) + { + QpidManagedObject instance = getObjectInstance(objectId,true); + updateInstanceWithConfigurationData(instance, rawData); + } + + /** + * Updates the instrumentation state of the object instance associates with the given object identifier. + * + * @param objectId the object identifier. + * @param rawData the instrumentation data (raw format). + */ + public void addInstrumentationData (Binary objectId, byte[] rawData) + { + QpidManagedObject instance = getObjectInstance(objectId,true); + updateInstanceWithInstrumentationData(instance, rawData); + } + + /** + * Never called when the class definition has this state. + */ + public void setSchema ( + List<Map<String, Object>> propertyDefinitions, + List<Map<String, Object>> statisticDefinitions, + List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException + { + throw new IllegalStateException("When a schema arrives it's not possible for this class to be in this state."); + } + }; + + /** + * MBean used for representing remote broker object instances. + * This is the core component of the QMan domain model + * + * @author Andrea Gazzarini + */ + class QpidManagedObject extends QpidManagedEntity implements MBeanRegistration + { + private Binary _objectId; + + // Arrays used for storing raw data before this mbean is registered to mbean server. + List<byte[]> _rawInstrumentationData = new ArrayList<byte[]>(); + List<byte[]> _rawConfigurationData = new ArrayList<byte[]>(); + + /** + * Builds a new managed object with the given object identifier. + * + * @param objectId the object identifier. + */ + QpidManagedObject(Binary objectId) + { + this._objectId = objectId; + } + + /** + * Returns the value of the given attribute.s + * + * @throws AttributeNotFoundException when no attribute is found with the given name. + */ + public Object getAttribute (String attributeName) throws AttributeNotFoundException, MBeanException, ReflectionException + { + if (attributeName == null) + { + throw new RuntimeOperationsException(new IllegalArgumentException("attribute name must not be null")); + } + + if (_properties.containsKey(attributeName) || _statistics.containsKey(attributeName)) + { + return _attributes.get(attributeName); + } else + { + throw new AttributeNotFoundException(attributeName); + } + } + + /** + * Executes an operation on this object instance. + * + * @param actionName the name of the method. + * @param params the method parameters + * @param signature the method signature. + */ + public Object invoke (String actionName, Object[] params, String[] signature) throws MBeanException,ReflectionException + { + // TODO : Overloaded methods + QpidMethod method = _methods.get(actionName); + if (method != null) + { + try + { + method.validate(params); + return invokeMethod(_objectId, method, params); + } catch (Exception exception) + { + throw new MBeanException(exception); + } + } else { + throw new ReflectionException(new NoSuchMethodException(actionName)); + } + } + + /** + * Sets the value of the given attribute on this object instance. + * + * @param attribute contains the new value of the attribute. + * @throws AttributeNotFoundException when the given attribute is not found on this object instance. + * @throws InvalidAttributeValueException when the given value is violating one attribute invariant. + */ + public void setAttribute (Attribute attribute) throws AttributeNotFoundException, + InvalidAttributeValueException, MBeanException, ReflectionException + { + QpidProperty property = _properties.get(attribute.getName()); + try + { + property.validate(attribute.getValue()); + } catch(ValidationException exception) + { + throw new InvalidAttributeValueException(exception.getMessage()); + } + throw new RuntimeException("Not yet implemented."); + } + + /** + * Sets the values of several attributes of this MBean. + * + * @param attributes a list of attributes: The identification of the attributes to be set and the values they are to be set to. + * @return The list of attributes that were set, with their new values. + */ + public AttributeList setAttributes (AttributeList attributes) + { + throw new RuntimeException("Not yet implemented."); + } + + /** + * MBean server callback after deregistration. + */ + public void postDeregister () + { + } + + /** + * After the object is registered the raw data is set to null. + * This is done because we no longer need this data : it has already been + * injected into this object instance. + * + * @param registrationDone a flag indicating if the instance has been registered to mbean server. + */ + public void postRegister (Boolean registrationDone) + { + if (registrationDone) + { + _rawConfigurationData = null; + _rawInstrumentationData = null; + } + } + + /** + * MBean server callback before deregistration. + */ + public void preDeregister () throws Exception + { + } + + /** + * MBean server callback before registration. + */ + public ObjectName preRegister (MBeanServer server, ObjectName name) throws Exception + { + return name; + } + } + + Map<String, QpidProperty> _properties = new HashMap<String, QpidProperty>(); + Map<String, QpidStatistic> _statistics = new HashMap<String, QpidStatistic>(); + private Map<String, QpidMethod> _methods = new HashMap<String, QpidMethod>(); + + private List<QpidProperty> _schemaOrderedProperties = new ArrayList<QpidProperty>(); + private List<QpidStatistic> _schemaOrderedStatistics= new ArrayList<QpidStatistic>(); + + private int _howManyPresenceBitMasks; + private BlockingQueue<InvocationResult> _exchangeChannelForMethodInvocations; + private final IMethodInvocationListener _methodInvocationListener; + + Map<Binary, QpidManagedObject> _objectInstances = new HashMap<Binary, QpidManagedObject>(); + State _state = _schemaNotRequested;; + + private final static class Log + { + private final static Logger LOGGER = Logger.get(QpidClass.class); + final static void logMethodInvocationResult(InvocationResult result) + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug(String.valueOf(result)); + } + } + } + + /** + * Builds a new class with the given name and package as parent. + * + * @param className the name of the class. + * @param hash the class schema hash. + * @param parentPackage the parent of this class. + */ + QpidClass(String className, Binary hash, QpidPackage parentPackage) + { + super(className,hash, parentPackage); + this._methodInvocationListener = _parent.getMethodInvocationListener(); + this._exchangeChannelForMethodInvocations = new SynchronousQueue<InvocationResult>(); + } + + /** + * Adds the configuration data for the object instance associated to the given object identifier. + * + * @param objectId the object identifier. + * @param rawData the raw configuration data. + */ + void addInstrumentationData (Binary objectId, byte[] rawData) + { + _logger.debug( + Messages.QMAN_200014_INCOMING_INSTRUMENTATION_DATA, + _parent.getOwnerId(), + _parent.getName(), + _name, + objectId); + _state.addInstrumentationData(objectId, rawData); + } + + /** + * Adds the instrumentation data for the object instance associated to the given object identifier. + * + * @param objectId the object identifier. + * @param rawData the raw instrumentation data. + */ + void addConfigurationData (Binary objectId, byte[] rawData) + { + _logger.debug( + Messages.QMAN_200015_INCOMING_CONFIGURATION_DATA, + _parent.getOwnerId(), + _parent.getName(), + _name, + objectId); + _state.addConfigurationData(objectId, rawData); + } + + /** + * Sets the schema for this class definition. + * A schema is basically a metadata description of all properties, statistics, methods and events of this class. + * + * @param propertyDefinitions properties metadata. + * @param statisticDefinitions statistics metadata. + * @param methodDefinitions methods metadata. + * @throws UnableToBuildFeatureException when some error occurs while parsing the incoming schema. + */ + void setSchema ( + List<Map<String, Object>> propertyDefinitions, + List<Map<String, Object>> statisticDefinitions, + List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException + { + _logger.info(Messages.QMAN_000010_INCOMING_SCHEMA,_parent.getOwnerId(),_parent.getName(),_name); + _state.setSchema(propertyDefinitions, statisticDefinitions, methodDefinitions); + } + + /** + * Internal method used for building attributes definitions. + * + * @param props the map contained in the properties schema. + * @param stats the map contained in the statistics schema. + * @param attributes the management metadata for attributes. + * @throws UnableToBuildFeatureException when it's not possibile to build one attribute definition. + */ + void buildAttributes ( + List<Map<String, Object>> props, + List<Map<String, Object>> stats, + MBeanAttributeInfo[] attributes) throws UnableToBuildFeatureException + { + int index = 0; + int howManyOptionalProperties = 0; + + for (Map<String, Object> propertyDefinition : props) + { + QpidFeatureBuilder builder = QpidFeatureBuilder.createPropertyBuilder(propertyDefinition); + builder.build(); + + QpidProperty property = (QpidProperty) builder.getQpidFeature(); + + howManyOptionalProperties += (property.isOptional()) ? 1 : 0; + + _properties.put(property.getName(),property); + _schemaOrderedProperties.add(property); + attributes[index++]=(MBeanAttributeInfo) builder.getManagementFeature(); + + _logger.debug( + Messages.QMAN_200016_PROPERTY_DEFINITION_HAS_BEEN_BUILT, + _parent.getName(), + _name, + property); + } + + _howManyPresenceBitMasks = (int)Math.ceil((double)howManyOptionalProperties / 8); + + _logger.debug( + Messages.QMAN_200018_OPTIONAL_PROPERTIES_INFO, + _parent.getOwnerId(), + _parent.getName(), + _name, + _howManyPresenceBitMasks); + + for (Map<String, Object> statisticDefinition : stats) + { + QpidFeatureBuilder builder = QpidFeatureBuilder.createStatisticBuilder(statisticDefinition); + builder.build(); + QpidStatistic statistic = (QpidStatistic) builder.getQpidFeature(); + + _statistics.put(statistic.getName(),statistic); + _schemaOrderedStatistics.add(statistic); + attributes[index++]=(MBeanAttributeInfo) builder.getManagementFeature(); + + _logger.debug( + Messages.QMAN_200017_STATISTIC_DEFINITION_HAS_BEEN_BUILT, + _parent.getName(), + _name, + statistic); + } + } + + /** + * Returns the object instance associated to the given identifier. + * Note that if the identifier is not associated to any obejct instance, a new one will be created. + * + * @param objectId the object identifier. + * @param registration a flag indicating whenever the (new ) instance must be registered with MBean server. + * @return the object instance associated to the given identifier. + */ + QpidManagedObject getObjectInstance(Binary objectId, boolean registration) + { + QpidManagedObject objectInstance = _objectInstances.get(objectId); + if (objectInstance == null) + { + objectInstance = new QpidManagedObject(objectId); + _objectInstances.put(objectId, objectInstance); + if (registration) + { + JMX_SERVICE.registerObjectInstance(objectInstance,_parent.getOwnerId(),_parent.getName(),_name,objectId); + } + } + return objectInstance; + } + + /** + * Internal method used for building method defintiions. + * + * @param definitions the properties map contained in the incoming schema. + * @param operationsMetadata + * @throws UnableToBuildFeatureException when it's not possibile to build one or more definitions. + */ + void buildMethods (List<MethodOrEventDataTransferObject> definitions, MBeanOperationInfo[] operationsMetadata) throws UnableToBuildFeatureException + { + int index = 0; + for (MethodOrEventDataTransferObject definition: definitions) + { + QpidFeatureBuilder builder = QpidFeatureBuilder.createMethodBuilder(definition); + builder.build(); + operationsMetadata [index++]= (MBeanOperationInfo) builder.getManagementFeature(); + QpidMethod method = (QpidMethod) builder.getQpidFeature(); + _methods.put(method.getName(),method); + } + } + + /** + * Header (opcode='M') + * ObjectId of target object (128 bits) + * Package name (str8) + * Class name (str8) + * Class hash (bin128) + * Method name (str8) [as defined in the schema] + * Now encode all input ("I") and i/o (IO) arguments in the order in which they are defined in the schema. + * (i.e. make one pass over the argument list and encode arguments that are either input or inptu/output). + + * @param objectId + * @param method + * @param parameters + * @throws Exception + */ + private InvocationResult invokeMethod(Binary objectId,QpidMethod method,Object [] parameters) throws Exception + { + try + { + _service.connect(); + + int sequenceNumber = SequenceNumberGenerator.getNextSequenceNumber(); + _methodInvocationListener.operationIsGoingToBeInvoked(new InvocationEvent(this,sequenceNumber,_exchangeChannelForMethodInvocations)); + _service.invoke(_parent.getName(), _name, _hash,objectId,parameters, method,sequenceNumber,objectId.getBankId(),objectId.getBrokerId()); + + InvocationResult result = _exchangeChannelForMethodInvocations.poll(5000,TimeUnit.MILLISECONDS); + + if (result == null) + { + throw new TimeoutException(); + } + + Map<String, Object> output = method.decodeParameters(result.getOutputAndBidirectionalArgumentValues()); + result.setOutputSection(output); + + Log.logMethodInvocationResult(result); + + if (result.isException()) + { + result.createAndThrowException(); + } + return result; + } finally + { + _service.close(); + } + } + + /** + * Updates the given obejct instance with the given incoming configuration data. + * + * @param instance the managed object instance. + * @param rawData the incoming configuration data which contains new values for instance properties. + */ + void updateInstanceWithConfigurationData(QpidManagedObject instance,byte [] rawData) + { + BBDecoder decoder = new BBDecoder(); + decoder.init(ByteBuffer.wrap(rawData)); + + byte [] presenceBitMasks = decoder.readBytes(_howManyPresenceBitMasks); + for (QpidProperty property : _schemaOrderedProperties) + { + try { + Object value = property.decodeValue(decoder,presenceBitMasks); + instance.createOrReplaceAttributeValue(property.getName(),value); + } catch(Exception ignore) { + _logger.error(Messages.QMAN_100016_UNABLE_TO_DECODE_FEATURE_VALUE, _parent.getName(),_name,property.getName()); + } + } + } + + /** + * Updates the given object instance with the given incoming instrumentation data. + * + * @param instance the managed object instance. + * @param rawData the incoming instrumentation data which contains new values for instance properties. + */ + void updateInstanceWithInstrumentationData(QpidManagedObject instance,byte [] rawData) + { + BBDecoder decoder = new BBDecoder(); + decoder.init(ByteBuffer.wrap(rawData)); + + for (QpidStatistic statistic : _schemaOrderedStatistics) + { + try { + Object value = statistic.decodeValue(decoder); + instance.createOrReplaceAttributeValue(statistic.getName(),value); + } catch(Exception ignore) { + _logger.error(Messages.QMAN_100016_UNABLE_TO_DECODE_FEATURE_VALUE, _parent.getName(),_name,statistic.getName()); + } + } + } + + @Override + public String toString () + { + return new StringBuilder() + .append(_parent.getOwnerId()) + .append("::") + .append(_parent.getName()) + .append('.') + .append(_name) + .toString(); + } + + /** + * Removes the object instance associated to the given identifier. + * + * @param objectId the object identifier. + */ + void removeObjectInstance (Binary objectId) + { + QpidManagedObject toBeRemoved = _objectInstances.remove(objectId); + if (toBeRemoved != null) + { + JMX_SERVICE.unregisterObjectInstance(_parent.getOwnerId(),_parent.getName(),_name,toBeRemoved._objectId); + } + } + + /** + * Deregisters all the object instances and release all previously acquired resources. + */ + void releaseResources () + { + _objectInstances.clear(); + JMX_SERVICE.unregisterObjectInstances(); + _service.close(); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java new file mode 100644 index 0000000000..59f8d807b2 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java @@ -0,0 +1,158 @@ +/*
+*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.management.domain.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.DynamicMBean;
+import javax.management.MBeanInfo;
+import javax.management.RuntimeOperationsException;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.management.domain.services.QpidService;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Layer supertype for QMan entities.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class QpidEntity
+{
+ /**
+ * Layer supertype for QMan managed bean entities.
+ *
+ * @author Andrea Gazzarini
+ */
+ abstract class QpidManagedEntity implements DynamicMBean
+ {
+ // After mbean is registered with the MBean server this collection holds the mbean attribute values.
+ Map<String,Object> _attributes = new HashMap<String, Object>();
+
+ /**
+ * Creates or replace the given attribute.
+ * Note that this is not part of the management interface of this object instance and therefore will be accessible only
+ * from within this class.
+ * It is used to update directly the object attributes bypassing jmx interface.
+ *
+ * @param attributeName the name of the attribute.
+ * @param property newValue the new value of the attribute.
+ */
+ void createOrReplaceAttributeValue(String attributeName, Object newValue)
+ {
+ _attributes.put(attributeName, newValue);
+ }
+
+ /**
+ * Get the values of several attributes of the Dynamic MBean.
+ *
+ * @param attributes A list of the attributes to be retrieved.
+ *
+ * @return The list of attributes retrieved.
+ */
+ public AttributeList getAttributes (String[] attributes)
+ {
+ if (attributes == null)
+ {
+ throw new RuntimeOperationsException(new IllegalArgumentException("Attributes array must not be null"));
+ }
+
+ AttributeList result = new AttributeList(attributes.length);
+ for (int i = 0; i < attributes.length; i++)
+ {
+ String attributeName = attributes[i];
+ try
+ {
+ result.add(new Attribute(attributeName,getAttribute(attributeName)));
+ } catch(Exception exception)
+ {
+ // Already logged.
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns metadata for this object instance.
+ */
+ // Developer Note : note that this metadata is a member of the outer class definition : in that way we create
+ // that metadata only once and then it will be shared between all object instances (it's a readonly object)
+ public MBeanInfo getMBeanInfo ()
+ {
+ return _metadata;
+ }
+ };
+
+ final Logger _logger = Logger.get(getClass());
+ final static JmxService JMX_SERVICE = new JmxService();
+
+ final String _name;
+ final Binary _hash;
+
+ final QpidPackage _parent;
+ MBeanInfo _metadata;
+
+ final QpidService _service;
+
+ /**
+ * Builds a new class with the given name and package as parent.
+ *
+ * @param className the name of the class.
+ * @param hash the class schema hash.
+ * @param parentPackage the parent of this class.
+ */
+ QpidEntity(String className, Binary hash, QpidPackage parentPackage)
+ {
+ this._name = className;
+ this._parent = parentPackage;
+ this._hash = hash;
+ this._service = new QpidService(_parent.getOwnerId());
+
+ _logger.debug(
+ Messages.QMAN_200020_ENTITY_DEFINITION_HAS_BEEN_BUILT,
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name);
+ }
+
+ /**
+ * Internal method used to send a schema request for this entity.
+ *
+ * @throws Exception when the request cannot be sent.
+ */
+ void requestSchema() throws Exception
+ {
+ try
+ {
+ _service.connect();
+ _service.requestSchema(_parent.getName(), _name, _hash);
+ _service.sync();
+ } finally
+ {
+ _service.close();
+ }
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java new file mode 100644 index 0000000000..273ae650c1 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java @@ -0,0 +1,456 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.InvalidAttributeValueException; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.ReflectionException; +import javax.management.RuntimeOperationsException; + +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.domain.model.type.Binary; +import org.apache.qpid.transport.codec.BBDecoder; + +/** + * Qpid event definition. + * + * @author Andrea Gazzarini + */ +class QpidEvent extends QpidEntity +{ + + /** + * State interface for this event definition. + * Each state is responsible to handle the injection of the data and / or schema. + * + * @author Andrea Gazzarini + */ + interface State + { + /** + * Adds the given data for the object instance associated to the given object identifier. + * + * @param rawData the raw configuration data. + */ + void addNewEventData (byte[] rawData, long currentTimestamp, int severity); + + /** + * Inject the schema into this class definition. + * + * @param propertyDefinitions + * @param statisticDefinitions + * @param methodDefinitions + * @throws UnableToBuildFeatureException when it's not possibile to parse schema and build the class definition. + */ + public void setSchema (List<Map<String, Object>> agumentDefinitions) throws UnableToBuildFeatureException; + }; + + + /** + * This is the initial state of every qpid class. + * The class definition instance is created but its schema has not been injected. + * Incoming configuration & instrumentation data will be stored in raw format because we don't know how to + * parse it until the schema arrives. + * In addition, this state is responsible (when data arrives) to request its schema. + */ + final State _schemaNotRequested = new State() { + + /** + * Stores the incoming data in raw format and request the schema for this class. + * After that a transition to the next state is made. + * + * @param objectId the object instance identifier. + * @param rawData incoming configuration data. + */ + public synchronized void addNewEventData (byte[] rawData, long currentTimestamp, int severity) + { + try + { + requestSchema(); + _state = _schemaRequestedButNotYetInjected; + } catch (Exception e) + { + _logger.error( + Messages.QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST, + _parent.getName(), + _name); + } finally { + createEventInstance(rawData,currentTimestamp,severity); + } + } + + /** + * This method only throws an illegal state exception because when a schema arrives + * this state is no longer valid. + */ + public void setSchema (List<Map<String, Object>> agumentDefinitions) throws UnableToBuildFeatureException + { + throw new IllegalStateException("When a schema arrives it's not possible for this class to be in this state."); + } + }; + + /** + * This is the first state of this class definition : the schema is not yet injected so each injection of object data will be + * retained in raw format. + */ + final State _schemaRequestedButNotYetInjected = new State() + { + /** + * Stores the incoming data in raw format and request the schema for this class. + * After that a transition to the next state is made. + * + * @param objectId the object instance identifier. + * @param rawData incoming configuration data. + */ + public synchronized void addNewEventData (byte[] rawData,long currentTimestamp, int severity) + { + createEventInstance(rawData,currentTimestamp, severity); + } + + /** + * When a schema is injected into this defintiion the following should happen : + * 1) the incoming schema is parsed and the class definition is built; + * 2) the retained raw data is converted into object instance(s) + * 3) the internal state of this class changes; + * + * If someting is wrong during that process the schema is not built and the state don't change. + */ + public synchronized void setSchema (List<Map<String, Object>> argumentDefinitions) throws UnableToBuildFeatureException + { + MBeanAttributeInfo [] attributesMetadata = new MBeanAttributeInfo[argumentDefinitions.size()+2]; + + buildArguments(argumentDefinitions, attributesMetadata); + + _metadata = new MBeanInfo(_name,_name,attributesMetadata,null,null,null); + + // Converting stored object instances into JMX MBean and removing raw instance data. + for (QpidManagedEvent instance : _eventInstances) + { + updateEventInstanceWithData(instance); + JMX_SERVICE.registerEventInstance(instance,_parent.getOwnerId(),_parent.getName(),_name); + } + _state = _schemaInjected; + } + }; + + /** + * After a schema is built into this definition this is the current state of the class. + */ + final State _schemaInjected = new State() + { + /** + * Updates the configuration state of the object instance associates with the given object identifier. + * + * @param objectId the object identifier. + * @param rawData the configuration data (raw format). + */ + public void addNewEventData (byte[] rawData,long currentTimestamp, int severity) + { + QpidManagedEvent instance = createEventInstance(rawData,currentTimestamp, severity); + updateEventInstanceWithData(instance); + JMX_SERVICE.registerEventInstance(instance,_parent.getOwnerId(),_parent.getName(),_name); + } + + /** + * Never called when the class definition has this state. + */ + public void setSchema (List<Map<String, Object>> agumentDefinitions) throws UnableToBuildFeatureException + { + // N.A. : Schema is already injected. + } + }; + + /** + * MBean used for representing remote broker object instances. + * This is the core component of the QMan domain model + * + * @author Andrea Gazzarini + */ + class QpidManagedEvent extends QpidManagedEntity + { + + + // Arrays used for storing raw data before this mbean is registered to mbean server. + final byte[] _rawEventData; + final long _timestamp; + final int _severity; + + /** + * Builds a new managed object with the given object identifier. + * + * @param objectId the object identifier. + */ + private QpidManagedEvent(byte [] data, long timestamp, int severity) + { + this._rawEventData = data; + this._timestamp = timestamp; + this._severity = severity; + _attributes.put(SEVERITY_ATTR_NAME, _severity); + _attributes.put(TIMESTAMP_ATTR_NAME, new Date(_timestamp)); + } + + /** + * Returns the value of the given attribute.s + * + * @throws AttributeNotFoundException when no attribute is found with the given name. + */ + public Object getAttribute (String attributeName) throws AttributeNotFoundException, MBeanException, ReflectionException + { + if (attributeName == null) + { + throw new RuntimeOperationsException(new IllegalArgumentException("Attribute name must not be null.")); + } + + if (_arguments.containsKey(attributeName) || SEVERITY_ATTR_NAME.equals(attributeName) || TIMESTAMP_ATTR_NAME.equals(attributeName)) + { + return _attributes.get(attributeName); + } else + { + throw new AttributeNotFoundException(attributeName); + } + } + + /** + * Executes an operation on this object instance. + * + * @param actionName the name of the method. + * @param params the method parameters + * @param signature the method signature. + */ + public Object invoke (String actionName, Object[] params, String[] signature) throws MBeanException,ReflectionException + { + throw new ReflectionException(new NoSuchMethodException(actionName)); + } + + /** + * Sets the value of the given attribute on this object instance. + * + * @param attribute contains the new value of the attribute. + * @throws AttributeNotFoundException when the given attribute is not found on this object instance. + * @throws InvalidAttributeValueException when the given value is violating one attribute invariant. + */ + public void setAttribute (Attribute attribute) throws AttributeNotFoundException, + InvalidAttributeValueException, MBeanException, ReflectionException + { + throw new ReflectionException(new NoSuchMethodException()); + } + + /** + * Sets the values of several attributes of this MBean. + * + * @param attributes a list of attributes: The identification of the attributes to be set and the values they are to be set to. + * @return The list of attributes that were set, with their new values. + */ + public AttributeList setAttributes (AttributeList attributes) + { + throw new RuntimeException(); + } + } + + final static String SEVERITY_ATTR_NAME = "Severity"; + final static String TIMESTAMP_ATTR_NAME = "Date"; + + private List<QpidProperty> _schemaOrderedArguments = new ArrayList<QpidProperty>(); + + Map<String, QpidProperty> _arguments = new HashMap<String, QpidProperty>(); + List<QpidManagedEvent> _eventInstances = new LinkedList<QpidManagedEvent>(); + State _state = _schemaNotRequested;; + + /** + * Builds a new class with the given name and package as parent. + * + * @param className the name of the class. + * @param hash the class schema hash. + * @param parentPackage the parent of this class. + */ + QpidEvent(String eventClassName, Binary hash, QpidPackage parentPackage) + { + super(eventClassName,hash,parentPackage); + } + + /** + * Adds the configuration data for the object instance associated to the given object identifier. + * + * @param objectId the object identifier. + * @param rawData the raw configuration data. + */ + void addEventData (byte[] rawData, long currentTimestamp, int severity) + { + _logger.debug( + Messages.QMAN_200021_INCOMING_EVENT_DATA, + _parent.getOwnerId(), + _parent.getName(), + _name); + _state.addNewEventData(rawData, currentTimestamp, severity); + } + + /** + * Sets the schema for this class definition. + * A schema is basically a metadata description of all properties, statistics, methods and events of this class. + * + * @param propertyDefinitions properties metadata. + * @param statisticDefinitions statistics metadata. + * @param methodDefinitions methods metadata. + * @throws UnableToBuildFeatureException when some error occurs while parsing the incoming schema. + */ + void setSchema (List<Map<String, Object>> argumentDefinitions) throws UnableToBuildFeatureException + { + _logger.info(Messages.QMAN_000010_INCOMING_SCHEMA,_parent.getOwnerId(),_parent.getName(),_name); + _state.setSchema(argumentDefinitions); + } + + /** + * Internal method used for building attributes definitions. + * + * @param props the map contained in the properties schema. + * @param stats the map contained in the statistics schema. + * @param attributes the management metadata for attributes. + * @throws UnableToBuildFeatureException when it's not possibile to build one attribute definition. + */ + void buildArguments ( + List<Map<String, Object>> arguments,MBeanAttributeInfo[] attributes) throws UnableToBuildFeatureException + { + int index = 0; + + for (Map<String, Object> argumentDefinition : arguments) + { + // Force metadata attributes. It is needed because arguments are "similar" to properties but they + // aren't properties and then they haven't optional, index and access metadata attributes + // (mandatory for build a property definition). + argumentDefinition.put(QpidFeatureBuilder.Attribute.optional.name(),0); + argumentDefinition.put(QpidFeatureBuilder.Attribute.index.name(),1); + argumentDefinition.put(QpidFeatureBuilder.Attribute.access.name(),3); + + QpidFeatureBuilder builder = QpidFeatureBuilder.createPropertyBuilder(argumentDefinition); + builder.build(); + + QpidProperty argument = (QpidProperty) builder.getQpidFeature(); + + _arguments.put(argument.getName(),argument); + _schemaOrderedArguments.add(argument); + attributes[index++]=(MBeanAttributeInfo) builder.getManagementFeature(); + + _logger.debug( + Messages.QMAN_200019_EVENT_ARGUMENT_DEFINITION_HAS_BEEN_BUILT, + _parent.getName(), + _name, + argument); + } + + attributes[index++] = new MBeanAttributeInfo( + SEVERITY_ATTR_NAME, + Integer.class.getName(), + Messages.EVENT_SEVERITY_ATTRIBUTE_DESCRIPTION, + true, + false, + false); + + attributes[index++] = new MBeanAttributeInfo( + TIMESTAMP_ATTR_NAME, + Date.class.getName(), + Messages.EVENT_TIMESTAMP_ATTRIBUTE_DESCRIPTION, + true, + false, + false); + } + + /** + * Returns the object instance associated to the given identifier. + * Note that if the identifier is not associated to any obejct instance, a new one will be created. + * + * @param objectId the object identifier. + * @param registration a flag indicating whenever the (new ) instance must be registered with MBean server. + * @return the object instance associated to the given identifier. + */ + QpidManagedEvent createEventInstance(byte [] data, long timestamp, int severity) + { + QpidManagedEvent eventInstance = new QpidManagedEvent(data, timestamp, severity); + _eventInstances.add(eventInstance); + return eventInstance; + } + + /** + * Updates the given obejct instance with the given incoming configuration data. + * + * @param instance the managed object instance. + * @param rawData the incoming configuration data which contains new values for instance properties. + */ + void updateEventInstanceWithData(QpidManagedEvent instance) + { + BBDecoder decoder = new BBDecoder(); + decoder.init(ByteBuffer.wrap(instance._rawEventData)); + + for (QpidProperty property : _schemaOrderedArguments) + { + try { + Object value = property.decodeValue(decoder); + instance.createOrReplaceAttributeValue(property.getName(),value); + } catch(Exception ignore) { + _logger.error(Messages.QMAN_100016_UNABLE_TO_DECODE_FEATURE_VALUE, _parent.getName(),_name,property.getName()); + } + } + } + + @Override + public String toString () + { + return new StringBuilder() + .append(_parent.getOwnerId()) + .append("::") + .append(_parent.getName()) + .append(".") + .append(_name) + .toString(); + } + + /** + * Deregisters all the object instances and release all previously acquired resources. + */ + void releaseResources () + { + _eventInstances.clear(); + JMX_SERVICE.unregisterEvents(); + _service.close(); + } + + /** + * Checks if this event definition contains event instance(s). + * + * @return true if there is one or more managed instances. + */ + boolean hasNoInstances() + { + return _eventInstances.isEmpty(); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java new file mode 100644 index 0000000000..e1ca5a4d42 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java @@ -0,0 +1,88 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +/** + * Layer Supertype for all qpid management features. + * + * @author Andrea Gazzarini + */ +abstract class QpidFeature +{ + /** The name of the feature. */ + protected String _name; + + /** + * The description of the feature. + */ + protected String _description; + + /** + * Returns the description of this feature. + * + * @return the description of this feature. + */ + String getDescription () + { + return _description; + } + + /** + * Sets the description for this feature. + * + * @param description the description for this feature. + */ + void setDescription (String description) + { + this._description = description; + } + + /** + * Returns the name of the feature. + * + * @return the name of the feature. + */ + public String getName () + { + return _name; + } + + /** + * Sets the name for this feature. + * + * @param name the name of this feature. + */ + void setName (String name) + { + this._name = name; + } + + /** + * Returns the name of the feature. + * + * @return the name of the feature. + */ + @Override + public String toString () + { + return _name; + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java new file mode 100644 index 0000000000..d0862c15ca --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java @@ -0,0 +1,454 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanFeatureInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanParameterInfo; + +import org.apache.qpid.management.configuration.Configuration; +import org.apache.qpid.management.configuration.UnknownTypeCodeException; +import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject; +import org.apache.qpid.management.Names; + +/** + * A builder used to parse incoming schema message and therefore to build a feature (property, statistic, method, event) + * definition. + * In order to set up the correct state for this builder, clients must create an instance of this class + * The product of the builder will be a QpidFeature and a JMX Managemtn feature used for describing that feature in a + * JMX environment. So, for example, for building a property definition client code should be : + * + * <br>- QpidFeatureBuilder builder = QpidFeature.createPropertyBuilder(...); + * <br>- builder.build(); + * <br>- QpidProperty property = (QpidProperty) builder.getQpidFeature(); + * <br>- MBeanAttributeInfo managementAttributeInfo = (MBeanAttributeInfo)builder.getManagementFeature(); + * + * <br>N.B.: a builder instance is not supposed to be reused. One instance for one feature! + * + * @author Andrea Gazzarini + */ +class QpidFeatureBuilder +{ + + static enum Attribute { + name,type,access,index,optional,unit,min,max,maxlen,desc,dir,argCount; + }; + + private List<Attribute> _mandatoryAttributes = new ArrayList<Attribute>(); + + /** + * Builder state for this class. + * Each concrete implementor is a builder for a specific feature. + * using the appropriate factory method. + * + * @author Andrea Gazzarini + */ + interface State { + void build() throws UnableToBuildFeatureException; + } + + /** + * Builder used for building property definition. + */ + final State _propertyBuilder = new State() { + + /** + * Builds a property definition as well a management attribute feature. + */ + public void build () throws UnableToBuildFeatureException + { + QpidProperty property = new QpidProperty(); + try { + int optionalIndex = 0; + for (Entry<String, Object> propertyAttribute : _featureDefinition.entrySet()) + { + Attribute attribute = Attribute.valueOf(propertyAttribute.getKey()); + switch(attribute) + { + case name : + { + property.setName(String.valueOf(propertyAttribute.getValue())); + break; + } + case access : + { + int code = (Integer)propertyAttribute.getValue(); + property.setAccessMode(Configuration.getInstance().getAccessMode(code)); + break; + } + case unit : + { + property.setUnit(String.valueOf(propertyAttribute.getValue())); + break; + } + case min : + { + property.setMinValue((Integer)propertyAttribute.getValue()); + break; + } + case max : + { + property.setMaxValue((Integer)propertyAttribute.getValue()); + break; + } + case maxlen : + { + property.setMaxLength((Integer)propertyAttribute.getValue()); + break; + } + case desc : + { + property.setDescription(String.valueOf(propertyAttribute.getValue())); + break; + } + case type : + { + int code = (Integer) propertyAttribute.getValue(); + property.setType(Configuration.getInstance().getType(code)); + break; + } + case index : + { + break; + } + case optional : + { + int code = (Integer) propertyAttribute.getValue(); + if (code == 1) + { + property.markAsOptional(optionalIndex); + optionalIndex++; + } + break; + } + } + _mandatoryAttributes.remove(attribute); + } + } catch(Exception exception) + { + throw new UnableToBuildFeatureException(exception,property.getName()); + } + + if (!_mandatoryAttributes.isEmpty()) + { + throw new MissingFeatureAttributesException(_mandatoryAttributes); + } + + _managementFeatureInfo = new MBeanAttributeInfo( + property.getName(), + property.getJavaType().getName(), + property.getDescription(), + true, + property.getAccessMode()==AccessMode.RW, + false); + _qpidFeature = property; + } + }; + + final State _statisticBuilder = new State() + { + public void build () throws UnableToBuildFeatureException + { + QpidStatistic statistic = new QpidStatistic(); + try + { + for (Entry<String, Object> statisticAttribute : _featureDefinition.entrySet()) + { + Attribute attribute = Attribute.valueOf(statisticAttribute.getKey()); + switch(attribute) + { + case name : + { + statistic.setName(String.valueOf(statisticAttribute.getValue())); + break; + } + case unit : + { + statistic.setUnit(String.valueOf(statisticAttribute.getValue())); + break; + } + case desc : + { + statistic.setDescription(String.valueOf(statisticAttribute.getValue())); + break; + } + case type : + { + int code = (Integer) statisticAttribute.getValue(); + statistic.setType(Configuration.getInstance().getType(code)); + break; + } + } + _mandatoryAttributes.remove(attribute); + } + } catch(Exception exception) + { + throw new UnableToBuildFeatureException(exception,statistic.getName()); + } + + if (!_mandatoryAttributes.isEmpty()) + { + throw new MissingFeatureAttributesException(_mandatoryAttributes); + } + + _managementFeatureInfo = new MBeanAttributeInfo( + statistic.getName(), + statistic.getJavaType().getName(), + statistic.getDescription(), + true, + false, + false); + _qpidFeature = statistic; + } + }; + + /** + * Builder used for building a statistic definition. + */ + final State _argumentBuilder = new State() + { + /** + * Builds a property definition as well a management attribute feature. + */ + public void build () throws UnableToBuildFeatureException + { + QpidArgument argument = new QpidArgument(); + for (Entry<String, Object> argumentAttribute : _featureDefinition.entrySet()) + { + String key = argumentAttribute.getKey(); + if (Names.DEFAULT_PARAM_NAME.equals(key)) + { + argument.setDefaultValue(argumentAttribute.getValue()); + } else { + Attribute attribute = Attribute.valueOf(key); + switch (attribute) + { + case name : + { + argument.setName((String)argumentAttribute.getValue()); + break; + } + case desc : + { + argument.setDescription((String)argumentAttribute.getValue()); + break; + } + case type : + { + try + { + argument.setType(Configuration.getInstance().getType((Integer)argumentAttribute.getValue())); + break; + } catch(UnknownTypeCodeException exception) + { + throw new UnableToBuildFeatureException(exception,argument.getName()); + } + } + case dir : + { + argument.setDirection((String)argumentAttribute.getValue()); + break; + } + case unit : + { + argument.setUnit((String)argumentAttribute.getValue()); + break; + + } + } + } + } + + if (!_mandatoryAttributes.isEmpty()) + { + throw new MissingFeatureAttributesException(_mandatoryAttributes); + } + + _qpidFeature = argument; + _managementFeatureInfo = new MBeanParameterInfo( + argument.getName(), + argument.getJavaType().getName(), + argument.getDescription()); + } + }; + + final State _methodBuilder = new State() + { + public void build () throws UnableToBuildFeatureException + { + Map<String,Object> definition = _methodOrEventDefinition.getDefinition(); + String name = (String)definition.get(Attribute.name.name()); + if (name == null) + { + throw new MissingFeatureAttributesException(_mandatoryAttributes); + } + + QpidMethod method = new QpidMethod((String)definition.get(Attribute.name.name()),(String) definition.get(Attribute.desc.name())); + + List<Map<String,Object>> args = _methodOrEventDefinition.getArgumentsDefinitions(); + + List<MBeanParameterInfo> signature = new LinkedList<MBeanParameterInfo>(); + + for (Map<String,Object> argumentDefinition : args) + { + QpidFeatureBuilder builder = QpidFeatureBuilder.createArgumentBuilder(argumentDefinition); + builder.build(); + + QpidArgument argument = (QpidArgument) builder.getQpidFeature(); + method.addArgument(argument); + if (argument.isInput()) + { + signature.add((MBeanParameterInfo) builder.getManagementFeature()); + } + } + + _qpidFeature = method; + _managementFeatureInfo = new MBeanOperationInfo( + method.getName(), + method.getDescription(), + (MBeanParameterInfo[])signature.toArray(new MBeanParameterInfo[signature.size()]), + void.class.getName(), + MBeanOperationInfo.ACTION); + } + }; + + final State _eventBuilder = new State() + { + public void build () throws UnableToBuildFeatureException + { + } + }; + + private MBeanFeatureInfo _managementFeatureInfo; + private QpidFeature _qpidFeature; + private final Map <String, Object> _featureDefinition; + private final MethodOrEventDataTransferObject _methodOrEventDefinition; + private State _state; + + static QpidFeatureBuilder createPropertyBuilder(Map<String, Object> propertyDefinition) + { + QpidFeatureBuilder result = new QpidFeatureBuilder(propertyDefinition); + result._state = result._propertyBuilder; + result._mandatoryAttributes.add(Attribute.name); + result._mandatoryAttributes.add(Attribute.access); + result._mandatoryAttributes.add(Attribute.type); + result._mandatoryAttributes.add(Attribute.optional); + result._mandatoryAttributes.add(Attribute.index); + return result; + } + + static QpidFeatureBuilder createStatisticBuilder(Map<String, Object> statisticDefinition) + { + QpidFeatureBuilder result = new QpidFeatureBuilder(statisticDefinition); + result._state = result._statisticBuilder; + result._mandatoryAttributes.add(Attribute.name); + result._mandatoryAttributes.add(Attribute.type); + return result; + } + + static QpidFeatureBuilder createEventBuilder(Map<String, Object> eventDefinition) + { + QpidFeatureBuilder result = new QpidFeatureBuilder(eventDefinition); + result._state = result._eventBuilder; + return result; + } + + static QpidFeatureBuilder createMethodBuilder(MethodOrEventDataTransferObject methodDefinition) + { + QpidFeatureBuilder result = new QpidFeatureBuilder(methodDefinition); + result._state = result._methodBuilder; + result._mandatoryAttributes.add(Attribute.name); + return result; + } + + private static QpidFeatureBuilder createArgumentBuilder(Map<String, Object> argumentDefinition) + { + QpidFeatureBuilder result = new QpidFeatureBuilder(argumentDefinition); + result._state = result._argumentBuilder; + return result; + } + + + /** + * Builds new builder with the given data. + * This constructor is used for building properties, statistics and arguments. + * + * @param definition the feature definition data. + */ + private QpidFeatureBuilder(Map<String, Object> definition) + { + this._featureDefinition = definition; + this._methodOrEventDefinition = null; + } + + /** + * Builds new builder with the given data. + * This constructor is used for building properties, statistics and arguments. + * + * @param definition the feature definition data. + */ + private QpidFeatureBuilder(MethodOrEventDataTransferObject definition) + { + this._featureDefinition = null; + this._methodOrEventDefinition = definition; + } + + /** + * Returns the just built qpid feature. + * + * @return the qpid feature. + */ + QpidFeature getQpidFeature() + { + return _qpidFeature; + } + + /** + * Return the jmx metadata for the built feature. + * + * @return the jmx metadata for the built feature. + */ + MBeanFeatureInfo getManagementFeature() + { + return _managementFeatureInfo; + } + + void build() throws UnableToBuildFeatureException + { + try + { + _state.build(); + } catch(UnableToBuildFeatureException exception) + { + throw exception; + } catch(Exception exception) + { + throw new UnableToBuildFeatureException(exception,"Feature name is not available for debugging."); + } + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java new file mode 100644 index 0000000000..7824ecc9a4 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java @@ -0,0 +1,147 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.apache.qpid.transport.codec.BBDecoder; +import org.apache.qpid.transport.codec.Encoder; + + +/** + * Qpid method definition. + * An entity describing an invocation that can be made on a managed object instance. + * + * @author Andrea Gazzarini + */ +public class QpidMethod extends QpidFeature +{ + /** Argument list */ + List<QpidArgument> arguments = new LinkedList<QpidArgument>(); + + /** + * Builds a new qpid method definition with the given name and description. + * + * @param name the method name. + * @param description the method description. + */ + QpidMethod(String name, String description) + { + this._name = name; + this._description = description; + } + + /** + * Adds an argument to this method. + * + * @param argument the new argument to be added. + */ + void addArgument(QpidArgument argument) + { + arguments.add(argument); + } + + /** + * Returns a string representation of this method. + * The result format is <method name>(argType1 argName1 (Direction), argType2 argName2 (Direction), etc...) + * + * @return a string representation of this method. + */ + @Override + public String toString () + { + StringBuilder builder = new StringBuilder() + .append(_name) + .append('('); + + for (QpidArgument argument : arguments) + { + builder.append(argument).append(','); + } + + builder.append(')'); + return builder.toString(); + } + + /** + * Encodes the given parameter values according to this method arguments definitions. + * Note that only Input/Output and Input parameters are encoded. + * + * @param parameters the parameters values. + * @param encoder the encoder used for encoding. + */ + public void encodeParameters (Object[] parameters, Encoder encoder) + { + int index = 0; + for (QpidArgument argument : arguments) + { + if (argument.getDirection() != Direction.O) + { + argument.encode(parameters[index++],encoder); + } + } + } + + /** + * Decodes the given input raw according to this method arguments definitions. + * Note that only Input/Output and Output parameters are encoded. + * + * @param parameters the parameters values. + * @param encoder the encoder used for encoding. + */ + public Map<String, Object> decodeParameters (byte [] values) + { + BBDecoder decoder = new BBDecoder(); + decoder.init(ByteBuffer.wrap(values)); + Map<String, Object> result = new HashMap<String, Object>(); + + for (QpidArgument argument : arguments) + { + if (argument.getDirection() != Direction.I) + { + result.put(argument.getName(),argument.decode(decoder)); + } + } + return result; + } + + /** + * Validates the given array of parameters against the constraint defined on this method's arguments. + * + * @param parameters the parameters (values) to be validated. + * @throws ValidationException when one of the supplied values is violating some constraint. + */ + public void validate (Object[] parameters) throws ValidationException + { + int index = 0; + for (QpidArgument argument : arguments) + { + if (argument.getDirection() != Direction.O) + { + argument.validate(parameters[index++]); + } + } + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java new file mode 100644 index 0000000000..e9799cb147 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java @@ -0,0 +1,279 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.management.domain.handler.impl.IMethodInvocationListener; +import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject; +import org.apache.qpid.management.domain.model.type.Binary; + +/** + * Qpid package definition. + * A grouping of class definitions that are related to a single software component. + * The package concept is used to extend the management schema beyond just the QPID software components. + * The name is prefixed with "Qpid" for avoiding name conficts with java.lang.Package. + * + * @author Andrea Gazzarini + */ +final class QpidPackage +{ + /** + * Qpid class identity. + * Each qpid class is uniquely identifier by its name and schema-hash. + * The schema hash is an MD5 checksum of the schema for a class. + * It is there so we can support the case where two different versions of the same class are present at the same time. + * + * @author Andrea Gazzarini + */ + class QpidClassIdentity { + final String name; + final Binary hash; + + /** + * Builds a new class identity with the given name and hash. + * + * @param name the class name. + * @param hash is an MD5 checksum of the schema of this outer class. + */ + QpidClassIdentity(String name,Binary hash) { + this.name = name; + this.hash = hash; + } + + @Override + public int hashCode () + { + return name.hashCode()+hash.hashCode(); + } + + @Override + public boolean equals (Object obj) + { + QpidClassIdentity identity = (QpidClassIdentity) obj; + return name.equals(identity.name) && hash.equals(identity.hash); + } + } + + private String _name; + private DomainModel _parent; + private Map<QpidClassIdentity, QpidClass> _classes = new HashMap<QpidClassIdentity, QpidClass>(); + private Map<QpidClassIdentity, QpidEvent> _events = new HashMap<QpidClassIdentity, QpidEvent>(); + + /** + * Builds a new package with the supplied name. + * + * @param name the name of the package. + */ + QpidPackage(String name, DomainModel parent) + { + this._name = name; + this._parent = parent; + } + + /** + * Returns the identifier of the broker which contains this package. + * @return + */ + UUID getOwnerId() + { + return _parent.getBrokerId(); + } + + /** + * Returns the name of this package. + * + * @return the name of this package. + */ + String getName () + { + return _name; + } + + /** + * Adds a class definition to this package. + * The class will be added only if its definition doesn't already exists. + * + * @param className the name of the class. + * @param classHash the class schema hash. + * @param properties the properties of the class. + * @param statistics the statistics of the class. + * @param methods the methods of the class. + * @param events the events of the class. + * + * @throws UnableToBuildFeatureException when the class definition cannot be built due to a feature build failure. + */ + void addClassDefinition ( + String className, + Binary classHash, + List<Map<String, Object>> properties, + List<Map<String, Object>> statistics, + List<MethodOrEventDataTransferObject> methods) throws UnableToBuildFeatureException + { + getQpidClass(className,classHash,true).setSchema(properties,statistics,methods); + } + + void addEventDefinition ( + String eventClassName, + Binary classHash, + List<Map<String, Object>> arguments) throws UnableToBuildFeatureException + { + getQpidEvent(eventClassName,classHash,true).setSchema(arguments); + } + + /** + * Returns true if this package contains the given class definition. + * + * @param className the name of the class. + * @return true if this package contains the class definition, false otherwise. + */ + boolean alreadyContainsClassDefinition (String className, Binary hash) + { + return _classes.containsKey(new QpidClassIdentity(className,hash)); + } + + /** + * Injects into a class the given object instance instrumentation data. + * + * @param className the of the class the injected object data belongs to. + * @param objectId the object identifier. + * @param rawData the instrumentation data (in raw format). + */ + void setObjectInstanceInstrumentationRawData (String className, Binary classHash,Binary objectId, byte[] rawData) + { + getQpidClass(className, classHash,true).addInstrumentationData(objectId,rawData); + } + + /** + * Injects into a class the given object instance configuration data. + * + * @param className the of the class the injected object data belongs to. + * @param objectId the object identifier. + * @param rawData the configuration data (in raw format). + */ + void setObjectInstanceConfigurationRawData (String className,Binary classHash, Binary objectId, byte[] rawData) + { + getQpidClass(className,classHash,true).addConfigurationData(objectId,rawData); + } + + void setEventInstanceRawData (String eventName,Binary eventHash, byte[] rawData,long currentTimestamp,int severity) + { + getQpidEvent(eventName,eventHash,true).addEventData(rawData, currentTimestamp, severity); + } + + /** + * Returns the definition of the class with given name. + * + * @param className the name of the class. + * @param hash the class hash. + * @param store a flag indicating if a just created class must be stored or not. + * @return the definition of the class with given name. + */ + QpidClass getQpidClass(String className, Binary hash, boolean store) + { + QpidClassIdentity identity = new QpidClassIdentity(className,hash); + QpidClass classDefinition = _classes.get(identity); + if (classDefinition == null) + { + classDefinition = new QpidClass(className, hash,this); + if (store) + { + _classes.put(identity,classDefinition); + } + } + return classDefinition; + } + + /** + * Returns the definition of the class with given name. + * + * @param className the name of the class. + * @param hash the class hash. + * @param store a flag indicating if a just created class must be stored or not. + * @return the definition of the class with given name. + */ + QpidEvent getQpidEvent(String className, Binary hash, boolean store) + { + QpidClassIdentity identity = new QpidClassIdentity(className,hash); + QpidEvent eventDefinition = _events.get(identity); + if (eventDefinition == null) + { + eventDefinition = new QpidEvent(className, hash,this); + if (store) + { + _events.put(identity,eventDefinition); + } + } + return eventDefinition; + } + + /** + * Returns a string representation of this class. + * That is, this method returns the simple name (not FQN) of this class. + */ + @Override + public String toString () + { + return _name; + } + + /** + * Removes the object instance associated to the given parameters. + * + * @param className the class definition of the object instance. + * @param classHash the class hash + * @param objectId the object identifier. + */ + void removeObjectInstance (String className, Binary classHash, Binary objectId) + { + QpidClass qpidClass = getQpidClass(className,classHash,false); + qpidClass.removeObjectInstance(objectId); + } + + /** + * Releases all previously acquired resources of this package. + */ + void releaseResources () + { + for (QpidClass qpidClass : _classes.values()) + { + qpidClass.releaseResources(); + } + + for (QpidEvent qpidEvent: _events.values()) + { + qpidEvent.releaseResources(); + } + } + + /** + * Returns the method invocation listener of the corresponing parent domain model. + * + * @return the method invocation listener of the corresponing parent domain model. + */ + IMethodInvocationListener getMethodInvocationListener () + { + return _parent.getMethodInvocationListener(); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java new file mode 100644 index 0000000000..089b00c71c --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java @@ -0,0 +1,295 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import java.lang.reflect.Constructor; + +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.configuration.Configuration; +import org.apache.qpid.management.domain.model.type.Type; +import org.apache.qpid.transport.util.Logger; + +/** + * Qpid property definition. + * + * @author Andrea Gazzarini + */ +class QpidProperty extends QpidAttribute +{ + private final static Logger LOGGER = Logger.get(QpidProperty.class); + + private final static int [] MASKS = {1,2,4,8,16,32,64,128}; + + /** + * Decoder interface used for decoding incomng values for this property. + * + * @author Andrea Gazzarini + */ + interface Decoder + { + Object decodeValue(org.apache.qpid.transport.codec.Decoder decoder,byte [] presenceBitMasks); + } + + /** + * Decoder used for decoding incoming values for this optional property. + */ + final Decoder _optionalPropertyDecoder = new Decoder() { + + public Object decodeValue (org.apache.qpid.transport.codec.Decoder decoder, byte[] presenceBitMasks) + { + return ((presenceBitMasks[_optionalIndex/8] & MASKS[_maskIndex]) != 0) + ? QpidProperty.this.decodeValue(decoder) + : null; + } + }; + + /** + * Decoder used for decoding incoming values for this mandatory property. + */ + final Decoder _mandatoryPropertyDecoder = new Decoder() { + + public Object decodeValue (org.apache.qpid.transport.codec.Decoder decoder, byte[] presenceBitMasks) + { + return QpidProperty.this.decodeValue(decoder); + } + }; + + + /** + * Null object used to perform a dummy validation. + * This is the default validator installed at creation time. + */ + final static IValidator EMPTY_VALIDATOR = new IValidator() + { + public void validate (Object value) throws ValidationException + { + // Nothing to do here. + } + }; + + /** + * Validator responsible for validating strings. + * At the moment the only constraint that should be applied to a string feature is the "max length" + */ + class StringValidator implements IValidator + { + public void validate (Object value) throws ValidationException + { + if ((_maxLength != Integer.MIN_VALUE) && (value != null)){ + int length = value.toString().length(); + if (length > _maxLength) { + throw new ValidationException( + ValidationException.MAX_LENGTH, + _maxLength, + _name, + length); + } + } + } + }; + + /** + * Validator responsible for validating numbers. + */ + class NumberValidator implements IValidator + { + public void validate (Object value) throws ValidationException + { + if (value != null) { + double numericValue = ((Number)value).doubleValue(); + if (_minValue != Integer.MIN_VALUE && numericValue < _minValue) { + throw new ValidationException( + ValidationException.MIN_VALUE, + _minValue, + _name, + numericValue); + } + + if (_maxValue != Integer.MIN_VALUE && numericValue > _maxValue) { + throw new ValidationException( + ValidationException.MAX_VALUE, + _maxValue, + _name, + numericValue); + } + } + } + }; + + private AccessMode _accessMode; + private int _minValue = Integer.MIN_VALUE; + private int _maxValue = Integer.MIN_VALUE; + private int _maxLength = Integer.MIN_VALUE; + + private int _optionalIndex; + private int _maskIndex; + + Decoder _decoder = _mandatoryPropertyDecoder; + + private IValidator _validator = EMPTY_VALIDATOR; + + /** + * Validates the given value according to the current validator. + * It delegates the validation to the current installed validator. + * + * @param value the value of this qpid property. + * @throws ValidationException when the given value is violating the current validator constraints. + */ + void validate(Object value) throws ValidationException { + _validator.validate(value); + } + + /** + * Sets the type of this property. + * In addition this method tries to detect if a validator has been associated with the type. + * If no validator is found then the default validator will be used; that is : no validator will be performed on this + * property. + * + * @param type the type of this property. + */ + void setType (Type type) + { + super.setType(type); + try { + Class<?> validatorClass = Class.forName(Configuration.getInstance().getValidatorClassName(type)); + Constructor<?> validatorConstructor = validatorClass.getDeclaredConstructor(QpidProperty.class); + _validator = (IValidator) validatorConstructor.newInstance(this); + LOGGER.debug(Messages.QMAN_200022_VALIDATOR_INSTALLED ,validatorClass.getName(), type); + } catch(Exception exception) { + _validator = EMPTY_VALIDATOR; + LOGGER.debug(Messages.QMAN_200023_VALIDATOR_NOT_FOUND , type); + } + } + + /** + * Gets the value of this property according to its type definition. + * + * @param decoder the decoder used to extract the value. + * @return the value of this feature according to its type definition + */ + Object decodeValue(org.apache.qpid.transport.codec.Decoder decoder,byte [] presenceBitMasks) + { + return _decoder.decodeValue(decoder, presenceBitMasks); + } + + /** + * Sets access mode for this property. + * + * @param accessMode the access mode for this property. + */ + void setAccessMode (AccessMode accessMode) + { + this._accessMode = accessMode; + } + + /** + * Gets the minimum allowed value for this property. + * + * @return the minimum allowed value for this property. + */ + int getMinValue () + { + return _minValue; + } + + /** + * Sets the minimum allowed value for this property. + * + * @param minValue the minimum allowed value for this property. + */ + void setMinValue (int minValue) + { + this._minValue = minValue; + } + + /** + * Gets the maximum allowed value for this property. + * + * @return the maximum allowed value for this property. + */ + int getMaxValue () + { + return _maxValue; + } + + /** + * Sets the masimum allowed value for this property. + * + * @param maxValue the maximum allowed value for this property. + */ + void setMaxValue (int maxValue) + { + this._maxValue = maxValue; + } + + /** + * Gets the max length value for this property. + * + * @return the max length value for this property. + */ + int getMaxLength () + { + return _maxLength; + } + + /** + * Sets the max length value for this property. + * + * @param maxLength the max length value for this property. + */ + void setMaxLength (int maxLength) + { + this._maxLength = maxLength; + } + + /** + * Gets the description of this property. + * + * @return the description of this property. + */ + AccessMode getAccessMode () + { + return _accessMode; + } + + /** + * Marks this property as optional. + * + * @param optional the optional attribute value for this property. + * @param index the index of this optional property + */ + void markAsOptional (int index) + { + this._optionalIndex = index; + this._maskIndex = (_optionalIndex >= 8) ? _optionalIndex-8 : _optionalIndex; + _decoder = _optionalPropertyDecoder; + } + + /** + * Returns true if this property is marked as optional. + * + * @return true if this property is marked as optional, false otherwise. + */ + boolean isOptional () + { + return _decoder == _optionalPropertyDecoder; + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java new file mode 100644 index 0000000000..37a652c098 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java @@ -0,0 +1,34 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +/** + * Qpid statistic definition. + * + * A statistic is a typed member of a class which represents an instrumentation attribute of the class. + * Statistics are always read-only in nature and tend to change rapidly. + * + * @author Andrea Gazzarini + */ +class QpidStatistic extends QpidAttribute +{ + // EMPTY CLASS : Statistic metadata are all defined in superclasses. +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java new file mode 100644 index 0000000000..fc4506779b --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java @@ -0,0 +1,51 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +/** + * Thrown when a feature (property, statistic, method or event) definition cannot be built due to schema parsing errors. + * + * @author Andrea Gazzarini + */ +public class UnableToBuildFeatureException extends Exception +{ + private static final long serialVersionUID = 5180111828887602836L; + + /** + * Builds a new UnableToBuildFeatureException with the specified cause. + * + * @param exception the exception cause. + */ + UnableToBuildFeatureException(Exception exception, String featureName) + { + super( (featureName != null) ? featureName : "Feature name is not available for debugging purposes." ,exception); + } + + /** + * Builds a new UnableToBuildFeatureException with the specified message. + * + * @param message the detail message. + */ + UnableToBuildFeatureException(String message) + { + super(message); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java new file mode 100644 index 0000000000..3b117e5b9d --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java @@ -0,0 +1,105 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +/** + * Thrown when an attempt is made in order to update / change the state of an object and a constraint on that state + * is violated. + * + * @author Andrea Gazzarini + */ +public class ValidationException extends Exception +{ + private static final long serialVersionUID = -5218828669655586205L; + + public final static String MAX_LENGTH = "Max Length"; + public final static String MAX_VALUE = "Max Value"; + public final static String MIN_VALUE = "Min Value"; + + private final String _featureName; + private final Object _featureValue; + + private final Number _constraintValue; + private final String _constraintName; + + /** + * Builds a new validation exception with the specified parameters. + * + * @param constraintName the name of the violated constraint. + * @param constraintValue the value of the violated constraint. + * @param featureName the name of the violating feature. + * @param featureValue the value of the violating feature. + */ + ValidationException(String constraintName,Number constraintValue, String featureName,Object featureValue) + { + super(String.format( + "Property constraint violation : " + + "%s allowed for property %s is %s but received value was %s", + constraintName, + featureName, + constraintValue, + featureValue)); + this._constraintName = constraintName; + this._constraintValue = constraintValue; + this._featureName = featureName; + this._featureValue = featureValue; + } + + /** + * Returns the value of the violating feature. + * + * @return the value of the violating feature. + */ + public Object getFeatureValue () + { + return _featureValue; + } + + /** + * Returns the name of the violating feature. + * + * @return the name of the violating feature. + */ + public String getFeatureName() + { + return _featureName; + } + + /** + * Returns the value of the violated constraint. + * + * @return the value of the violated constraint. + */ + public Number getConstraintValue () + { + return _constraintValue; + } + + /** + * Returns the name of the violated constraint. + * + * @return the name of the violated constraint. + */ + public String getConstraintName () + { + return _constraintName; + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/AbsTime.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/AbsTime.java new file mode 100644 index 0000000000..28f5f70c04 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/AbsTime.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class AbsTime extends Type +{ + public AbsTime() + { + super(Long.class); + } + + @Override + public Object decode (Decoder decoder) + { + return decoder.readInt64(); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeInt64((Long)value); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java new file mode 100644 index 0000000000..8009150eb2 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java @@ -0,0 +1,151 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.UUID; + +import org.apache.qpid.management.messages.AmqpCoDec; +import org.apache.qpid.transport.codec.Encoder; + +/** + * It is a simple wrapper for a byte array (for example a 128bin). + * It is used to let QMan deal with an object instead of an array. + * + * @author Andrea Gazzarini + */ +public final class Binary implements Serializable +{ + private static final long serialVersionUID = -6865585077320637567L; + + // Marker internal (empty) interface + private interface State extends Serializable{} + + /** + * Internal state of this object used to denote the situation when the hashcode() method has never been called. + * After the hashcode has been computed this class switches the state of the outer object to the next state. + */ + State hashCodeNotYetComputed = new State() + { + private static final long serialVersionUID = 221632033761266959L; + + @Override + public int hashCode () + { + hashCode = Arrays.hashCode(_bytes); + state = hashCodeAlreadyComputed; + return hashCode; + } + }; + + /** + * Internal state of this object used to denote the situation where the hashcode() method has already been computed. + * Simply it returns the just computed value for the hashcode. + */ + State hashCodeAlreadyComputed = new State() + { + private static final long serialVersionUID = 221632033761266959L; + + @Override + public int hashCode () + { + return hashCode; + } + }; + + private final UUID uuid; + private final byte [] _bytes; + private long _first; + private int hashCode; + + /** Current state (hashcode computation). */ + State state = hashCodeNotYetComputed; + + /** + * Builds a new binary with the given byte array. + * + * @param bytes the wrapped data. + */ + public Binary(byte [] bytes) + { + this._bytes = bytes; + byte [] array = new byte [8]; + System.arraycopy(_bytes, 0, array, 0, 8); + _first = AmqpCoDec.unpack64(array); + uuid = UUID.randomUUID(); + } + + @Override + public int hashCode () + { + return state.hashCode(); + } + + @Override + public boolean equals (Object obj) + { + try + { + Binary binary = (Binary)obj; + return Arrays.equals(_bytes, binary._bytes); + } catch (Exception exception) + { + return false; + } + } + + /** + * Encodes the content (wrapped byte array) of this instance using the given encoder. + * + * @param encoder the encoder used to encode instance content. + */ + public void encode(Encoder encoder) + { + encoder.writeBin128(_bytes); + } + + @Override + public String toString () + { + return uuid.toString(); + } + + /** + * Returns the bank identifier derived from this object identifier. + * + * @return the bank identifier derived from this object identifier. + */ + public long getBankId() + { + return _first & 0x000000000FFFFFFF; + } + + /** + * Returns the broker identifier derived from this object identifier. + * + * @return the broker identifier derived from this object identifier. + */ + public long getBrokerId() + { + return (_first & 281474708275200L) >> 28; + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Boolean.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Boolean.java new file mode 100644 index 0000000000..c339b870ac --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Boolean.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class Boolean extends Type +{ + public Boolean() + { + super(java.lang.Boolean.class); + } + + @Override + public Object decode (Decoder decoder) + { + return (decoder.readUint8() == 1); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeUint8( ((java.lang.Boolean)value) ? (short)1 : 0 ); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/DeltaTime.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/DeltaTime.java new file mode 100644 index 0000000000..a788e2f8e1 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/DeltaTime.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class DeltaTime extends Type +{ + public DeltaTime() + { + super(Long.class); + } + + @Override + public Object decode (Decoder decoder) + { + return decoder.readUint64(); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeUint64((Long)value); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Double.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Double.java new file mode 100644 index 0000000000..d36af3d3df --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Double.java @@ -0,0 +1,44 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Double extends Type
+{
+ public Double()
+ {
+ super(java.lang.Double.class);
+ }
+
+ @Override
+ public Object decode(Decoder decoder)
+ {
+ return decoder.readDouble();
+ }
+
+ @Override
+ public void encode(Object value, Encoder encoder)
+ {
+ encoder.writeDouble((java.lang.Double)value);
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Float.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Float.java new file mode 100644 index 0000000000..cb1f6e78a7 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Float.java @@ -0,0 +1,44 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Float extends Type
+{
+ public Float()
+ {
+ super(java.lang.Float.class);
+ }
+
+ @Override
+ public Object decode(Decoder decoder)
+ {
+ return decoder.readFloat();
+ }
+
+ @Override
+ public void encode(Object value, Encoder encoder)
+ {
+ encoder.writeFloat((java.lang.Float)value);
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int16.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int16.java new file mode 100644 index 0000000000..f4685f0295 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int16.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class Int16 extends Type +{ + public Int16() + { + super(Short.class); + } + + @Override + public Object decode (Decoder decoder) + { + return decoder.readInt16(); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeInt16((Short)value); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int32.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int32.java new file mode 100644 index 0000000000..ae5be90a2d --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int32.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class Int32 extends Type +{ + public Int32() + { + super(Integer.class); + } + + @Override + public Object decode (Decoder decoder) + { + return decoder.readInt32(); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeInt32((Integer)value); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int64.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int64.java new file mode 100644 index 0000000000..f76818344e --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int64.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class Int64 extends Type +{ + public Int64() + { + super(Long.class); + } + + @Override + public Object decode (Decoder decoder) + { + return decoder.readInt64(); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeInt64((Long)value); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int8.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int8.java new file mode 100644 index 0000000000..6f7c3b24d0 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int8.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class Int8 extends Type +{ + public Int8() + { + super(Byte.class); + } + + @Override + public Object decode (Decoder decoder) + { + return decoder.readInt8(); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeInt8((Byte)value); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java new file mode 100644 index 0000000000..cc540ff4da --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class Map extends Type +{ + public Map() + { + super(java.util.Map.class); + } + + @Override + public Object decode (Decoder decoder) + { + return decoder.readMap(); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeMap((java.util.Map<String, Object>)value); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/ObjectReference.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/ObjectReference.java new file mode 100644 index 0000000000..13e1b68d26 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/ObjectReference.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class ObjectReference extends Type +{ + public ObjectReference() + { + super(byte[].class); + } + + @Override + public Object decode (Decoder decoder) + { + return decoder.readBin128(); + } + + @Override + public void encode (Object value, Encoder encoder) + { + ((Binary)value).encode(encoder); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str16.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str16.java new file mode 100644 index 0000000000..42829ce176 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str16.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class Str16 extends Type +{ + public Str16() + { + super(String.class); + } + + @Override + public Object decode (Decoder decoder) + { + return decoder.readStr16(); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeStr16((String)value); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str8.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str8.java new file mode 100644 index 0000000000..f9b747ce6d --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str8.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class Str8 extends Type +{ + public Str8() + { + super(String.class); + } + + @Override + public Object decode (Decoder decoder) + { + return decoder.readStr8(); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeStr8((String)value); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Type.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Type.java new file mode 100644 index 0000000000..c455faaf2c --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Type.java @@ -0,0 +1,101 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +/** + * Layer supertype for all management "types". + * + * @author Andrea Gazzarini + */ +public abstract class Type +{ + /** Java representation of this type. */ + protected final Class<?> javaType; + + /** + * Builds a new management type wiich wraps the given java type. + * + * @param javaType the java type. + */ + Type(Class<?> javaType) + { + this.javaType = javaType; + } + + /** + * Returns the wrapped java type. + * + * @return the wrapped java type. + */ + public Class<?> getJavaType () + { + return javaType; + } + + /** + * Each concrete subclass must define here how to decode incoming data according. + * + * @param decoder the decoder used to extract data. + * @return the "typed" value. + * + */ + public abstract Object decode(Decoder decoder); + + /** + * Returns a string representation of this type. + * + * @return a string representation of this type. + */ + @Override + public String toString () + { + return new StringBuilder(getClass().getName()) + .append(" (wraps ") + .append(javaType.getName()) + .append(')').toString(); + } + + /** + * Identity for types is based on wrapped java type identity. + */ + @Override + public boolean equals (Object obj) + { + return getClass() == obj.getClass(); + } + + @Override + public int hashCode () + { + return getClass().hashCode(); + } + + /** + * Encodes the given values according to this type definition. + * + * @param value the value to be encoded. + * @param encoder the encoder. + */ + public abstract void encode (Object value,Encoder encoder); +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint16.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint16.java new file mode 100644 index 0000000000..2d3edd41ea --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint16.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class Uint16 extends Type +{ + public Uint16() + { + super(Integer.class); + } + + @Override + public Object decode (Decoder decoder) + { + return new Integer(decoder.readUint16()); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeUint16((Integer)value); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint32.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint32.java new file mode 100644 index 0000000000..c5fb981bb0 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint32.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class Uint32 extends Type +{ + public Uint32() + { + super(Long.class); + } + + @Override + public Object decode (Decoder decoder) + { + return new Long(decoder.readUint32()); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeUint32((Long)value); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint64.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint64.java new file mode 100644 index 0000000000..9182f883bf --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint64.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class Uint64 extends Type +{ + public Uint64() + { + super(Long.class); + } + + @Override + public Object decode (Decoder decoder) + { + return new Long(decoder.readUint64()); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeUint64((Long)value); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint8.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint8.java new file mode 100644 index 0000000000..ab7e78856c --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint8.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class Uint8 extends Type +{ + public Uint8() + { + super(Short.class); + } + + @Override + public Object decode (Decoder decoder) + { + return new Short(decoder.readUint8()); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeUint8((Short)value); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uuid.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uuid.java new file mode 100644 index 0000000000..1b3be954d6 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uuid.java @@ -0,0 +1,46 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import java.util.UUID; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +public class Uuid extends Type +{ + public Uuid() + { + super(UUID.class); + } + + @Override + public Object decode (Decoder decoder) + { + return decoder.readUuid(); + } + + @Override + public void encode (Object value, Encoder encoder) + { + encoder.writeUuid((UUID)value); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java new file mode 100644 index 0000000000..aa588043aa --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java @@ -0,0 +1,177 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.services; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.qpid.api.Message; +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Protocol; +import org.apache.qpid.management.domain.handler.base.IMessageHandler; +import org.apache.qpid.management.domain.model.DomainModel; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.transport.codec.BBDecoder; +import org.apache.qpid.transport.util.Logger; + +/** + * Message listener used for processing incoming messages. + * So it is installed as a consumer on a specific channel and when a new message arrives: + * + * 1) Performs a sanity check on the message (magic number, sequence number) + * 2) Extracts the opcode and looks for one message handler associated with that opcode. + * 3) If a message handler is found the delegates the message processing; otherwise a log message is written to indicate + * that the message will be skipped. + * + * @author Andrea Gazzarini + */ +class BrokerMessageListener implements MessageListener +{ + private final static Logger LOGGER = Logger.get(BrokerMessageListener.class); + + private static class Log + { + // Debugs the content of the incoming message. + static void debugIncomingMessage(ByteBuffer message) + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug(Messages.QMAN_200001_INCOMING_MESSAGE_HAS_BEEN_RECEIVED, Arrays.toString(message.array())); + } + } + + // Debugs all the configured handlers. + static void debugConfiguredHandlers (Map<Character, IMessageHandler> _handlers) + { + if (LOGGER.isDebugEnabled()) + { + for (Entry<Character, IMessageHandler> entry : _handlers.entrySet()) + { + LOGGER.debug(Messages.QMAN_200002_OPCODE_HANDLER_ASSOCIATION,entry.getKey(),entry.getValue()); + } + } + } + } + + Map<Character, IMessageHandler> _handlers = new HashMap<Character, IMessageHandler>(); + private DomainModel _domainModel; + + /** + * Builds a new message listener with the given broker domain model. + * + * @param model the managed broker domain model. + */ + BrokerMessageListener(DomainModel model) + { + this._domainModel = model; + } + + /** + * When a new message arrives this method is called. + * 1) Performs a sanity check on the message (magic number, sequence number) + * 2) Extracts the opcode and looks for one message handler associated with that opcode. + * 3) If a message handler is found the delegates the message processing; otherwise a log message is written to indicate + * that the message will be skipped. + * + * @param message the incoming message. + */ + public void onMessage (Message compoundMessage) + { + try + { + MessageTokenizer tokenizer = new MessageTokenizer(compoundMessage); + while (tokenizer.hasMoreElements()) + { + dispatch(tokenizer.nextElement()); + } + } catch(IOException exception) + { + LOGGER.error(exception,Messages.QMAN_100002_MESSAGE_READ_FAILURE); + } catch(Exception exception) + { + LOGGER.error(exception,Messages.QMAN_100003_MESSAGE_PROCESS_FAILURE); + } + } + + /** + * Configures a new handler with this listener. + * After that, each time a message arrives with the specified opcode, this handler will be responsible for + * processing. + * Note that calling this method will switch this listener to a WORKING state. + * + * @param opcode the operation code. + * @param handler the message handler. + */ + void setHandlers(Map<Character, IMessageHandler> handlers) + { + for (Entry<Character, IMessageHandler> entry : handlers.entrySet()) + { + char opcode = entry.getKey(); + IMessageHandler handler = entry.getValue(); + try + { + handler.setDomainModel(_domainModel); + _handlers.put(opcode, handler); + } catch(Exception exception) { + LOGGER.error(exception,Messages.QMAN_100004_HANDLER_INITIALIZATION_FAILURE, opcode); + } + } + } + + /** + * Dispatches the given message to the appropriate handler. + * + * @param message the incoming message. + * @throws IOException when the message content cannot be read. + */ + private void dispatch(Message message) throws IOException + { + ByteBuffer buffer = message.readData(); + + String magicNumber = new String(new byte[] {buffer.get(),buffer.get(),buffer.get()}); + if (!Protocol.MAGIC_NUMBER.equals(magicNumber)) + { + LOGGER.error(Messages.QMAN_100001_BAD_MAGIC_NUMBER_FAILURE,magicNumber); + return; + } + + char opcode = (char)buffer.get(); + + IMessageHandler handler = _handlers.get(opcode); + if (handler != null) + { + BBDecoder decoder = new BBDecoder(); + decoder.init(buffer); + + LOGGER.debug(Messages.QMAN_200003_MESSAGE_FORWARDING,opcode,handler); + + handler.process(decoder,decoder.readSequenceNo()); + } else + { + LOGGER.warn(Messages.QMAN_300001_MESSAGE_DISCARDED,opcode); + Log.debugConfiguredHandlers(_handlers); + } + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.java new file mode 100644 index 0000000000..a3584571f3 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.java @@ -0,0 +1,231 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.services; + +import java.util.UUID; + +import org.apache.qpid.QpidException; +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; +import org.apache.qpid.management.configuration.BrokerConnectionData; +import org.apache.qpid.management.configuration.Configuration; +import org.apache.qpid.management.domain.model.DomainModel; +import org.apache.qpid.transport.util.Logger; + +/** + * This is the Object representation of a management client. + * According to specification : "A software component that is separate from the messaging broker, connected to the + * management broker via an AMQP connection, which allows any software component to be managed remotely by QPID." + * + * @author Andrea Gazzarini + */ +final class ManagementClient +{ + private final static Logger LOGGER = Logger.get(ManagementClient.class); + + private final String _managementQueueName; + private final String _methodReplyQueueName; + + private DomainModel _domainModel; + private QpidService _service; + + /** + * Builds a new <code>ManagementClient</code> with the given identifier and connection data. + * + * @param brokerId the broker identifier. + * @param connectionData the broker connection data (host, port, etc...) + */ + ManagementClient(UUID brokerId,BrokerConnectionData connectionData) + { + _service = new QpidService(brokerId); + _domainModel = new DomainModel(brokerId); + _managementQueueName = Configuration.getInstance().getManagementQueueName(); + _methodReplyQueueName = Configuration.getInstance().getMethodReplyQueueName(); + } + + /** + * Establishing initial communication Between Client and Broker. + * According to specification : + * "Communication is established between the management client and management agent using normal AMQP procedures. + * The client creates a connection to the broker and then establishes a session with its corresponding channel. + * Two private queues are then declared. + * A management queue is declared and bound to the qpid.management exchange with "mgmt.#" as routing key; in that + * way all management-related messages sent to the exchange will be received by this client. + * When a client successfully binds to the qpid.management exchange, the management agent schedules a schema + * broadcast to be sent to the exchange. + * The agent will publish, via the exchange, a description of the schema for all manageable objects in its control. That + * schema is therefore received by this service and it will be part of service's domain model." + * + * @throws StartupFailureException when this management client cannot perform startup operations due to an error. + */ + void estabilishFirstConnectionWithBroker() throws StartupFailureException{ + try { + connectWithBroker(); + + createAndBindMethodReplyQueue(); + createAndBindManagementQueue(); + + registerConsumerOnManagementQueue(); + registerConsumerOnMethodReplyQueue(); + + synchronize(); + } catch(Exception exception) + { + try { + _service.close(); + } catch(Exception ignore) + { + } + throw new StartupFailureException(exception); + } + } + + /** + * Shutdown procedure for this management client. + */ + void shutdown () + { + LOGGER.info(Messages.QMAN_000011_SHUTDOWN_INITIATED,_domainModel.getBrokerId()); + + removeMethodReplyConsumer(); + destroyAndUnbingMethodReplyQueue(); + + removeManagementConsumer(); + destroyAndUnbingManagementQueue(); + + _domainModel.releaseResources(); + + _service.close(); + + LOGGER.info(Messages.QMAN_000012_MANAGEMENT_CLIENT_SHUT_DOWN,_domainModel.getBrokerId()); + } + + /** + * Registers a consumer (that is, a listener) on the method-reply queue. + */ + private void registerConsumerOnMethodReplyQueue () + { + BrokerMessageListener methodReplyChannelListener = new BrokerMessageListener(_domainModel); + methodReplyChannelListener.setHandlers(Configuration.getInstance().getMethodReplyQueueHandlers()); + _service.createSubscription(_methodReplyQueueName, _methodReplyQueueName, methodReplyChannelListener); + + LOGGER.info(Messages.QMAN_000013_METHOD_REPLY_CONSUMER_INSTALLED, _domainModel.getBrokerId()); + } + + /** + * Registers a consumer (listener) on the management queue. + */ + private void registerConsumerOnManagementQueue () throws QpidException + { + BrokerMessageListener managementChannelListener = new BrokerMessageListener(_domainModel); + managementChannelListener.setHandlers(Configuration.getInstance().getManagementQueueHandlers()); + _service.createSubscription(_managementQueueName, _managementQueueName, managementChannelListener); + + LOGGER.info(Messages.QMAN_000014_MANAGEMENT_CONSUMER_INSTALLED, _domainModel.getBrokerId()); + } + + /** + * Declares a management queue and bound it to the "qpid.management" exchange with "mgmt.#" as routing key; + */ + private void createAndBindManagementQueue () + { + _service.declareQueue(_managementQueueName); + _service.declareBinding( + _managementQueueName, + Names.MANAGEMENT_EXCHANGE, + Names.MANAGEMENT_ROUTING_KEY); + + LOGGER.info(Messages.QMAN_000015_MANAGEMENT_QUEUE_DECLARED,_managementQueueName,_domainModel.getBrokerId()); + } + + /** + * Declares a private queue for receiving method replies (after method invocations). + * This queue is bound to the amq.direct exchange using a routing key equal to the name of the queue. + */ + private void createAndBindMethodReplyQueue () + { + _service.declareQueue(_methodReplyQueueName); + _service.declareBinding(_methodReplyQueueName, Names.AMQ_DIRECT_QUEUE, _methodReplyQueueName); + + LOGGER.info(Messages.QMAN_000016_METHOD_REPLY_QUEUE_DECLARED,_methodReplyQueueName, _domainModel.getBrokerId()); + } + + /** + * Removes the method-reply queue consumer. + */ + private void removeMethodReplyConsumer() + { + _service.removeSubscription(_methodReplyQueueName); + + LOGGER.info(Messages.QMAN_000017_CONSUMER_HAS_BEEN_REMOVED,_methodReplyQueueName,_domainModel.getBrokerId()); + } + + /** + * Unbind the method reply queue and after that destroy it from remote broker. + */ + private void destroyAndUnbingMethodReplyQueue() + { + _service.declareUnbinding(_methodReplyQueueName, Names.AMQ_DIRECT_QUEUE, _methodReplyQueueName); + _service.deleteQueue(_methodReplyQueueName); + + LOGGER.info(Messages.QMAN_000018_QUEUE_UNDECLARED,_methodReplyQueueName,_domainModel.getBrokerId()); + } + + /** + * Removes the management queue consumer. + */ + private void removeManagementConsumer() + { + _service.removeSubscription(_managementQueueName); + + LOGGER.info(Messages.QMAN_000017_CONSUMER_HAS_BEEN_REMOVED,_managementQueueName,_domainModel.getBrokerId()); + } + + /** + * Unbind the management queue and after that destroy it from remote broker. + */ + private void destroyAndUnbingManagementQueue() + { + _service.declareUnbinding(_managementQueueName, Names.MANAGEMENT_EXCHANGE, Names.MANAGEMENT_ROUTING_KEY); + _service.deleteQueue(_managementQueueName); + + LOGGER.info(Messages.QMAN_000018_QUEUE_UNDECLARED, _managementQueueName,_domainModel.getBrokerId()); + } + + /** + * Connects this client with the broker. + * + * @throws QpidException when it's not possibile to connect with the broker. + */ + private void connectWithBroker() throws Exception + { + _service.connect(); + } + + /** + * All the Management client commands are asynchronous. + * Synchronous behavior is achieved through invoking the sync method. + */ + private void synchronize() + { + _service.sync(); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MessageTokenizer.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MessageTokenizer.java new file mode 100644 index 0000000000..9275255517 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MessageTokenizer.java @@ -0,0 +1,152 @@ +/*
+*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.management.domain.services;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.apache.qpid.api.Message;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.nclient.util.ByteBufferMessage;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * The message tokenizer class allows a multi message listener to break a
+ * message into tokens where each token is itself a valid AMQP message.
+ *
+ * @author Andrea Gazzarini
+ * @see QPID-1368
+ */
+class MessageTokenizer implements Enumeration<Message>
+{
+ private final static Logger LOGGER = Logger.get(MessageTokenizer.class);
+
+ static byte [] MAGIC_NUMBER_BYTES;
+
+ private LinkedList<Message> _messages = new LinkedList<Message>();
+ private Iterator<Message> _iterator;
+
+ static
+ {
+ try
+ {
+ MAGIC_NUMBER_BYTES = Protocol.MAGIC_NUMBER.getBytes("UTF-8");
+ } catch(Exception exception)
+ {
+ throw new ExceptionInInitializerError(exception);
+ }
+ }
+
+ /**
+ * Builds a new Message tokenizer with the given message.
+ * Note that if the given message is not a "compound" message this tokenizer will producer only one token;
+ * That is, the token is a message equals to the given message.
+ *
+ * @param compoundMessage the compound message
+ * @throws IOException when it's not possible to read the given message content.
+ */
+ MessageTokenizer(Message compoundMessage) throws IOException
+ {
+ build(compoundMessage);
+ }
+
+ public boolean hasMoreElements()
+ {
+ return _iterator.hasNext();
+ }
+
+ public Message nextElement()
+ {
+ return _iterator.next();
+ }
+
+ /**
+ * Retruns the number of the tokens produced by this tokenizer.
+ *
+ * @return the number of the tokens produced by this tokenizer.
+ */
+ public int countTokens()
+ {
+ return _messages.size();
+ }
+
+ // Internal methods used for splitting the multi message byte array.
+ int indexOf(byte[] source, int startIndex)
+ {
+ int currentSourceIndex;
+ int currentExampleIndex;
+
+ if (startIndex + 3 > source.length)
+ return -1;
+
+ for (currentSourceIndex = startIndex; currentSourceIndex <= source.length - 3; currentSourceIndex++)
+ {
+ for (currentExampleIndex = 0; currentExampleIndex < 3; currentExampleIndex++)
+ {
+ if (source[currentSourceIndex + currentExampleIndex] != MAGIC_NUMBER_BYTES[currentExampleIndex])
+ break;
+ }
+
+ if (currentExampleIndex == 3)
+ return currentSourceIndex;
+ }
+ return -1;
+ }
+
+ // Internal method used for building the tokens.
+ private void build(Message compoundMessage) throws IOException
+ {
+ int startIndex = 0;
+ int indexOfMagicNumber = 0;
+
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(compoundMessage.readData());
+ byte [] source = decoder.readReaminingBytes();
+
+ int howManyTokens = 1;
+
+ while ((indexOfMagicNumber = indexOf(source, startIndex+1)) != -1)
+ {
+ addMessageToken(source, startIndex, (indexOfMagicNumber-startIndex));
+ startIndex = indexOfMagicNumber;
+ howManyTokens++;
+ }
+ addMessageToken(source, startIndex, (source.length-startIndex));
+ _iterator = _messages.iterator();
+
+ LOGGER.debug(Messages.QMAN_200031_COMPOUND_MESSAGE_CONTAINS,howManyTokens);
+ };
+
+ // Builds & adds a new "message" token
+ private void addMessageToken(byte [] source,int startIndex,int length) throws IOException
+ {
+ byte [] messageData = new byte[length];
+ System.arraycopy(source, startIndex, messageData, 0, messageData.length);
+ Message message = new ByteBufferMessage();
+ message.appendData(messageData);
+ _messages.add(message);
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MethodInvocationException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MethodInvocationException.java new file mode 100644 index 0000000000..26fd8eee24 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MethodInvocationException.java @@ -0,0 +1,50 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.services; + +public class MethodInvocationException extends Exception +{ + private static final long serialVersionUID = -7772343434879470351L; + private final long _returnCode; + private final String _statusText; + + public MethodInvocationException(long code, String text) + { + this._returnCode = code; + this._statusText = text; + } + + @Override + public String getMessage () + { + return String.format("Return code : \"%s, reason : \"%s\"",_returnCode,_statusText); + } + + public long getReturnCode () + { + return _returnCode; + } + + public String getStatusText () + { + return _statusText; + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java new file mode 100644 index 0000000000..600b54a6c9 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java @@ -0,0 +1,365 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.services; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.Map.Entry; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.DynamicMBean; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanParameterInfo; +import javax.management.ReflectionException; + +import org.apache.log4j.xml.DOMConfigurator; +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; +import org.apache.qpid.management.configuration.BrokerAlreadyConnectedException; +import org.apache.qpid.management.configuration.BrokerConnectionData; +import org.apache.qpid.management.configuration.BrokerConnectionException; +import org.apache.qpid.management.configuration.Configuration; +import org.apache.qpid.management.configuration.Configurator; +import org.apache.qpid.management.domain.model.JmxService; +import org.apache.qpid.transport.util.Logger; + +/** + * Main entry point for starting Q-Man application. + * + * @author Andrea Gazzarini + */ +public class QMan implements DynamicMBean +{ + private final static Logger LOGGER = Logger.get(QMan.class); + private final List<ManagementClient> managementClients = new ArrayList<ManagementClient>(); + + /** + * Starts QMan. + * @throws StartupFailureException when it's not possible to proceed with startup. + */ + public void start() throws StartupFailureException + { + LOGGER.info(Messages.QMAN_000001_STARTING_QMAN); + LOGGER.info(Messages.QMAN_000002_READING_CONFIGURATION); + + Configurator configurator = new Configurator(); + try + { + configurator.configure(); + Configuration configuration = Configuration.getInstance(); + if (configuration.hasOneOrMoreBrokersDefined()) + { + LOGGER.info(Messages.QMAN_000003_CREATING_MANAGEMENT_CLIENTS); + for (Entry<UUID, BrokerConnectionData> entry : Configuration.getInstance().getConnectionInfos()) + { + createManagementClient(entry.getKey(), entry.getValue()); + } + } else + { + LOGGER.info(Messages.QMAN_000022_NO_BROKER_CONFIGURED); + } + + registerQManService(); + + LOGGER.info(Messages.QMAN_000019_QMAN_STARTED); + } catch(Exception exception) { + LOGGER.error(exception,Messages.QMAN_100018_UNABLE_TO_STARTUP_CORRECTLY ); + throw new StartupFailureException(exception); + } + } + + /** + * Creates a management client using the given data. + * + * @param brokerId the broker identifier. + * @param data the broker connection data. + */ + private void createManagementClient(UUID brokerId, BrokerConnectionData data) + { + try + { + ManagementClient client = new ManagementClient(brokerId,data); + client.estabilishFirstConnectionWithBroker(); + managementClients.add(client); + + LOGGER.info(Messages.QMAN_000004_MANAGEMENT_CLIENT_CONNECTED,brokerId); + } catch(StartupFailureException exception) { + LOGGER.error(exception, Messages.QMAN_100017_UNABLE_TO_CONNECT,brokerId,data); + } + } + + /** + * Connects Q-Man with a broker defined by the given parameter. + * + * @param host the hostname where the broker is running. + * @param port the port where the broker is running. + * @param username the username for connecting with the broker. + * @param password the password for connecting with the broker. + * @param virtualHost the virtual host. + * @param initialPoolCapacity the number of the connection that must be immediately opened. + * @param maxPoolCapacity the maximum number of opened connection. + * @param maxWaitTimeout the maximum amount of time that a client will wait for obtaining a connection. + * @throws MBeanException when it's not possible to connect with the broker. + */ + public void addBroker( + String host, + int port, + String username, + String password, + String virtualHost, + int initialPoolCapacity, + int maxPoolCapacity, + long maxWaitTimeout) throws BrokerAlreadyConnectedException, BrokerConnectionException + { + Configurator configurator = new Configurator(); + try { + UUID brokerId = UUID.randomUUID(); + BrokerConnectionData data = configurator.createAndReturnBrokerConnectionData( + brokerId, + host, + port, + username, + password, + virtualHost, + initialPoolCapacity, + maxPoolCapacity, + maxWaitTimeout); + createManagementClient(brokerId, data); + } catch (BrokerAlreadyConnectedException exception) + { + LOGGER.warn(Messages.QMAN_300003_BROKER_ALREADY_CONNECTED, exception.getBrokerConnectionData()); + throw exception; + } + } + + /** + * Stop Qman + */ + public void stop() + { + LOGGER.info(Messages.QMAN_000020_SHUTTING_DOWN_QMAN); + try + { + for (ManagementClient client : managementClients) + { + client.shutdown(); + } + } catch(Exception exception) + { + } + LOGGER.info(Messages.QMAN_000021_SHUT_DOWN); + } + + /** + * Main method used for starting Q-Man. + * + * @param args the command line arguments. + */ + public static void main (String[] args) + { + if (args.length == 1) + { + String logFileName = args[0]; + DOMConfigurator.configureAndWatch(logFileName,5000); + } + + final QMan qman = new QMan(); + + Thread hook = new Thread() + { + @Override + public void run () + { + qman.stop(); + } + }; + + Runtime.getRuntime().addShutdownHook(hook); + try + { + qman.start(); + + System.out.println("Type \"q\" to quit."); + BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + while ( !"q".equals(reader.readLine()) ) + { + + } + Runtime.getRuntime().removeShutdownHook(hook); + qman.stop(); + System.exit(-1); + } catch (StartupFailureException exception) + { + qman.stop(); + System.exit(-1); + } catch (IOException exception) + { + System.exit(-1); + } + } + + /** + * Not implemented for this MBean. + */ + public Object getAttribute(String attribute) + { + return null; + } + + /** + * Not implemented for this MBean. + */ + public AttributeList getAttributes(String[] attributes) + { + return null; + } + + /** + * Returns the metadata for this MBean + * + * @return the metadata for this MBean + */ + public MBeanInfo getMBeanInfo() + { + MBeanParameterInfo parameters [] = new MBeanParameterInfo[8]; + + parameters[0] = new MBeanParameterInfo( + "host", + String.class.getName(), + "The IP address or DNS name that Qpid Broker uses to listen for incoming connections."); + parameters[1] = new MBeanParameterInfo( + "port", + int.class.getName(), + "The port number that Qpid Broker uses to listen for incoming connections."); + parameters[2] = new MBeanParameterInfo( + "username", + String.class.getName(), + "The Qpid account name used in the physical connection."); + parameters[3] = new MBeanParameterInfo( + "password", + String.class.getName(), + "The Qpid account password used in the physical connection."); + parameters[4]= new MBeanParameterInfo( + "virtualHost", + String.class.getName(), + "The virtualHost name."); + parameters[5]= new MBeanParameterInfo( + "initialPoolCapacity", + int.class.getName(), + "The number of physical connections (between 0 and a positive 32-bit integer) to create when creating the (Qpid) connection pool."); + parameters[6]= new MBeanParameterInfo( + "maxPoolCapacity", + int.class.getName(), + "The maximum number of physical database connections (between 0 and a positive 32-bit integer) that the (Qpid) connection pool can contain. "); + parameters[7]= new MBeanParameterInfo( + "maxWaitTimeout", + long.class.getName(), + "The maximum amount of time to wait for an idle connection.A value of -1 indicates an illimted amount of time (i.e. forever)"); + + MBeanOperationInfo operation = new MBeanOperationInfo( + "addBroker", + "Connects QMan with a broker.", + parameters, + void.class.getName(), + MBeanOperationInfo.ACTION); + + MBeanInfo mbean = new MBeanInfo( + QMan.class.getName(), + "QMan Management & Administration interface.", + null, + null, + new MBeanOperationInfo[]{operation}, + null); + + return mbean; + } + + /** + * Invokes an operation on QMan (MBean). + * + * @param actionName the operation name. + * @param params the operation parameters. + * @param signature the operation signature. + * @return the result of the invocation (if the operation is not void); + * @exception MBeanException Wraps a <CODE>java.lang.Exception</CODE> thrown by the MBean's invoked method. + * @exception ReflectionException Wraps a <CODE>java.lang.Exception</CODE> thrown while trying to invoke the method + */ + public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException + { + if (Names.ADD_BROKER_OPERATION_NAME.equals(actionName)) + { + try + { + addBroker( + (String)params[0], + (Integer)params[1], + (String)params[2], + (String)params[3], + (String)params[4], + (Integer)params[5], + (Integer)params[6], + (Long)params[7]); + } catch(Exception exception) + { + throw new MBeanException(exception); + } + } else + { + throw new ReflectionException(new NoSuchMethodException(actionName)); + } + return null; + } + + /** + * Not implemented for this MBean. + */ + public void setAttribute(Attribute attribute) + { + } + + /** + * Not implemented for this MBean. + */ + public AttributeList setAttributes(AttributeList attributes) + { + return null; + } + + /** + * Registers QMan as an MBean on MBeanServer. + * + * @throws MBeanException when it's not possible to proceeed with registration. + */ + private void registerQManService() throws MBeanException + { + JmxService service = new JmxService(); + service.registerQManService(this); + + LOGGER.info(Messages.QMAN_000023_QMAN_REGISTERED_AS_MBEAN); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java new file mode 100644 index 0000000000..a12993d40e --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java @@ -0,0 +1,360 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.services; + +import java.io.IOException; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.qpid.QpidException; +import org.apache.qpid.api.Message; +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; +import org.apache.qpid.management.configuration.QpidDatasource; +import org.apache.qpid.management.domain.model.QpidMethod; +import org.apache.qpid.management.domain.model.type.Binary; +import org.apache.qpid.management.messages.MethodInvocationRequestMessage; +import org.apache.qpid.management.messages.SchemaRequestMessage; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.nclient.util.MessagePartListenerAdapter; +import org.apache.qpid.transport.Connection; +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; +import org.apache.qpid.transport.MessageCreditUnit; +import org.apache.qpid.transport.MessageTransfer; +import org.apache.qpid.transport.Option; +import org.apache.qpid.transport.Session; +import org.apache.qpid.transport.SessionException; +import org.apache.qpid.transport.SessionListener; +import org.apache.qpid.transport.util.Logger; + +/** + * Qpid Broker facade. + * + * @author Andrea Gazzarini + */ +public class QpidService implements SessionListener +{ + private final static Logger LOGGER = Logger.get(QpidService.class); + + private UUID _brokerId; + private Connection _connection; + private Session _session; + private Map<String,MessagePartListenerAdapter> _listeners; + + /** + * Builds a new service with the given connection data. + * + * @param connectionData the connection data of the broker. + */ + public QpidService(UUID brokerId) + { + this._brokerId = brokerId; + } + + /** + * Estabilishes a connection with the broker. + * + * @throws QpidException in case of connection failure. + */ + public void connect() throws Exception + { + _connection = QpidDatasource.getInstance().getConnection(_brokerId); + _listeners = new ConcurrentHashMap<String,MessagePartListenerAdapter>(); + _session = _connection.createSession(0); + _session.setSessionListener(this); + } + + public void opened(Session ssn) {} + + public void message(Session ssn, MessageTransfer xfr) + { + MessagePartListenerAdapter l = _listeners.get(xfr.getDestination()); + if (l == null) + { + LOGGER.error("unhandled message: %s", xfr); + } + else + { + l.messageTransfer(xfr); + } + } + + + public void exception(Session ssn, SessionException exc) + { + + } + + public void closed(Session ssn) {} + + /** + * All the previously entered outstanding commands are asynchronous. + * Synchronous behavior is achieved through invoking this method. + */ + public void sync() + { + _session.sync(); + } + + /** + * Closes communication with broker. + */ + public void close() + { + try + { + _session.close(); + _session = null; + _listeners = null; + } catch (Exception e) + { + } + try + { + _connection.close(); + _connection = null; + } catch (Exception e) + { + } + } + + /** + * Associate a message listener with a destination therefore creating a new subscription. + * + * @param queueName The name of the queue that the subscriber is receiving messages from. + * @param destinationName the name of the destination, or delivery tag, for the subscriber. + * @param listener the listener for this destination. + * + * @see Session#messageSubscribe(String, String, short, short, org.apache.qpid.nclient.MessagePartListener, java.util.Map, org.apache.qpid.transport.Option...) + */ + public void createSubscription(String queueName, String destinationName, MessageListener listener) + { + _listeners.put(destinationName, new MessagePartListenerAdapter(listener)); + _session.messageSubscribe + (queueName, + destinationName, + MessageAcceptMode.NONE, + MessageAcquireMode.PRE_ACQUIRED, + null, 0, null); + + _session.messageFlow(destinationName, MessageCreditUnit.BYTE, Session.UNLIMITED_CREDIT); + _session.messageFlow(destinationName, MessageCreditUnit.MESSAGE, Session.UNLIMITED_CREDIT); + + LOGGER.debug(Messages.QMAN_200025_SUBSCRIPTION_DECLARED,queueName,destinationName); + } + + /** + * Removes a previously declared consumer from the broker. + * + * @param destinationName the name of the destination, or delivery tag, for the subscriber. + * @see Session#messageCancel(String, Option...) + */ + public void removeSubscription(String destinationName) + { + _session.messageCancel(destinationName); + LOGGER.debug(Messages.QMAN_200026_SUBSCRIPTION_REMOVED,destinationName); + } + + /** + * Declares a queue on the broker with the given name. + * + * @param queueName the name of the declared queue. + * @see Session#queueDeclare(String, String, java.util.Map, Option...) + */ + public void declareQueue(String queueName) + { + _session.queueDeclare(queueName, null, null); + LOGGER.debug(Messages.QMAN_200027_QUEUE_DECLARED,queueName); + } + + /** + * Removes the queue with the given name from the broker. + * + * @param queueName the name of the queue. + * @see Session#queueDelete(String, Option...) + */ + public void deleteQueue(String queueName) + { + _session.queueDelete(queueName); + LOGGER.debug(Messages.QMAN_200028_QUEUE_REMOVED,queueName); + } + + /** + * Binds (on the broker) a queue with an exchange. + * + * @param queueName the name of the queue to bind. + * @param exchangeName the exchange name. + * @param routingKey the routing key used for the binding. + * @see Session#exchangeBind(String, String, String, java.util.Map, Option...) + */ + public void declareBinding(String queueName, String exchangeName, String routingKey) + { + _session.exchangeBind(queueName, exchangeName, routingKey, null); + LOGGER.debug(Messages.QMAN_200029_BINDING_DECLARED,routingKey,queueName,exchangeName); + } + + /** + * Removes a previously declare binding between an exchange and a queue. + * + * @param queueName the name of the queue. + * @param exchangeName the name of the exchange. + * @param routingKey the routing key used for binding. + */ + public void declareUnbinding(String queueName, String exchangeName, String routingKey) + { + _session.exchangeUnbind(queueName, exchangeName, routingKey); + LOGGER.debug(Messages.QMAN_200030_BINDING_REMOVED,routingKey,queueName,exchangeName); + } + + /** + * Sends a command message with the given data on the management queue. + * + * @param messageData the command message content. + */ + + /** + * Requests a schema for the given package.class.hash. + * + * @param packageName the package name. + * @param className the class name. + * @param schemaHash the schema hash. + * @throws IOException when the schema request cannot be sent. + */ + public void requestSchema(final String packageName, final String className, final Binary schemaHash) throws IOException + { + Message message = new SchemaRequestMessage() + { + @Override + protected String className () + { + return className; + } + + @Override + protected String packageName () + { + return packageName; + } + + @Override + protected Binary schemaHash () + { + return schemaHash; + } + }; + + sendMessage(message); + } + + /** + * Invokes an operation on a broker object instance. + * + * @param packageName the package name. + * @param className the class name. + * @param schemaHash the schema hash of the corresponding class. + * @param objectId the object instance identifier. + * @param parameters the parameters for this invocation. + * @param method the method (definition) invoked. + * @param bankId the object bank identifier. + * @param brokerId the broker identifier. + * @return the sequence number used for this message. + * @throws MethodInvocationException when the invoked method returns an error code. + * @throws UnableToComplyException when it wasn't possibile to invoke the requested operation. + */ + public void invoke( + final String packageName, + final String className, + final Binary schemaHash, + final Binary objectId, + final Object[] parameters, + final QpidMethod method, + final int sequenceNumber, + final long bankId, + final long brokerId) throws MethodInvocationException, UnableToComplyException + { + Message message = new MethodInvocationRequestMessage(bankId, brokerId) + { + + @Override + protected int sequenceNumber () + { + return sequenceNumber; + } + + protected Binary objectId() { + return objectId; + } + + protected String packageName() + { + return packageName; + } + + protected String className() + { + return className; + } + + @Override + protected QpidMethod method () + { + return method; + } + + @Override + protected Object[] parameters () + { + return parameters; + } + + @Override + protected Binary schemaHash () + { + return schemaHash; + } + }; + + try { + sendMessage(message); + sync(); + } catch(Exception exception) { + throw new UnableToComplyException(exception); + } + } + + /** + * Sends a command message. + * + * @param message the command message. + * @throws IOException when the message cannot be sent. + */ + public void sendMessage(Message message) throws IOException + { + _session.messageTransfer( + Names.MANAGEMENT_EXCHANGE, + MessageAcceptMode.EXPLICIT, + MessageAcquireMode.PRE_ACQUIRED, + message.getHeader(), + message.readData()); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/SequenceNumberGenerator.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/SequenceNumberGenerator.java new file mode 100644 index 0000000000..e6d99971cd --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/SequenceNumberGenerator.java @@ -0,0 +1,41 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.services; + +/** + * Sequence number generator utility class. + * + * @author Andrea Gazzarini + */ +public class SequenceNumberGenerator +{ + private static int sequenceNumber; + + /** + * Returns a valid sequence number. + * + * @return a sequence number. + */ + public static synchronized int getNextSequenceNumber() + { + return sequenceNumber++; + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/StartupFailureException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/StartupFailureException.java new file mode 100644 index 0000000000..9da8832624 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/StartupFailureException.java @@ -0,0 +1,42 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.services; + +/** + * Thrown in case of service startup failure. + * For example the configuration file couldn't be read because is not well-formed. + * + * @author Andrea Gazzarini. + */ +public class StartupFailureException extends Exception +{ + private static final long serialVersionUID = -4102037574602857703L; + + /** + * Builds a new StartupFailureException with the given exception. + * + * @param exception the exception cause. + */ + public StartupFailureException(Exception exception) + { + super(exception); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/UnableToComplyException.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/UnableToComplyException.java new file mode 100644 index 0000000000..2ab9a41e75 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/UnableToComplyException.java @@ -0,0 +1,31 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.services; + +public class UnableToComplyException extends Exception +{ + public UnableToComplyException(Exception exception) + { + super(exception); + } + + private static final long serialVersionUID = -3071434478559509435L; +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java new file mode 100644 index 0000000000..4d1dfe796a --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java @@ -0,0 +1,178 @@ +/* +* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.management.messages; + +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; + +/** + * AMQP Management messages codec. + * + * @author Andrea Gazzarini + */ +public class AmqpCoDec +{ + private byte [] _buffer; + private int _position; + + /** + * Builds a new codec. + */ + AmqpCoDec() + { + _buffer = new byte [1000]; + _buffer[0] = 'A'; + _buffer[1] = 'M'; + _buffer[2] = '2'; + _position = 3; + } + + + /** + * Int32-to-4 byte array marshalling. + * Marshalles an integer using four bytes. + * + * @param data the result array. + * @param pos the starting position of the array to be filled. + * @param value the value to be marshalled. + */ + public final void pack32(int value) { + _buffer[_position++] = (byte) (value >> 24 & 0xff); + _buffer[_position++] = (byte) (value >> 16 & 0xff); + _buffer[_position++] = (byte) (value >> 8 & 0xff); + _buffer[_position++] = (byte) (value & 0xff); + } + + /** + * Int32-to-4 byte array marshalling. + * Marshalles an integer using four bytes. + * + * @param data the result array. + * @param pos the starting position of the array to be filled. + * @param value the value to be marshalled. + */ + public final void pack16(int value) { + _buffer[_position++] = (byte) (value >> 8 & 0xff); + _buffer[_position++] = (byte) (value & 0xff); + } + + /** + * Int32-to-4 byte array marshalling. + * Marshalles an integer using four bytes. + * + * @param data the result array. + * @param pos the starting position of the array to be filled. + * @param value the value to be marshalled. + */ + public final void pack64(long value) { + _buffer[_position++] = (byte) (value >> 56 & 0xff); + _buffer[_position++] = (byte) (value >> 48 & 0xff); + _buffer[_position++] = (byte) (value >> 40 & 0xff); + _buffer[_position++] = (byte) (value >> 32 & 0xff); + _buffer[_position++] = (byte) (value >> 24 & 0xff); + _buffer[_position++] = (byte) (value >> 16 & 0xff); + _buffer[_position++] = (byte) (value >> 8 & 0xff); + _buffer[_position++] = (byte) (value & 0xff); + } + + /** + * Int32-to-byte array marshalling. + * Marshalles an integer using two bytes. + * + * @param data the result array. + * @param pos the starting position of the array to be filled. + * @param value the value to be marshalled. + */ + public final void pack24(int value) { + _buffer[_position++] = (byte) (value >> 16 & 0xff); + _buffer[_position++] = (byte) (value >> 8 & 0xff); + _buffer[_position++] = (byte) (value & 0xff); + } + + public final void pack8(int value) { + _buffer[_position++] = (byte) (value & 0xff); + } + + public void pack8 (byte aByte) + { + _buffer[_position++] = aByte; + } + + public void packStr8(String aString) + { + try + { + byte [] toBytes = aString.getBytes("UTF-8"); + int length = toBytes.length; + pack8(length); + System.arraycopy(toBytes, 0, _buffer, _position, length); + _position+=length; + } catch (UnsupportedEncodingException exception) + { + throw new RuntimeException(exception); + } + } + + public void packStr16(String aString) + { + try + { + byte [] toBytes = aString.getBytes("UTF-8"); + int length = toBytes.length; + pack16(length); + System.arraycopy(toBytes, 0, _buffer, _position, length); + _position+=length; + } catch (UnsupportedEncodingException exception) + { + throw new RuntimeException(exception); + } + } + + public static final long unpack64(byte data[]) { + return ( + ((long) (data[0] & 0xff) << 56) | + ((long)(data[1] & 0xff) << 48) | + ((long)(data[2] & 0xff) << 40) | + ((long)(data[3] & 0xff) << 32) | + ((long)(data[4] & 0xff) << 24) | + ((long)(data[5] & 0xff) << 16) | + ((long)(data[6] & 0xff) << 8) | + (long) data[7] & 0xff); + } + + + public void pack (byte[] bytes) + { + System.arraycopy(bytes, 0, _buffer, _position, bytes.length); + _position+=bytes.length; + } + + /** + * Retruns the byte buffer that is wrapping the backing array of this codec. + * + * @return the byte buffer that is wrapping the backing array of this codec. + */ + public ByteBuffer getEncodedBuffer () + { + return ByteBuffer.wrap(_buffer,0,_position); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/ManagementMessage.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/ManagementMessage.java new file mode 100644 index 0000000000..2fa20fb456 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/ManagementMessage.java @@ -0,0 +1,189 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.messages; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import org.apache.qpid.api.Message; +import org.apache.qpid.management.configuration.Configuration; +import org.apache.qpid.management.domain.services.SequenceNumberGenerator; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.codec.BBEncoder; + +/** + * Message implementation used for specific management purposes. + * + * @author Andrea Gazzarini + */ +public abstract class ManagementMessage implements Message +{ + /** + * Strategy interface for building / getting data. + * + * @author Andrea Gazzarini + */ + private interface IDataBuilderStrategy + { + ByteBuffer getData(); + }; + + /** + * Strategy used for retrieving raw data from this message when it has been already encoded. + */ + IDataBuilderStrategy READING = new IDataBuilderStrategy() + { + public ByteBuffer getData() { + return _data; + }; + }; + + /** + * Strategy used for retrieving raw data from this message when it hasn't been already encoded. + */ + IDataBuilderStrategy ACCUMULATING = new IDataBuilderStrategy() + { + public ByteBuffer getData() { + _codec.writeInt8((byte)opcode()); + _codec.writeSequenceNo(sequenceNumber()); + + specificMessageEncoding(); + + _data =_codec.segment(); + _reader = READING; + return _data; + } + }; + + protected BBEncoder _codec; + protected ByteBuffer _data; + private int _messageTransferId; + private IDataBuilderStrategy _reader = ACCUMULATING; + + /** + * Builds an empty management message. + */ + ManagementMessage() + { + _codec = new BBEncoder(100); + _codec.writeMagicNumber(); + } + + /** + * Returns the sequence number that will be used for this message. + * + * @return the sequence number that will be used for this message. + */ + protected int sequenceNumber () + { + return SequenceNumberGenerator.getNextSequenceNumber(); + } + + /** + * Returns the opcode that will be used for this message. + * + * @return the opcode that will be used for this message. + */ + abstract char opcode (); + + /** + * Returns the delivery properties of this message. + * + * @return the delivery properties of this message. + */ + public DeliveryProperties getDeliveryProperties () + { + return Configuration.getInstance().getCommandDeliveryProperties(); + } + + /** + * Returns the header of this message. + * + * @return the header of this message. + */ + public Header getHeader () + { + return Configuration.getInstance().getCommandMessageHeader(); + } + + /** + * Returns the messages header properties of this message. + * + * @return the message header properties of this message. + */ + public MessageProperties getMessageProperties () + { + return Configuration.getInstance().getCommandMessageProperties(); + } + + /** + * Returns the transfer Id of this message. + * + * @return the transfer Id of this message. + */ + public int getMessageTransferId () + { + return _messageTransferId; + } + + /** + * Returns the encoded data of this message. + * + * @return the encoded data of this message. + */ + public ByteBuffer readData () throws IOException + { + return _reader.getData(); + } + + /** + * Sets the header for this message. + * + * @param header the new message header. + */ + public void setHeader (Header header) + { + // N.A. at the moment. + } + + public void appendData (byte[] src) throws IOException + { + } + + public void appendData (ByteBuffer src) throws IOException + { + } + + public void clearData () + { + } + + public void readData (byte[] target) throws IOException + { + } + + /** + * Concrete subclasses (message implementations) must define here their specific data encoding. + */ + abstract void specificMessageEncoding(); +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/MethodInvocationRequestMessage.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/MethodInvocationRequestMessage.java new file mode 100644 index 0000000000..99916085d6 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/MethodInvocationRequestMessage.java @@ -0,0 +1,161 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.messages; + +import org.apache.qpid.management.Messages; +import org.apache.qpid.management.Names; +import org.apache.qpid.management.Protocol; +import org.apache.qpid.management.configuration.Configuration; +import org.apache.qpid.management.domain.model.QpidMethod; +import org.apache.qpid.management.domain.model.type.Binary; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.ReplyTo; +import org.apache.qpid.transport.util.Logger; + +/** + * Abstract representation of a method invocation request message. + * Concrete subclasses must supply the values needed to build & encode the message. + * + * @author Andrea Gazzarini + */ +public abstract class MethodInvocationRequestMessage extends ManagementMessage +{ + private final static Logger LOGGER = Logger.get(MethodInvocationRequestMessage.class); + + private DeliveryProperties _deliveryProperties; + private MessageProperties _messageProperties; + private Header _header; + + /** + * Builds a new method invocation request message with the given target identifiers. + * + * @param bankId the bank identifier. + * @param brokerId the broker identifier. + */ + public MethodInvocationRequestMessage(long bankId, long brokerId) + { + ReplyTo replyTo=new ReplyTo(); + replyTo.setRoutingKey(Configuration.getInstance().getMethodReplyQueueName()); + _messageProperties = new MessageProperties(); + _messageProperties.setReplyTo(replyTo); + + String routingKey = String.format(Names.AGENT_ROUTING_KEY_PREFIX+"%s.%s", brokerId,bankId); + + LOGGER.debug(Messages.QMAN_200032_COMMAND_MESSAGE_ROUTING_KEY, routingKey); + + _deliveryProperties = new DeliveryProperties(); + _deliveryProperties.setRoutingKey(routingKey); + _header = new Header(_deliveryProperties, _messageProperties); + } + + @Override + char opcode () + { + return Protocol.OPERATION_INVOCATION_REQUEST_OPCODE; + } + + /** + * Returns the package name. + * + * @return the package name. + */ + protected abstract String packageName(); + + /** + * Returns the class name. + * + * @return the class name. + */ + protected abstract String className(); + + /** + * Returns the schema hash. + * + * @return the schema hash. + */ + protected abstract Binary schemaHash(); + + /** + * Returns the object identifier. + * + * @return the object identifier. + */ + protected abstract Binary objectId(); + + /** + * Returns the method to be invoked. + * + * @return the method to be invoked. + */ + protected abstract QpidMethod method(); + + /** + * Returns the parameters used for method invocation. + * + * @return the parameters used for method invocation. + */ + protected abstract Object[] parameters(); + + /** + * Returns the delivery properties of this message. + * + * @return the delivery properties of this message. + */ + public DeliveryProperties getDeliveryProperties () + { + return _deliveryProperties; + } + + /** + * Returns the header of this message. + * + * @return the header of this message. + */ + public Header getHeader () + { + return _header; + } + + /** + * Returns the messages header properties of this message. + * + * @return the message header properties of this message. + */ + public MessageProperties getMessageProperties () + { + return _messageProperties; + } + + @Override + void specificMessageEncoding () + { + objectId().encode(_codec); + _codec.writeStr8(packageName()); + _codec.writeStr8(className()); + schemaHash().encode(_codec); + + QpidMethod method = method(); + _codec.writeStr8(method.getName()); + method.encodeParameters(parameters(), _codec); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/SchemaRequestMessage.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/SchemaRequestMessage.java new file mode 100644 index 0000000000..9df1733649 --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/SchemaRequestMessage.java @@ -0,0 +1,68 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.messages; + +import org.apache.qpid.management.Protocol; +import org.apache.qpid.management.domain.model.type.Binary; + +/** + * Abstract representation of a schema request message. + * Concrete subclasses must supply the values needed to build & encode the message. + * + * @author Andrea Gazzarini + */ +public abstract class SchemaRequestMessage extends ManagementMessage +{ + @Override + char opcode () + { + return Protocol.SCHEMA_REQUEST_OPCODE; + } + + /** + * Returns the package name. + * + * @return the package name. + */ + protected abstract String packageName(); + + /** + * Returns the class name. + * + * @return the class name. + */ + protected abstract String className(); + + /** + * Returns the schema hash. + * + * @return the schema hash. + */ + protected abstract Binary schemaHash(); + + @Override + final void specificMessageEncoding () + { + _codec.writeStr8(packageName()); + _codec.writeStr8(className()); + schemaHash().encode(_codec); + } +} diff --git a/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManServlet.java b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManServlet.java new file mode 100644 index 0000000000..f0d663701b --- /dev/null +++ b/RC9/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManServlet.java @@ -0,0 +1,66 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.servlet;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+
+import org.apache.qpid.management.domain.services.QMan;
+import org.apache.qpid.management.domain.services.StartupFailureException;
+
+/**
+ * QMan initializer.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QManServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 6149614872902682208L;
+
+ // QMan instance
+ private QMan qman;
+
+ /**
+ * Initializes QMan instance.
+ *
+ * @throws ServletException when It's not possibile to proceed with initialization.
+ */
+ @Override
+ public void init() throws ServletException
+ {
+ qman = new QMan();
+ try {
+ qman.start();
+ } catch (StartupFailureException exception)
+ {
+ throw new ServletException(exception);
+ }
+ }
+
+ /**
+ * Stops QMan instance.
+ */
+ @Override
+ public void destroy()
+ {
+ qman.stop();
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java new file mode 100644 index 0000000000..5855a3e60b --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java @@ -0,0 +1,64 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject; +import org.apache.qpid.management.domain.model.DomainModel; +import org.apache.qpid.management.domain.model.type.Binary; + +public interface TestConstants +{ + UUID BROKER_ID = UUID.randomUUID(); + Binary OBJECT_ID = new Binary(new byte []{1,2,3,2,1,1,2,3}); + + DomainModel DOMAIN_MODEL = new DomainModel(BROKER_ID); + + String AGE_ATTRIBUTE_NAME = "age"; + String AGE_ATTRIBUTE_DESCRIPTION = "The age of a person."; + String SURNAME_ATTRIBUTE_NAME = "surname"; + String SURNAME_ATTRIBUTE_DESCRIPTION = "The surname of a person."; + Integer _1 = new Integer(1); + + byte [] TEST_RAW_DATA= new byte []{1,4,5,7,8,9,4,44}; + long NOW = System.currentTimeMillis(); + int SEVERITY = _1; + + String QPID_PACKAGE_NAME = "qpid"; + String EXCHANGE_CLASS_NAME = "exchange"; + String BIND_EVENT_NAME = "bind"; + Binary HASH = new Binary(new byte []{1,2,3,4,5,6,7,8,9}); + int VALID_CODE = _1; + + List<Map<String, Object>> EMPTY_PROPERTIES_SCHEMA = new LinkedList<Map<String,Object>>(); + List<Map<String, Object>> EMPTY_STATISTICS_SCHEMA = new LinkedList<Map<String,Object>>(); + List<MethodOrEventDataTransferObject> EMPTY_METHODS_SCHEMA = new LinkedList<MethodOrEventDataTransferObject>(); + List<Map<String, Object>> EMPTY_ARGUMENTS_SCHEMA = new LinkedList<Map<String,Object>>(); + int _0 = 0; + int SAMPLE_ACCESS_CODE = 1; + String YEARS = "years"; + int SAMPLE_MIN_VALUE = 1; + int SAMPLE_MAX_VALUE = 120; +} diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java new file mode 100644 index 0000000000..efd5990bd7 --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java @@ -0,0 +1,229 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.management.TestConstants; +import org.apache.qpid.management.domain.handler.base.IMessageHandler; +import org.apache.qpid.management.domain.handler.impl.ConfigurationMessageHandler; +import org.apache.qpid.management.domain.handler.impl.InstrumentationMessageHandler; +import org.apache.qpid.management.domain.handler.impl.SchemaResponseMessageHandler; +import org.apache.qpid.management.domain.model.AccessMode; +import org.apache.qpid.management.domain.model.type.Type; +import org.apache.qpid.management.domain.model.type.Uint8; + +import junit.framework.TestCase; + +/** + * Test case for Configuration singleton. + * + * @author Andrea Gazzarini + */ +public class ConfigurationTest extends TestCase +{ + /** + * Tests the singleton behaviour of the configuration object. + */ + public void testSingleton() + { + assertSame(Configuration.getInstance(),Configuration.getInstance()); + } + + /** + * Tests the execution of getType() method when a valid code is supplied. + * + * <br>precondition : the requested type already exist on the configuration. + * <br>postcondition : the requested type is returned and no exception is thrown. + */ + public void testGetTypeOk() throws UnknownTypeCodeException + { + TypeMapping mapping = new TypeMapping(TestConstants.VALID_CODE,new Uint8()); + Configuration.getInstance().addTypeMapping(mapping); + Type type = Configuration.getInstance().getType(TestConstants.VALID_CODE); + + assertTrue(type instanceof Uint8); + } + + /** + * Tests the execution of getType() method when a unknown code is supplied. + * + * <br>precondition : the requested type doesn't exist on the configuration. + * <br>postcondition : an exception is thrown indicating the failure. + */ + public void testGetTypeKO() + { + try + { + Configuration.getInstance().getType(Integer.MIN_VALUE); + fail("If an unknwon code is supplied an exception must be thrown."); + } catch (UnknownTypeCodeException expected) + { + assertEquals(Integer.MIN_VALUE,expected.getCode()); + } + } + + /** + * Tests the execution of getAccessMode() method when a valid code is supplied. + * + * <br>precondition : the requested access mode already exist on the configuration. + * <br>postcondition : the requested access mode is returned and no exception is thrown. + */ + public void testGetAccessModeOk() throws UnknownAccessCodeException + { + AccessModeMapping mapping = new AccessModeMapping(TestConstants.VALID_CODE,AccessMode.RW); + Configuration.getInstance().addAccessModeMapping(mapping); + AccessMode accessMode = Configuration.getInstance().getAccessMode(TestConstants.VALID_CODE); + + assertSame(AccessMode.RW,accessMode); + } + + /** + * Tests the execution of getAccessMode() method when a unknown code is supplied. + * + * <br>precondition : the requested access mode doesn't exist on the configuration. + * <br>postcondition : an exception is thrown indicating the failure. + */ + public void testGetAccessModeKO() + { + try + { + Configuration.getInstance().getAccessMode(Integer.MIN_VALUE); + fail("If an unknwon code is supplied an exception must be thrown."); + } catch (UnknownAccessCodeException expected) + { + assertEquals(Integer.MIN_VALUE,expected.getCode()); + } + } + + /** + * Tests the execution of the getBrokerConnectionData when a valid broker id is supplied. + * + * <br>precondition : on configuration a connection data is stored and associated with the supplied id. + * <br>postcondition : the requested connection data is returned and no exception is thrown. + */ + public void testGetBrokerConnectionDataOK() throws Exception + { + BrokerConnectionData connectionData = new BrokerConnectionData(); + connectionData.setHost("host"); + connectionData.setPort("7001"); + connectionData.setInitialPoolCapacity("0"); + connectionData.setMaxPoolCapacity("10"); + connectionData.setMaxWaitTimeout("1"); + Configuration.getInstance().addBrokerConnectionData(TestConstants.BROKER_ID, connectionData); + + BrokerConnectionData result = Configuration.getInstance().getBrokerConnectionData(TestConstants.BROKER_ID); + assertSame(connectionData, result); + } + + /** + * Tests the execution of the getBrokerConnectionData when a unknown broker id is supplied. + * + * <br>precondition : on configuration there's no connection data associated with the supplied id. + * <br>postcondition : an exception is thrown indicating the failure. + */ + public void testGetBrokerConnectionDataKO_withUnknownBrokerId() + { + UUID brokerId = UUID.randomUUID(); + try + { + Configuration.getInstance().getBrokerConnectionData(brokerId); + fail("If an unknown broker id is supplied then an exception must be thrown."); + } catch(UnknownBrokerException expected) + { + assertEquals(brokerId.toString(),expected.getMessage()); + } + } + + /** + * Tests the execution of the getBrokerConnectionData when a null id is supplied. + * + * <br>precondition : a null broker is given. + * <br>postcondition : an exception is thrown indicating the failure. + */ + public void testGetBrokerConnectionDataKO_withNullBrokerId() + { + try + { + Configuration.getInstance().getBrokerConnectionData(null); + fail("If a null broker id is supplied then an exception must be thrown."); + } catch(UnknownBrokerException expected) + { + } + } + + /** + * Tests the behaviour of the getManagementQueueHandlers() method. + * + * <br>precondition: 2 management handlers are in stored configuration + * <br>postcondition : 2 management handlers are returned. + */ + public void testGetManagementQueueHandlersOk() + { + String i = "i"; + String c = "c"; + + String instrMessageHandlerClassName = InstrumentationMessageHandler.class.getName(); + String configMessageHandlerClassName = ConfigurationMessageHandler.class.getName(); + + MessageHandlerMapping instrMapping = new MessageHandlerMapping(); + MessageHandlerMapping configMapping = new MessageHandlerMapping(); + + instrMapping.setOpcode(i); + instrMapping.setMessageHandlerClass(instrMessageHandlerClassName); + + configMapping.setOpcode(c); + configMapping.setMessageHandlerClass(configMessageHandlerClassName); + + Configuration.getInstance().addManagementMessageHandlerMapping(instrMapping); + Configuration.getInstance().addManagementMessageHandlerMapping(configMapping); + + Map<Character, IMessageHandler> handlerMappings = Configuration.getInstance().getManagementQueueHandlers(); + + assertEquals(instrMessageHandlerClassName,handlerMappings.get(instrMapping.getOpcode()).getClass().getName()); + assertEquals(configMessageHandlerClassName,handlerMappings.get(configMapping.getOpcode()).getClass().getName()); + } + + /** + * Tests the behaviour of the getManagementQueueHandlers() method. + * + * <br>precondition: 2 management handlers are in stored configuration + * <br>postcondition : 2 management handlers are returned. + */ + public void testGetMethodReplyQueueHandlersOk() + { + String s = "s"; + + String schemaMessageHandlerClassName = SchemaResponseMessageHandler.class.getName(); + + MessageHandlerMapping schemaMapping = new MessageHandlerMapping(); + + schemaMapping.setOpcode(s); + schemaMapping.setMessageHandlerClass(schemaMessageHandlerClassName); + + Configuration.getInstance().addMethodReplyMessageHandlerMapping(schemaMapping); + + Map<Character, IMessageHandler> handlerMappings = Configuration.getInstance().getMethodReplyQueueHandlers(); + + assertEquals(schemaMessageHandlerClassName,handlerMappings.get(schemaMapping.getOpcode()).getClass().getName()); + } +} diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java new file mode 100644 index 0000000000..6237f21cc9 --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java @@ -0,0 +1,164 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +import java.util.Map; +import java.util.UUID; + +import junit.framework.TestCase; + +import org.apache.qpid.management.Names; +import org.apache.qpid.management.Protocol; +import org.apache.qpid.management.domain.handler.base.IMessageHandler; +import org.apache.qpid.management.domain.handler.impl.ConfigurationMessageHandler; +import org.apache.qpid.management.domain.handler.impl.EventContentMessageHandler; +import org.apache.qpid.management.domain.handler.impl.HeartBeatIndicationMessageHandler; +import org.apache.qpid.management.domain.handler.impl.InstrumentationMessageHandler; +import org.apache.qpid.management.domain.handler.impl.MethodResponseMessageHandler; +import org.apache.qpid.management.domain.handler.impl.SchemaResponseMessageHandler; +import org.apache.qpid.management.domain.model.AccessMode; +import org.apache.qpid.management.domain.model.type.AbsTime; +import org.apache.qpid.management.domain.model.type.DeltaTime; +import org.apache.qpid.management.domain.model.type.ObjectReference; +import org.apache.qpid.management.domain.model.type.Str16; +import org.apache.qpid.management.domain.model.type.Str8; +import org.apache.qpid.management.domain.model.type.Uint16; +import org.apache.qpid.management.domain.model.type.Uint32; +import org.apache.qpid.management.domain.model.type.Uint64; +import org.apache.qpid.management.domain.model.type.Uint8; +import org.xml.sax.SAXException; + +/** + * Test case for configurator. + * + * @author Andrea Gazzarini + * + */ +public class ConfiguratorTest extends TestCase +{ + /** + * Tests the execution of the configure() method when no configuration file is given. + * + * <br>precondition : configuration file option is not set + * <br>postcondition : no exception is thrown, the configuration is holding no broker data and the predefined mappings are + * stored in configuration. + */ + public void testConfigureOK_WithNoConfigurationFile() throws Exception + { + Configurator configurator = new Configurator(); + configurator.configure(); + Configuration configuration = Configuration.getInstance(); + + assertEquals(new Uint8(), configuration.getType(1)); + assertEquals(new Uint16(), configuration.getType(2)); + assertEquals(new Uint32(), configuration.getType(3)); + assertEquals(new Uint64(), configuration.getType(4)); + assertEquals(new Str8(), configuration.getType(6)); + assertEquals(new Str16(), configuration.getType(7)); + assertEquals(new AbsTime(), configuration.getType(8)); + assertEquals(new DeltaTime(), configuration.getType(9)); + assertEquals(new ObjectReference(), configuration.getType(10)); + assertEquals(new org.apache.qpid.management.domain.model.type.Boolean(), configuration.getType(11)); + assertEquals(new org.apache.qpid.management.domain.model.type.Uuid(), configuration.getType(14)); + assertEquals(new org.apache.qpid.management.domain.model.type.Map(), configuration.getType(15)); + + assertEquals(AccessMode.RC,configuration.getAccessMode(1)); + assertEquals(AccessMode.RW,configuration.getAccessMode(2)); + assertEquals(AccessMode.RO,configuration.getAccessMode(3)); + + Map<Character, IMessageHandler> managementHandlers = configuration.getManagementQueueHandlers(); + assertEquals(4,managementHandlers.size()); + assertEquals( + InstrumentationMessageHandler.class, + managementHandlers.get(Protocol.INSTRUMENTATION_CONTENT_RESPONSE_OPCODE).getClass()); + + assertEquals( + ConfigurationMessageHandler.class, + managementHandlers.get(Protocol.CONFIGURATION_CONTENT_RESPONSE_OPCDE).getClass()); + + assertEquals( + EventContentMessageHandler.class, + managementHandlers.get(Protocol.EVENT_CONTENT_RESPONSE_OPCDE).getClass()); + + assertEquals( + HeartBeatIndicationMessageHandler.class, + managementHandlers.get(Protocol.HEARTBEAT_INDICATION_RESPONSE_OPCODE).getClass()); + + Map<Character, IMessageHandler> methodReplyHandlers = configuration.getMethodReplyQueueHandlers(); + assertEquals(2, methodReplyHandlers.size()); + + assertEquals( + MethodResponseMessageHandler.class, + methodReplyHandlers.get(Protocol.OPERATION_INVOCATION_RESPONSE_OPCODE).getClass()); + + assertEquals( + SchemaResponseMessageHandler.class, + methodReplyHandlers.get(Protocol.SCHEMA_RESPONSE_OPCODE).getClass()); + } + + /** + * Tests the changes of the configurator internal state while configuration file is parsed. + * + * <br>precondition: N.A. + * <br>postcondition: N.A. + */ + public void testDirectorParsing() throws SAXException{ + Configurator configurator = new Configurator(); + + assertSame(Configurator.DEFAULT_PARSER,configurator._currentParser); + + configurator.startElement(null, null, Tag.BROKERS.toString(), null); + assertSame(configurator._brokerConfigurationParser,configurator._currentParser); + } + + /** + * It's not possibile to add twice the same broker connection data. + * Is so an exception must be thrown indicating that the given broker is already connected. + * + * <br>precondition : the given data identifies an already connected broker. + * <br>postcondition : an exception is thrown indicating the failure. + */ + public void testAddTwoIdenticalBrokers() throws ConfigurationException, BrokerConnectionException + { + Configurator configurator = new Configurator(); + configurator.configure(); + + BrokerConnectionData data = new BrokerConnectionData("sofia.gazzax.com",5672,"virtualHost","user","pwd",1,4,-1); + + Configuration.getInstance()._brokerConnectionInfos.put(UUID.randomUUID(),data); + + try { + configurator.createAndReturnBrokerConnectionData( + UUID.randomUUID(), + data.getHost(), + data.getPort(), + "anotherUser", + "anotherPassword", + data.getVirtualHost(), + 33, + 12, + 1000); + fail("If a broker is added twice an exception must be thrown."); + } catch (BrokerAlreadyConnectedException expected) { + assertEquals(data,expected.getBrokerConnectionData()); + } + } +} diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/MappingParsersTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/MappingParsersTest.java new file mode 100644 index 0000000000..af261024bd --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/MappingParsersTest.java @@ -0,0 +1,79 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.configuration; + +import java.util.UUID; + +import junit.framework.TestCase; + +import org.apache.qpid.management.TestConstants; + +/** + * Test case for mapping parsers. + * + * @author Andrea Gazzarini. + */ +public class MappingParsersTest extends TestCase +{ + /** + * Tests the execution of the broker connection data mapping parser. + * + * <br>precondition: A broker connection datamapping is built by the parser; + * <br>postcondition: the corresponding connection data is available on the configuration. + */ + public void testBrokerConnectionDataParser() throws UnknownBrokerException + { + String host = "127.0.0.1"; + String port = "7001"; + String virtualHost = "test"; + String username = "username_guest"; + String password ="password_guest"; + + BrokerConnectionDataParser parser = new BrokerConnectionDataParser() + { + @Override + UUID getUUId () + { + return TestConstants.BROKER_ID; + } + }; + + parser.setCurrrentAttributeValue(host); + parser.setCurrentAttributeName(Tag.HOST.toString()); + parser.setCurrrentAttributeValue(port); + parser.setCurrentAttributeName(Tag.PORT.toString()); + parser.setCurrrentAttributeValue(virtualHost); + parser.setCurrentAttributeName(Tag.VIRTUAL_HOST.toString()); + parser.setCurrrentAttributeValue(username); + parser.setCurrentAttributeName(Tag.USER.toString()); + parser.setCurrrentAttributeValue(password); + parser.setCurrentAttributeName(Tag.PASSWORD.toString()); + parser.setCurrentAttributeName(Tag.BROKER.toString()); + + BrokerConnectionData result = Configuration.getInstance().getBrokerConnectionData(TestConstants.BROKER_ID); + + assertEquals(host,result.getHost()); + assertEquals(Integer.parseInt(port),result.getPort()); + assertEquals(virtualHost,result.getVirtualHost()); + assertEquals(username,result.getUsername()); + assertEquals(password,result.getPassword()); + } +} diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandlerTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandlerTest.java new file mode 100644 index 0000000000..d6b51b64fc --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandlerTest.java @@ -0,0 +1,59 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.handler.base; + +import junit.framework.TestCase; + +import org.apache.qpid.management.domain.model.type.Binary; + +/** + * Test case for Content indication message handler (base class). + * + * @author Andrea Gazzarini + */ +public class ContentIndicationMessageHandlerTest extends TestCase +{ + /** + * Tests the behaviour of the objectHasBeenRemoved method(). + */ + public void testObjectHasBeenRemoved() + { + ContentIndicationMessageHandler mockHandler = new ContentIndicationMessageHandler() + { + @Override + protected void updateDomainModel (String packageName, String className, Binary classHash, Binary objectId, + long timeStampOfCurrentSample, long timeObjectWasCreated, long timeObjectWasDeleted, byte[] contentData) + { + } + }; + + long deletionTimestamp = 0; + long now = System.currentTimeMillis(); + + assertFalse(mockHandler.objectHasBeenRemoved(deletionTimestamp, now)); + + deletionTimestamp = now + 1000; + assertFalse(mockHandler.objectHasBeenRemoved(deletionTimestamp, now)); + + deletionTimestamp = now - 1000; + assertTrue(mockHandler.objectHasBeenRemoved(deletionTimestamp, now)); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseDomainModelTestCase.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseDomainModelTestCase.java new file mode 100644 index 0000000000..c528392a93 --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseDomainModelTestCase.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import org.apache.qpid.management.configuration.Configurator; + +import junit.framework.TestCase; + +/** + * Layer supertype for all domain model related test cases. + * + * @author Andrea Gazzarini + */ +public abstract class BaseDomainModelTestCase extends TestCase +{ + /** + * Set up fixture for this test case. + * In order to execute tests on domain model we need to build the configuration. + */ + @Override + protected void setUp () throws Exception + { + Configurator configurator = new Configurator(); + configurator.configure(); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseQpidFeatureBuilderTestCase.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseQpidFeatureBuilderTestCase.java new file mode 100644 index 0000000000..3d3783eb04 --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseQpidFeatureBuilderTestCase.java @@ -0,0 +1,96 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.desc; +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.name; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.apache.qpid.management.configuration.Configurator; +import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute; + +/** + * Layer supertype for feature builder test cases. + * + * @author Andrea Gazzarini + */ +public abstract class BaseQpidFeatureBuilderTestCase extends TestCase +{ + protected final static String NAME = "aName"; + + protected final static String DESCRIPTION = "A description."; + + protected Map <String,Object> _featureDefinition; + protected QpidFeatureBuilder _builder; + + /** + * Set up fixture for all concrete builder test cases. + */ + @Override + protected void setUp () throws Exception + { + Configurator configurator = new Configurator(); + configurator.configure(); + _featureDefinition = new HashMap<String, Object>(); + _featureDefinition.put(name.name(),NAME); + _featureDefinition.put(desc.name(), DESCRIPTION); + } + + // Internal test used to avoid code duplication. + protected void internalTestForMissingMandatoryAttribute(Attribute ...toBeRemoved) + { + try + { + for (Attribute attribute : toBeRemoved) + { + _featureDefinition.remove(attribute.name()); + } + _builder.build(); + fail("If a mandatory attribute is missing an exception must be thrown!"); + } catch (UnableToBuildFeatureException expected) + { + assertTrue(expected instanceof MissingFeatureAttributesException); + for (Attribute attribute : toBeRemoved) + { + assertTrue(expected.getMessage().contains(attribute.name())); + } + } + } + + // Internal test used to avoid code duplication. + protected void internalTestForMissingOptionalAttribute(Attribute ...toBeRemoved) throws UnableToBuildFeatureException + { + for (Attribute attribute : toBeRemoved) + { + _featureDefinition.remove(attribute.name()); + } + _builder.build(); + + assertNotNull(_builder.getQpidFeature()); + assertNotNull(_builder.getManagementFeature()); + } + + +} diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/DomainModelTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/DomainModelTest.java new file mode 100644 index 0000000000..578fa36bc7 --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/DomainModelTest.java @@ -0,0 +1,55 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import java.util.UUID; + +import org.apache.qpid.management.TestConstants; + +/** + * Test case for domain model entity. + * + * @author Andrea Gazzarini + */ +public class DomainModelTest extends BaseDomainModelTestCase +{ + private DomainModel _model; + + @Override + protected void setUp () throws Exception + { + _model = new DomainModel(UUID.randomUUID()); + } + + /** + * Tests the execution of the getPackage() method. + */ + public void testGetPackage() + { + assertFalse(_model.containsPackage(TestConstants.QPID_PACKAGE_NAME)); + + QpidPackage qpidPackage = _model.getPackageByName(TestConstants.QPID_PACKAGE_NAME); + assertEquals(TestConstants.QPID_PACKAGE_NAME,qpidPackage.getName()); + + QpidPackage theSameAsPreviousOne = _model.getPackageByName(TestConstants.QPID_PACKAGE_NAME); + assertSame(qpidPackage, theSameAsPreviousOne); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/OptionalPropertiesTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/OptionalPropertiesTest.java new file mode 100644 index 0000000000..553c1c21de --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/OptionalPropertiesTest.java @@ -0,0 +1,187 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import java.nio.ByteBuffer; +import java.util.LinkedList; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.qpid.management.domain.model.type.Uint64; +import org.apache.qpid.transport.codec.BBDecoder; + +public class OptionalPropertiesTest extends TestCase +{ + public void testDecoderStateChange() + { + QpidProperty property = new QpidProperty(); + assertSame( + "Default decoder for properties is the one for mandatory properties.", + property._mandatoryPropertyDecoder, + property._decoder); + + property.markAsOptional(1); + assertSame( + "After a property has been marked as optional the corresponding decoder must be installed.", + property._optionalPropertyDecoder, + property._decoder); + } + + /** + * Tests the execution of the decode() method when the current property is optional but in the presence bitmask + * there's no the corresponding bit set. + * + * <br>precondition : property is optional and corresponding presence bit is not set. + * <br>postcondition : result must be null. + */ + public void testDecodeValueWithOptionalPropertyAndMissingValue() + { + byte [] presenceBytes = {2}; + + QpidProperty property = new QpidProperty(); + + // We don't need a decoder so in order to be sure that it won't be invoked set it to null. + BBDecoder nullDecoder = null; + + for (int i = 0; i < 8; i++) + { + // Property number 1 is declaring a value so skip it! + if (i != 1) + { + property.markAsOptional(i); + assertNull(property.decodeValue(nullDecoder, presenceBytes)); + } + } + } + + /** + * Tests the execution of the decode() method when the current property is optional but in the presence bitmask + * there's no the corresponding bit set. + * + * <br>precondition : property is optional and corresponding presence bit is not set. + * <br>postcondition : result must be null. + */ + public void testDecodeValueWithOptionalPropertyAndDeclaredValue() + { + byte [] presenceBytes = {4}; + Long _44 = new Long(44); + + QpidProperty property = new QpidProperty(); + property.setType(new Uint64()); + property.markAsOptional(2); + + ByteBuffer buffer = ByteBuffer.allocate(8); + buffer.putLong(_44); + buffer.rewind(); + BBDecoder decoder = new BBDecoder(); + + decoder.init(buffer); + assertEquals(_44,property.decodeValue(decoder, presenceBytes)); + } + + /** + * Tests the execution of the decode() method with a real scenario where there are mandatory and optional + * properties. + */ + public void testDecodeValueWithOptionalAndMandatoryProperties() + { + // With this bitset : + // + // 1th opt property is null; + // 2th opt property is null; + // 3th opt property is not null; + // 4th opt property is null; + // 5th opt propertyis null; + // 6th opt property is null; + // 7th opt property is null; + // 8th opt property is not null; + byte [] presenceBytes = {4,1}; + + List<QpidProperty> properties = new LinkedList<QpidProperty>(); + + properties.add(createProperty(false, -1)); + properties.add(createProperty(false, -1)); + properties.add(createProperty(true, 0)); + properties.add(createProperty(false, -1)); + properties.add(createProperty(false, -1)); + properties.add(createProperty(true, 1)); + properties.add(createProperty(false, -1)); + properties.add(createProperty(false, -1)); + properties.add(createProperty(true, 2)); + properties.add(createProperty(true, 3)); + properties.add(createProperty(true, 4)); + properties.add(createProperty(true, 5)); + properties.add(createProperty(true, 6)); + properties.add(createProperty(true, 7)); + properties.add(createProperty(false, -1)); + properties.add(createProperty(true, 8)); + + Long expectedResults [] = { + 1L, // p1 + 22L, // p2 + null, // p3 + 232L, // p4 + 211L, // p5 + null, // p6 + 232L, // p7 + 211L, // p8 + 999L, // p9 + null, // p10 + null, // p11 + null, // p12 + null, // p13 + null, // p14 + 626L, // p15 + 969L // p16 + }; + + + ByteBuffer buffer = ByteBuffer.allocate(expectedResults.length * 8); + for (Long expected : expectedResults) + { + if (expected != null) + { + buffer.putLong(expected); + } + } + buffer.rewind(); + BBDecoder decoder = new BBDecoder(); + + decoder.init(buffer); + int index = 0; + for (QpidProperty property : properties) + { + assertEquals(expectedResults[index++],property.decodeValue(decoder, presenceBytes)); + } + } + + private QpidProperty createProperty(boolean isOptional, int optionalIndex) + { + QpidProperty property = new QpidProperty(); + property.setType(new Uint64()); + if (isOptional) + { + property.markAsOptional(optionalIndex); + } + return property; + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java new file mode 100644 index 0000000000..284f3841b8 --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java @@ -0,0 +1,408 @@ +/* +* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.management.domain.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanInfo; + +import junit.framework.TestCase; + +import org.apache.qpid.management.TestConstants; +import org.apache.qpid.management.configuration.ConfigurationException; +import org.apache.qpid.management.configuration.Configurator; +import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject; +import org.apache.qpid.management.domain.model.QpidClass.QpidManagedObject; + +/** + * Test case for Qpid Class. + * + * @author Andrea Gazzarini + */ +public class QpidClassTest extends TestCase +{ + private QpidClass _class; + private QpidPackage _package; + + @Override + protected void setUp () throws ConfigurationException + { + Configurator configurator = new Configurator(); + configurator.configure(); + _package = new QpidPackage(TestConstants.QPID_PACKAGE_NAME,TestConstants.DOMAIN_MODEL); + _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package); + } + + /** + * Tests the execution of the getObjectInstance() method. + * Basically it tests the addition of a new object instance. + * + * <br>precondition: class has no object instances. + * <br>precondition : class contains the added object instance. + */ + public void testGetObjectInstance() + { + assertFalse ( + "Nobody set instance #"+TestConstants.OBJECT_ID+" into this class so why is it there?", + _class._objectInstances.containsKey(TestConstants.OBJECT_ID)); + + QpidManagedObject instance = _class.getObjectInstance(TestConstants.OBJECT_ID, false); + + assertTrue ( + "Now the instance #"+TestConstants.OBJECT_ID+" should be there...", + _class._objectInstances.containsKey(TestConstants.OBJECT_ID)); + + assertEquals(instance,_class.getObjectInstance(TestConstants.OBJECT_ID, false)); + } + + /** + * Tests the injection of instrumentation and configuration data (related to a specific object instance) before the + * schema is installed. + * + * <br>precondition : the schema hasn't yet installed on this class. + * <br>postcondition : incoming configuration & instrumentation data is stored into the corresponding object instance. + */ + public void testAddInstrumentationAndConfigurationDataBeforeSchemaInstallation() + { + _class._state = _class._schemaRequestedButNotYetInjected; + QpidManagedObject objectInstance = _class.getObjectInstance(TestConstants.OBJECT_ID,false); + + assertTrue( + "This object instance is a new one so how is it possible that it has already instrumentation data? ", + objectInstance._rawInstrumentationData.isEmpty()); + assertTrue( + "This object instance is a new one so how is it possible that it has already configuration data? ", + objectInstance._rawConfigurationData.isEmpty()); + + byte [] dummyConfigurationData = {1,2,3,4,5,6,7,8}; + byte [] dummyInstrumentationData = {11,21,31,41,51,61,71,81}; + + _class.addConfigurationData(TestConstants.OBJECT_ID, dummyConfigurationData); + _class.addInstrumentationData(TestConstants.OBJECT_ID, dummyInstrumentationData); + + assertEquals("Now configuration data should be there...",1,objectInstance._rawConfigurationData.size()); + assertEquals("Now instrumentation data should be there...",1,objectInstance._rawInstrumentationData.size()); + + assertTrue( + "Object instance configuration data should be the previously set...", + Arrays.equals(objectInstance._rawConfigurationData.get(0), + dummyConfigurationData)); + + assertTrue( + "Object instance instrumentation data should be the previously set...", + Arrays.equals(objectInstance._rawInstrumentationData.get(0), + dummyInstrumentationData)); + } + + /** + * Tests the internal state change of a class definition. + */ + public void testStateChange() throws UnableToBuildFeatureException + { + _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package) + { + @Override + void requestSchema() throws Exception { + _state = _schemaRequestedButNotYetInjected; + } + + @Override + void setSchema(List<Map<String, Object>> propertyDefinitions, + List<Map<String, Object>> statisticDefinitions, + List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException { + _state = _schemaInjected; + } + }; + + assertSame( + "Initial state doesn't match.", + _class._schemaNotRequested, + _class._state); + + _class.addConfigurationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA); + _class.addInstrumentationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA); + + assertSame( + "Request schema has been requested but not yet injected. The current state is not indicating that!", + _class._schemaRequestedButNotYetInjected, + _class._state); + + _class.setSchema( + TestConstants.EMPTY_PROPERTIES_SCHEMA, + TestConstants.EMPTY_STATISTICS_SCHEMA, + new LinkedList<MethodOrEventDataTransferObject>()); + + assertSame( + "Request schema has been injected. The current state is not indicating that!", + _class._schemaInjected, + _class._state); + } + + /** + * Tests the injection of a valid schema on a QpidClass. + * + * <br>precondition : a valid arguments is injected on the qpid class. + * <br>postcondition : class definition is built successfully. + */ + public void testSchemaInjectionOk() throws UnableToBuildFeatureException + { + _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package) + { + @Override + void requestSchema() throws Exception + { + // DO NOTHING : QMan is not running and therefore the schema will be manually injected. + } + + @Override + void updateInstanceWithConfigurationData(QpidManagedObject instance, byte[] rawData) + { + // DO NOTHING Given raw data is not valid so it cannot be converted. + } + }; + + // Incoming configuration data : that will fire the schema request and a state change + // from schema-not-requested to schema-requested-but-not-injected + _class.addConfigurationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA); + + // I must be sure that what is obvious for me it's obvious for QMan... :) + assertSame( + "Request schema has been requested but not yet injected. The current state is not indicating that!", + _class._schemaRequestedButNotYetInjected, + _class._state); + + List<Map<String,Object>> propertyDefinitions = new ArrayList<Map<String,Object>>(2); + propertyDefinitions.add( + createProperty( + TestConstants.AGE_ATTRIBUTE_NAME, + 1, + TestConstants.YEARS, + TestConstants.SAMPLE_MIN_VALUE, + TestConstants.SAMPLE_MAX_VALUE, + null, + TestConstants.AGE_ATTRIBUTE_DESCRIPTION, + TestConstants._1, + false, + TestConstants._0)); + + propertyDefinitions.add( + createProperty( + TestConstants.SURNAME_ATTRIBUTE_NAME, + TestConstants.SAMPLE_ACCESS_CODE, + null, + null, + null, + TestConstants.SAMPLE_MAX_VALUE, + TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION, + TestConstants._1, + true, + TestConstants._1)); + + _class.setSchema(propertyDefinitions, TestConstants.EMPTY_STATISTICS_SCHEMA, TestConstants.EMPTY_METHODS_SCHEMA); + + assertEquals(2,_class._properties.size()); + + QpidProperty property = _class._properties.get(TestConstants.AGE_ATTRIBUTE_NAME); + assertEquals(TestConstants.AGE_ATTRIBUTE_NAME,property.getName()); + assertEquals(AccessMode.RC,property.getAccessMode()); + assertEquals(TestConstants.YEARS,property.getUnit()); + assertEquals(TestConstants.SAMPLE_MIN_VALUE,property.getMinValue()); + assertEquals(TestConstants.SAMPLE_MAX_VALUE,property.getMaxValue()); + assertEquals(Integer.MIN_VALUE,property.getMaxLength()); + assertEquals(TestConstants.AGE_ATTRIBUTE_DESCRIPTION,property.getDescription()); + assertEquals(Short.class,property.getJavaType()); + assertFalse(property.isOptional()); + + property = _class._properties.get(TestConstants.SURNAME_ATTRIBUTE_NAME); + assertEquals(TestConstants.SURNAME_ATTRIBUTE_NAME,property.getName()); + assertEquals(AccessMode.RC,property.getAccessMode()); + assertNull(property.getUnit()); + assertEquals(Integer.MIN_VALUE,property.getMinValue()); + assertEquals(Integer.MIN_VALUE,property.getMaxValue()); + assertEquals(TestConstants.SAMPLE_MAX_VALUE,property.getMaxLength()); + assertEquals(TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,property.getDescription()); + assertEquals(Short.class,property.getJavaType()); + assertTrue(property.isOptional()); + + MBeanInfo mbeanInfo = _class._metadata; + assertEquals(TestConstants.EXCHANGE_CLASS_NAME,mbeanInfo.getClassName()); + + MBeanAttributeInfo [] attributes = mbeanInfo.getAttributes(); + assertEquals(2,attributes.length); + + MBeanAttributeInfo attribute = attributes[0]; + assertEquals(TestConstants.AGE_ATTRIBUTE_NAME,attribute.getName()); + assertEquals(TestConstants.AGE_ATTRIBUTE_DESCRIPTION,attribute.getDescription()); + assertFalse(attribute.isWritable()); + assertTrue(attribute.isReadable()); + assertEquals(Short.class.getName(),attribute.getType()); + + attribute = attributes[1]; + assertEquals(TestConstants.SURNAME_ATTRIBUTE_NAME,attribute.getName()); + assertEquals(TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,attribute.getDescription()); + assertFalse(attribute.isWritable()); + assertTrue(attribute.isReadable()); + assertEquals(Short.class.getName(),attribute.getType()); + } + + /** + * Tests the behaviour of the class when a schema request can't be made. + * + * <br>precondition : class must be in "schema-not-requested" state when incoming data arrives. + * <br>postcondition : no exception is thrown and no state transition happens. + */ + public void testStateChange_withRequestSchemaFailure() + { + _class= new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package) + { + @Override + void requestSchema() throws Exception { + throw new Exception(); + } + + @Override + void setSchema( + List<Map<String, Object>> propertyDefinitions, + List<Map<String, Object>> statisticDefinitions, + List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException + { + } + }; + + assertSame( + "Initial state must be schema-not-requested.", + _class._schemaNotRequested, + _class._state); + + _class.addInstrumentationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA); + + assertSame( + "Current state must be still schema-not-requested.", + _class._schemaNotRequested, + _class._state); + } + + /** + * Tests the behaviour of the class when a schema injection fails. + * + * <br>precondition : class must be in "schema-not-requested" state when incoming data arrives. + * <br>postcondition : an exception is thrown and no state transition happens. + */ + public void testStateChange_withSchemaInjectionFailure() + { + _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package) + { + @Override + void requestSchema() throws Exception + { + // DO NOTHING. + } + + @Override + void setSchema(List<Map<String, Object>> propertyDefinitions, + List<Map<String, Object>> statisticDefinitions, + List<MethodOrEventDataTransferObject> methodDefinitions) + throws UnableToBuildFeatureException + { + throw new UnableToBuildFeatureException(""); + } + }; + + assertSame( + "Initial state must be schema-not-requested.", + _class._schemaNotRequested, + _class._state); + + _class.addInstrumentationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA); + + assertSame( + "Request schema has been requested but not yet injected. The current state is not indicating that!", + _class._schemaRequestedButNotYetInjected, + _class._state); + + try { + _class.setSchema( + TestConstants.EMPTY_PROPERTIES_SCHEMA, + TestConstants.EMPTY_STATISTICS_SCHEMA, + TestConstants.EMPTY_METHODS_SCHEMA); + fail("If we are here something was wrong becuase the setSchema() of this event is throwing an exception..."); + } catch (UnableToBuildFeatureException expected) { + assertSame( + "Request schema has been requested but not yet injected. The current state is not indicating that!", + _class._schemaRequestedButNotYetInjected, + _class._state); + } + } + + private Map<String,Object> createProperty( + String name, + Integer accessCode, + String unit, + Integer min, + Integer max, + Integer maxLength, + String description, + Integer type, + boolean optional, + Integer index) + { + Map <String,Object> result = new HashMap<String, Object>(); + result.put(QpidFeatureBuilder.Attribute.name.name(),name); + result.put(QpidFeatureBuilder.Attribute.access.name(), accessCode); + + if (unit != null) + { + result.put(QpidFeatureBuilder.Attribute.unit.name(),unit); + } + + if (min != null) + { + result.put(QpidFeatureBuilder.Attribute.min.name(), min); + } + + if (max != null) + { + result.put(QpidFeatureBuilder.Attribute.max.name(),max); + } + + if (maxLength != null) + { + result.put(QpidFeatureBuilder.Attribute.maxlen.name(),maxLength); + } + + result.put(QpidFeatureBuilder.Attribute.desc.name(), description); + result.put(QpidFeatureBuilder.Attribute.type.name(), type); + result.put(QpidFeatureBuilder.Attribute.optional.name(),optional ? 1 : 0); + + if (index != null) + { + result.put(QpidFeatureBuilder.Attribute.index.name(), index); + } + return result; + } +} diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java new file mode 100644 index 0000000000..954a419787 --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java @@ -0,0 +1,293 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.TestConstants;
+import org.apache.qpid.management.configuration.ConfigurationException;
+import org.apache.qpid.management.configuration.Configurator;
+import org.apache.qpid.management.domain.model.QpidEvent.QpidManagedEvent;
+
+/**
+ * Test case for qpid class entity.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidEventTest extends TestCase
+{
+ private QpidEvent _event;
+ private QpidPackage _qpidPackage;
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ _qpidPackage = new QpidPackage(TestConstants.QPID_PACKAGE_NAME,TestConstants.DOMAIN_MODEL);
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage);
+ }
+
+ /**
+ * Tests the execution of the createEventInstance() method.
+ * Basically it tests the addition of a new event instance.
+ *
+ * <br>precondition: event deifinition has no object instances.
+ * <br>precondition : event definition contains the new object instance.
+ */
+ public void testCreateEventInstance()
+ {
+ assertTrue(
+ "A just created event should be empty. I mean there shouldn't be event instances inside.",
+ _event.hasNoInstances());
+
+ QpidManagedEvent instance = createEventInstance();
+
+ assertFalse (
+ "Now a new instance should be there...",
+ _event.hasNoInstances());
+
+ assertEquals(TestConstants.TEST_RAW_DATA,instance._rawEventData);
+ assertEquals(TestConstants.NOW,instance._timestamp);
+ assertEquals(TestConstants.SEVERITY, instance._severity);
+ }
+
+ /**
+ * Tests the internal state change of an event definition.
+ */
+ public void testStateChange() throws UnableToBuildFeatureException
+ {
+ // Let's override this class because this is not an online tests and therefore
+ // QMan is not supposed to be up.
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ // Do Nothing.
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> argumentDefinitions)throws UnableToBuildFeatureException {
+ _state = _schemaInjected;
+ }
+ };
+
+ assertSame(
+ "Initial state doesn't match.",
+ _event._schemaNotRequested,
+ _event._state);
+
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+
+ _event.setSchema(TestConstants.EMPTY_ARGUMENTS_SCHEMA);
+
+ assertSame(
+ "Request schema has been injected. The current state is not indicating that!",
+ _event._schemaInjected,
+ _event._state);
+ }
+
+ /**
+ * Tests the injection of a valid schema on a QpidEvent.
+ *
+ * <br>precondition : a valid arguments is injected on the qpid event.
+ * <br>postcondition : event definition is built successfully.
+ */
+ public void testSchemaInjectionOK() throws UnableToBuildFeatureException, ConfigurationException, InstanceNotFoundException, MBeanException, ReflectionException
+ {
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception
+ {
+ // DO NOTHING : QMan is not running and therefore the schema will be manually injected.
+ }
+
+ @Override
+ void updateEventInstanceWithData(QpidManagedEvent instance)
+ {
+ // DO NOTHING : otherwise we should supply a valid raw data to be converted. ;-)
+ }
+ };
+
+ Configurator configurator = new Configurator();
+ configurator.configure();
+
+ List<Map<String,Object>> arguments = new ArrayList<Map<String, Object>>();
+ arguments.add(createArgument(TestConstants.AGE_ATTRIBUTE_NAME, TestConstants.AGE_ATTRIBUTE_DESCRIPTION));
+ arguments.add(createArgument(TestConstants.SURNAME_ATTRIBUTE_NAME, TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION));
+
+ // Incoming data : that will fire the schema request and a state change from schema-not-requested to schema-requested-but-not-injected
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ // I must be sure that what is obvious for me it's obvious for QMan... :)
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+
+ // Inject schema
+ _event.setSchema(arguments);
+
+ // Arguments must be 2 + 2 (severity)
+ assertEquals(2,_event._arguments.size());
+
+ QpidProperty argument = _event._arguments.get(TestConstants.AGE_ATTRIBUTE_NAME);
+ assertEquals(TestConstants.AGE_ATTRIBUTE_NAME,argument.getName());
+ assertEquals(AccessMode.RO,argument.getAccessMode());
+ assertEquals(TestConstants.AGE_ATTRIBUTE_DESCRIPTION,argument.getDescription());
+ assertEquals(Short.class,argument.getJavaType());
+ assertFalse(argument.isOptional());
+
+ argument = _event._arguments.get(TestConstants.SURNAME_ATTRIBUTE_NAME);
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_NAME,argument.getName());
+ assertEquals(AccessMode.RO,argument.getAccessMode());
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,argument.getDescription());
+ assertEquals(Short.class,argument.getJavaType());
+ assertFalse(argument.isOptional());
+
+ assertEquals(1,_event._eventInstances.size());
+
+ JmxService service = new JmxService();
+ Set<ObjectName> objectNames = service.getEventMBeans();
+
+ assertEquals(1,objectNames.size());
+ }
+
+ /**
+ * Tests the behaviour of the event class when a schema request can't be made.
+ *
+ * <br>precondition : event must be in "schema-not-requested" state when incoming data arrives.
+ * <br>postcondition : no exception is thrown and no state transition happens.
+ */
+ public void testStateChange_withRequestSchemaFailure()
+ {
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ throw new Exception();
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> argumentDefinitions)throws UnableToBuildFeatureException {
+ _state = _schemaInjected;
+ }
+ };
+
+ assertSame(
+ "Initial state must be schema-not-requested.",
+ _event._schemaNotRequested,
+ _event._state);
+
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ assertSame(
+ "Current state must be still schema-not-requested.",
+ _event._schemaNotRequested,
+ _event._state);
+ }
+
+ /**
+ * Tests the behaviour of the event class when a schema injection fails.
+ *
+ * <br>precondition : event must be in "schema-not-requested" state when incoming data arrives.
+ * <br>postcondition : an exception is thrown and no state transition happens.
+ */
+ public void testStateChange_withSchemaInjectionFailure()
+ {
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ // DO NOTHING.
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> argumentDefinitions)throws UnableToBuildFeatureException {
+ throw new UnableToBuildFeatureException("");
+ }
+ };
+
+ assertSame(
+ "Initial state must be schema-not-requested.",
+ _event._schemaNotRequested,
+ _event._state);
+
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+
+ try {
+ _event.setSchema(TestConstants.EMPTY_ARGUMENTS_SCHEMA);
+ fail("If we are here something was wrong becuase the setSchema() of this event is throwing an exception...");
+ } catch (UnableToBuildFeatureException expected) {
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+ }
+ }
+
+ /**
+ * Factory method for qpid managed event instances.
+ *
+ * @return a new QpidManagedEvent with test data inside.
+ */
+ private QpidManagedEvent createEventInstance()
+ {
+ return _event.createEventInstance(
+ TestConstants.TEST_RAW_DATA,
+ TestConstants.NOW,
+ TestConstants.SEVERITY);
+ }
+
+ /**
+ * Factory method for event argument.
+ *
+ * @return a new argument metadata.
+ */
+ private Map<String,Object> createArgument(String name,String desc)
+ {
+ Map <String,Object> argument = new HashMap<String, Object>();
+ argument.put(QpidFeatureBuilder.Attribute.name.name(),name);
+ argument.put(QpidFeatureBuilder.Attribute.desc.name(), desc);
+ argument.put(QpidFeatureBuilder.Attribute.type.name(), TestConstants._1);
+ return argument;
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidMethodBuilderTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidMethodBuilderTest.java new file mode 100644 index 0000000000..06dc35b0b1 --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidMethodBuilderTest.java @@ -0,0 +1,147 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.dir; +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.name; +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.type; +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.unit; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.management.MBeanOperationInfo; + +import org.apache.qpid.management.Names; +import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject; +import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute; + +/** + * Test case for Qpid Statistic builder. + * + * @author Andrea Gazzarini + */ +public class QpidMethodBuilderTest extends BaseQpidFeatureBuilderTestCase +{ + private final static Integer ARG_COUNT = 3; + private MethodOrEventDataTransferObject _methodDefinition; + + private List<Map<String,Object>> _argumentsDefinitons = new ArrayList<Map<String, Object>>(); + + @Override + protected void setUp () throws Exception + { + super.setUp(); + _featureDefinition.put(Names.ARG_COUNT_PARAM_NAME, ARG_COUNT); + + Map<String,Object> arg1 = new HashMap<String,Object>(); + arg1.put(name.name(), "arg1"); + arg1.put(type.name(),1); + arg1.put(dir.name(),Direction.I.name()); + arg1.put(unit.name(), "bytes"); + + Map<String,Object> arg2 = new HashMap<String,Object>(); + arg2.put(name.name(), "arg2"); + arg2.put(type.name(),1); + arg2.put(dir.name(),Direction.O.name()); + arg2.put(unit.name(), "bytes"); + + Map<String,Object> arg3 = new HashMap<String,Object>(); + arg3.put(name.name(), "arg3"); + arg3.put(type.name(),1); + arg3.put(dir.name(),Direction.IO.name()); + arg3.put(unit.name(), "bytes"); + + /* + dir yes no yes Direction code for method arguments + unit yes yes yes Units for numeric values (i.e. seconds, bytes, etc.) + min yes no yes Minimum value for numerics + max yes no yes Maximum value for numerics + maxlen yes no yes Maximum length for strings + desc yes yes yes Description of the argument + default yes no yes Default value for the argument + */ + _argumentsDefinitons.add(arg1); + _argumentsDefinitons.add(arg2); + + _methodDefinition = new MethodOrEventDataTransferObject(_featureDefinition,_argumentsDefinitons); + _builder = QpidFeatureBuilder.createMethodBuilder(_methodDefinition); + } + + /** + * Tests the build process for a statistic when the definition map doesn't contains type attribute. + * + * <br>precondition: definition map doesn't contains type attribute. + * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the + * missing attribute. + */ + public void testMethodBuilderKO_WithMissingName() + { + internalTestForMissingMandatoryAttribute(Attribute.name); + } + + /** + * Tests the build process for a statistic when the definition map doesn't contain type, name, index & optional attributes. + * + * <br>precondition: definition map doesn't contain type, name, index & optional attributes. + * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the + * missing attributes. + */ + public void testMethodBuilderOK_WithMissingUnit() throws UnableToBuildFeatureException + { + internalTestForMissingOptionalAttribute(Attribute.unit); + } + + /** + * Tests the build process for a statistic when the definition map doesn't unit attribute. + * Note that this attribute is optional and therefore the build must succeed. + * + * <br>precondition: definition map doesn't contain unit attribute. + * <br>postcondition : no exception is thrown and the statistic is built. + */ + public void testMethodBuilderOK_WithMissingDescription() throws UnableToBuildFeatureException + { + internalTestForMissingOptionalAttribute(Attribute.desc); + } + + /** + * Tests the build process for a statistic when the definition map contains valid values. + * + * <br>precondition : the statistic definiton map contains valid values. + * <br>postcondition : no exception is thrown and the statistisc is built as expected. + */ + public void testMethodBuilderOK() throws UnableToBuildFeatureException + { + _builder.build(); + + QpidMethod method = (QpidMethod) _builder.getQpidFeature(); + MBeanOperationInfo info = (MBeanOperationInfo) _builder.getManagementFeature(); + + assertEquals(NAME,method.getName()); + + assertEquals(DESCRIPTION,method.getDescription()); + + assertEquals(method.getDescription(),info.getDescription()); + assertEquals(method.getName(),info.getName()); + } +} diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidNumberPropertyTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidNumberPropertyTest.java new file mode 100644 index 0000000000..374011d150 --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidNumberPropertyTest.java @@ -0,0 +1,171 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import junit.framework.TestCase; + +import org.apache.qpid.management.configuration.Configurator; +import org.apache.qpid.management.domain.model.type.Uint8; + +public class QpidNumberPropertyTest extends TestCase +{ + private QpidProperty _property; + private Long _value = 55432L; + + @Override + protected void setUp () throws Exception + { + Configurator configurator = new Configurator(); + configurator.configure(); + _property = new QpidProperty(); + _property.setName("average"); + _property.setAccessMode(AccessMode.RW); + _property.setType(new Uint8()); + } + + /** + * Tests the validation of a qpid property when the type is a number and no constraint has been set. + * + * <br>precondition : property type is a string, no constraint has been set. + * <br>postcondition : no exception is thrown and the validation succeeds. + */ + public void testValidationWithoutConstraints() { + try + { + _property.validate(_value); + } catch (ValidationException notExpected) + { + fail("If no constraint has been set on this property why the validation is failing?"); + } + } + + /** + * Tests the validation of a qpid property when the type is a number and a max value constraint has been set. + * + * <br>precondition : property type is a number, max value has been set and property value is greater than max value. + * <br>postcondition : an exception is thrown indicating the validation failure. + */ + public void testValidationKO_withMaxValue() { + int maxValue = (int)(_value-1); + _property.setMaxValue(maxValue); + + try + { + _property.validate(_value); + fail("The given value is violating the installed constraint so an exception must be thrown."); + } catch (ValidationException expected) + { + assertEquals(ValidationException.MAX_VALUE,expected.getConstraintName()); + assertEquals(maxValue,expected.getConstraintValue()); + assertEquals((double)_value,expected.getFeatureValue()); + assertEquals(_property.getName(),expected.getFeatureName()); + } + } + + /** + * Tests the validation of a qpid property when the type is a number and a min value constraint has been set. + * + * <br>precondition : property type is a number, min value has been set and property value is lesser than min value. + * <br>postcondition : an exception is thrown indicating the validation failure. + */ + public void testValidationKO_withMinValue() { + int minValue = (int)(_value+1); + _property.setMinValue(minValue); + + try + { + _property.validate(_value); + fail("The given value is violating the installed constraint so an exception must be thrown."); + } catch (ValidationException expected) + { + assertEquals(ValidationException.MIN_VALUE,expected.getConstraintName()); + assertEquals(minValue,expected.getConstraintValue()); + assertEquals((double)_value,expected.getFeatureValue()); + assertEquals(_property.getName(),expected.getFeatureName()); + } + } + + + /** + * Tests the validation of a qpid property when the number is a string and the property value is null. + * + * <br>precondition : property type is a number and property value is null.. + * <br>postcondition : no exception is thrown. That is : the validation succeeds. + */ + public void testValidationOK_withNullValue() { + try + { + _property.validate(null); + } catch (ValidationException notExpected) + { + fail("No constraint has been violated so validate() shouldn't raise an exception."); + } + + _property.setMinValue(1); + _property.setMaxValue(10); + + try + { + _property.validate(null); + } catch (ValidationException notExpected) + { + fail("No constraint has been violated so validate() shouldn't raise an exception."); + } + } + + /** + * Tests the validation of a qpid property when the type is a number and a max / min constraints have been set. + * + * <br>precondition : property type is a number, max / min constraint have been set and property value is wrong. + * <br>postcondition : an exception is thrown indicating the validation failure. + */ + public void testValidationOK_withMinAndMaxConstraint() { + int minValue = (int)(_value+1); + int maxValue = (int)(_value-1); + _property.setMinValue(minValue); + _property.setMaxValue(maxValue); + + try + { + _property.validate(_value); + fail("The given value is violating the installed constraint so an exception must be thrown."); + } catch (ValidationException expected) + { + assertEquals(ValidationException.MIN_VALUE,expected.getConstraintName()); + assertEquals(minValue,expected.getConstraintValue()); + assertEquals((double)_value,expected.getFeatureValue()); + assertEquals(_property.getName(),expected.getFeatureName()); + } + + _property.setMinValue(0); + try + { + _property.validate(_value); + fail("The given value is violating the installed constraint so an exception must be thrown."); + } catch (ValidationException expected) + { + assertEquals(ValidationException.MAX_VALUE,expected.getConstraintName()); + assertEquals(maxValue,expected.getConstraintValue()); + assertEquals((double)_value,expected.getFeatureValue()); + assertEquals(_property.getName(),expected.getFeatureName()); + } + } +} diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPackageTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPackageTest.java new file mode 100644 index 0000000000..b7eb9055ba --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPackageTest.java @@ -0,0 +1,53 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import org.apache.qpid.management.TestConstants; + +/** + * Test case for Qpid package entity. + * + * @author Andrea Gazzarini + */ +public class QpidPackageTest extends BaseDomainModelTestCase +{ + private QpidPackage _qpidPackage; + + @Override + protected void setUp () throws Exception + { + _qpidPackage = new QpidPackage(TestConstants.QPID_PACKAGE_NAME, TestConstants.DOMAIN_MODEL); + } + + /** + * Tests the association of a new class with a qpid package. + * + * <br>precondition : the package is not associated with any class. + * <br>postcondition : the package is now associated with the given class. + */ + public void testAddClass() throws UnableToBuildFeatureException { + assertFalse(_qpidPackage.alreadyContainsClassDefinition(TestConstants.EXCHANGE_CLASS_NAME, TestConstants.HASH)); + + _qpidPackage.getQpidClass(TestConstants.EXCHANGE_CLASS_NAME, TestConstants.HASH, true); + + assertTrue(_qpidPackage.alreadyContainsClassDefinition(TestConstants.EXCHANGE_CLASS_NAME, TestConstants.HASH)); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPropertyBuilderTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPropertyBuilderTest.java new file mode 100644 index 0000000000..8ad177645c --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPropertyBuilderTest.java @@ -0,0 +1,269 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.access; +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.index; +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.max; +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.min; +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.optional; +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.type; +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.unit; + +import javax.management.MBeanAttributeInfo; + +import org.apache.qpid.management.configuration.UnknownTypeCodeException; +import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute; + +/** + * Test case for Qpid Property builder. + * + * @author Andrea Gazzarini + */ +public class QpidPropertyBuilderTest extends BaseQpidFeatureBuilderTestCase +{ + private final static Integer MIN = 0; + private final static Integer MAX = 120; + private final static String UNIT = "bytes"; + + private Integer _access; + + @Override + protected void setUp () throws Exception + { + super.setUp(); + + _access = 1; + _featureDefinition.put(access.name(), _access); + _featureDefinition.put(unit.name(),UNIT); + _featureDefinition.put(min.name(), MIN); + _featureDefinition.put(max.name(),MAX); + + _featureDefinition.put(type.name(), 1); + _featureDefinition.put(optional.name(),0); + _featureDefinition.put(index.name(), 0); + + _builder = QpidFeatureBuilder.createPropertyBuilder(_featureDefinition); + } + + /** + * Tests the build process for a statistic when the definition map contains an unknown type code. + * + * <br>precondition : the statistic definiton map contains an unknown type code. + * <br>postcondition : an exception is thrown indicating the failure. + */ + public void testStatisticBuilderKO_WithUnknownType() + { + int unknownTypeCode =999; + try + { + _featureDefinition.put(type.name(), unknownTypeCode); + _builder.build(); + fail("An unknown type code should raise an exception to indicate a failure."); + } catch (UnableToBuildFeatureException expected) + { + assertEquals(unknownTypeCode,((UnknownTypeCodeException)expected.getCause()).getCode()); + } + } + + /** + * Tests the build process for a statistic when the definition map contains a null value for a metadata attribute. + * + * <br>precondition : the statistic definiton map contains a null value for a metadata attribute. + * <br>postcondition : an exception is thrown indicating the failure. + */ + public void testMethodBuilderKO_WithNullMetadataValue() + { + try + { + _featureDefinition.put(type.name(), null); + _builder.build(); + fail("An null value for a metadata attribute should raise an exception to indicate a failure."); + } catch (UnableToBuildFeatureException expected) + { + assertTrue(expected.getCause() instanceof NullPointerException); + } + } + + /** + * Tests the build process for a property when the definition map contains an invalid metadata type. + * + * <br>precondition : the property definiton map contains a wrong type for a metadata attribute. + * <br>postcondition : an exception is thrown indicating the failure. + */ + public void testPropertyBuilderKO_WithClassCastException() + { + try + { + _featureDefinition.put(access.name(), new String("a")); + _builder.build(); + fail("A wrong metadata attribute type should raise an exception to indicate a failure."); + } catch (UnableToBuildFeatureException expected) + { + assertTrue(expected.getCause() instanceof ClassCastException); + } + } + + /** + * Tests the build process for a property when the definition map contains an unknown type code. + * + * <br>precondition : the property definiton map contains an unknown type code. + * <br>postcondition : an exception is thrown indicating the failure. + */ + public void testPropertyBuilderKO_WithUnknownType() + { + int unknownTypeCode = 999; + try + { + _featureDefinition.put(type.name(), unknownTypeCode); + _builder.build(); + fail("An unknown type code should raise an exception to indicate a failure."); + } catch (UnableToBuildFeatureException expected) + { + assertEquals(unknownTypeCode,((UnknownTypeCodeException)expected.getCause()).getCode()); + } + } + + /** + * Tests the build process for a property when the definition map doesn't contains type attribute. + * + * <br>precondition: definition map doesn't contains type attribute. + * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the + * missing attribute. + */ + public void testPropertyBuilderKO_WithMissingType() + { + internalTestForMissingMandatoryAttribute(Attribute.type); + } + + /** + * Tests the build process for a property when the definition map doesn't contain type & name attributes. + * + * <br>precondition: definition map doesn't contain type & name attributes. + * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the + * missing attributes. + */ + public void testPropertyBuilderKO_WithMissingTypeAndName() + { + internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name); + } + + /** + * Tests the build process for a property when the definition map doesn't contain type & name & index attributes. + * + * <br>precondition: definition map doesn't contain type & name & index attributes. + * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the + * missing attributes. + */ + public void testPropertyBuilderKO_WithMissingTypeAndNameAndIndex() + { + internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name,Attribute.index); + } + + /** + * Tests the build process for a property when the definition map doesn't contain type, name, index & optional attributes. + * + * <br>precondition: definition map doesn't contain type, name, index & optional attributes. + * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the + * missing attributes. + */ + public void testPropertyBuilderKO_WithMissingTypeAndNameAndIndexAndOptional() + { + internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name,Attribute.index,Attribute.optional); + } + + /** + * Tests the build process for a property when the definition map doesn't contain type, name, index, optional and access + * attributes. + * + * <br>precondition: definition map doesn't contain type, name, index, optional and access attributes. + * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the + * missing attributes. + */ + public void testPropertyBuilderKO_WithMissingTypeAndNameAndIndexAndOptionalAndAccess() + { + internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name,Attribute.index,Attribute.optional,Attribute.access); + } + + /** + * Tests the build process for a property when the definition map doesn't unit attribute. + * Note that this attribute is optional and therefore the build must succeed. + * + * <br>precondition: definition map doesn't contain unit attribute. + * <br>postcondition : no exception is thrown and the property is built. + */ + public void testBuilderOK_WithMissingUnit() throws UnableToBuildFeatureException + { + internalTestForMissingOptionalAttribute(Attribute.unit); + } + + /** + * Tests the build process for a property when the definition map doesn't min and max attributes. + * Note that those attributes are optional and therefore the build must succeed. + * + * <br>precondition: definition map doesn't contain min and max attributes. + * <br>postcondition : no exception is thrown and the property is built. + */ + public void testBuilderOK_WithMissingMinAndMax() throws UnableToBuildFeatureException + { + internalTestForMissingOptionalAttribute(Attribute.min,Attribute.max); + } + + /** + * Tests the build process for a property when the definition map doesn't description attribute. + * Note that this attribute is optional and therefore the build must succeed. + * + * <br>precondition: definition map doesn't contain description attribute. + * <br>postcondition : no exception is thrown and the property is built. + */ + public void testBuilderOK_WithMissingDescription() throws UnableToBuildFeatureException + { + internalTestForMissingOptionalAttribute(Attribute.desc); + } + + /** + * Tests the build process for a property when the definition map contains valid values. + * + * <br>precondition : the property definiton map contains valid values. + * <br>postcondition : no exception is thrown and the property is built as expected. + */ + public void testPropertyBuilderOK() throws UnableToBuildFeatureException + { + _builder.build(); + + QpidProperty property = (QpidProperty) _builder.getQpidFeature(); + MBeanAttributeInfo info = (MBeanAttributeInfo) _builder.getManagementFeature(); + + assertEquals(NAME,property.getName()); + assertEquals(AccessMode.RC,property.getAccessMode()); + assertEquals(UNIT,property.getUnit()); + assertEquals(MIN.intValue(),property.getMinValue()); + assertEquals(MAX.intValue(),property.getMaxValue()); + assertEquals(Integer.MIN_VALUE,property.getMaxLength()); + assertEquals(DESCRIPTION,property.getDescription()); + assertEquals(Short.class,property.getJavaType()); + assertFalse(property.isOptional()); + + assertEquals(property.getDescription(),info.getDescription()); + assertEquals(property.getName(),info.getName()); + assertEquals(property.getJavaType().getName(),info.getType()); + } +} diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStatisticBuilderTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStatisticBuilderTest.java new file mode 100644 index 0000000000..b7a8540b2d --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStatisticBuilderTest.java @@ -0,0 +1,159 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.type; +import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.unit; + +import javax.management.MBeanAttributeInfo; + +import org.apache.qpid.management.configuration.UnknownTypeCodeException; +import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute; + +/** + * Test case for Qpid Statistic builder. + * + * @author Andrea Gazzarini + */ +public class QpidStatisticBuilderTest extends BaseQpidFeatureBuilderTestCase +{ + private final static String UNIT = "bytes"; + + @Override + protected void setUp () throws Exception + { + super.setUp(); + _featureDefinition.put(unit.name(),UNIT); + _featureDefinition.put(type.name(), 1); + + _builder = QpidFeatureBuilder.createStatisticBuilder(_featureDefinition); + } + + /** + * Tests the build process for a statistic when the definition map contains an unknown type code. + * + * <br>precondition : the statistic definiton map contains an unknown type code. + * <br>postcondition : an exception is thrown indicating the failure. + */ + public void testStatisticBuilderKO_WithUnknownType() + { + int unknownTypeCode = 999; + try + { + _featureDefinition.put(type.name(), unknownTypeCode); + _builder.build(); + fail("An unknown type code should raise an exception to indicate a failure."); + } catch (UnableToBuildFeatureException expected) + { + assertEquals(unknownTypeCode,((UnknownTypeCodeException)expected.getCause()).getCode()); + } + } + + /** + * Tests the build process for a statistic when the definition map contains a null value for a metadata attribute. + * + * <br>precondition : the statistic definiton map contains a null value for a metadata attribute. + * <br>postcondition : an exception is thrown indicating the failure. + */ + public void testMethodBuilderKO_WithNullMetadataValue() + { + try + { + _featureDefinition.put(type.name(), null); + _builder.build(); + fail("An null value for a metadata attribute should raise an exception to indicate a failure."); + } catch (UnableToBuildFeatureException expected) + { + assertTrue(expected.getCause() instanceof NullPointerException); + } + } + + /** + * Tests the build process for a statistic when the definition map doesn't contains type attribute. + * + * <br>precondition: definition map doesn't contains type attribute. + * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the + * missing attribute. + */ + public void testStatisticBuilderKO_WithMissingType() + { + internalTestForMissingMandatoryAttribute(Attribute.type); + } + + /** + * Tests the build process for a statistic when the definition map doesn't contain type & name attributes. + * + * <br>precondition: definition map doesn't contain type & name attributes. + * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the + * missing attributes. + */ + public void testStatisticBuilderKO_WithMissingTypeAndName() + { + internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name); + } + + /** + * Tests the build process for a statistic when the definition map doesn't contain type, name, index & optional attributes. + * + * <br>precondition: definition map doesn't contain type, name, index & optional attributes. + * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the + * missing attributes. + */ + public void testStatisticBuilderOK_WithMissingUnit() throws UnableToBuildFeatureException + { + internalTestForMissingOptionalAttribute(Attribute.unit); + } + + /** + * Tests the build process for a statistic when the definition map doesn't unit attribute. + * Note that this attribute is optional and therefore the build must succeed. + * + * <br>precondition: definition map doesn't contain unit attribute. + * <br>postcondition : no exception is thrown and the statistic is built. + */ + public void testBuilderOK_WithMissingDescription() throws UnableToBuildFeatureException + { + internalTestForMissingOptionalAttribute(Attribute.desc); + } + + /** + * Tests the build process for a statistic when the definition map contains valid values. + * + * <br>precondition : the statistic definiton map contains valid values. + * <br>postcondition : no exception is thrown and the statistisc is built as expected. + */ + public void testStatisticBuilderOK() throws UnableToBuildFeatureException + { + _builder.build(); + + QpidStatistic statistic= (QpidStatistic) _builder.getQpidFeature(); + MBeanAttributeInfo info = (MBeanAttributeInfo) _builder.getManagementFeature(); + + assertEquals(NAME,statistic.getName()); + assertEquals(UNIT,statistic.getUnit()); + assertEquals(DESCRIPTION,statistic.getDescription()); + assertEquals(Short.class,statistic.getJavaType()); + + assertEquals(statistic.getDescription(),info.getDescription()); + assertEquals(statistic.getName(),info.getName()); + assertEquals(statistic.getJavaType().getName(),info.getType()); + } +} diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStringPropertyTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStringPropertyTest.java new file mode 100644 index 0000000000..8aeb7c8550 --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStringPropertyTest.java @@ -0,0 +1,127 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model; + +import junit.framework.TestCase; + +import org.apache.qpid.management.configuration.Configurator; +import org.apache.qpid.management.domain.model.type.Str16; + +public class QpidStringPropertyTest extends TestCase +{ + private QpidProperty _property; + private final String _5LettersString = "12345"; + + @Override + protected void setUp () throws Exception + { + Configurator configurator = new Configurator(); + configurator.configure(); + _property = new QpidProperty(); + _property.setName("name"); + _property.setAccessMode(AccessMode.RW); + _property.setType(new Str16()); + } + + /** + * Tests the validation of a qpid property when the type is a string and a max length constraint hasn't been set. + * + * <br>precondition : property type is a string, max length hasn't been set. + * <br>postcondition : no exception is thrown. That is : the validation succeeds. + */ + public void testValidationWithoutMaxLength() { + try + { + _property.validate(_5LettersString); + } catch (ValidationException notExpected) + { + fail("No max length has been set on property so validation must succeed."); + } + } + + /** + * Tests the validation of a qpid property when the type is a string and a max length constraint has been set. + * + * <br>precondition : property type is a string, max length has been set and property value is longer than max length. + * <br>postcondition : an exception is thrown indicating the validation failure. + */ + public void testValidationKO_withMaxLength() { + int maxLength = 2; + _property.setMaxLength(maxLength); + + try + { + _property.validate(_5LettersString); + fail("No max length has been set on property so validation must proceed."); + } catch (ValidationException expected) + { + assertEquals(ValidationException.MAX_LENGTH,expected.getConstraintName()); + assertEquals(maxLength,expected.getConstraintValue()); + assertEquals(_5LettersString.length(),expected.getFeatureValue()); + assertEquals(_property.getName(),expected.getFeatureName()); + } + } + + /** + * Tests the validation of a qpid property when the type is a string and the property value is null. + * + * <br>precondition : property type is a string and property value is null.. + * <br>postcondition : no exception is thrown. That is : the validation succeeds. + */ + public void testValidationOK_withNullValue() { + try + { + _property.validate(null); + } catch (ValidationException notExpected) + { + fail("No constraint has been violated so validate() shouldn't raise an exception."); + } + + _property.setMaxLength(1); + + try + { + _property.validate(null); + } catch (ValidationException notExpected) + { + fail("No constraint has been violated so validate() shouldn't raise an exception."); + } + } + + /** + * Tests the validation of a qpid property when the type is a string and a max length constraint has been set. + * + * <br>precondition : property type is a string, max length has been set and property value is not violating that. + * <br>postcondition : no exception is thrown. That is : the validation succeeds. + */ + public void testValidationOK_withMaxLength() { + int maxLength = (_5LettersString.length()+1); + _property.setMaxLength(maxLength); + + try + { + _property.validate(_5LettersString); + } catch (ValidationException notExpected) + { + fail("No constraint has been violated so validate() shouldn't raise an exception."); + } + } +} diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/type/BinaryTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/type/BinaryTest.java new file mode 100644 index 0000000000..6636c08710 --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/type/BinaryTest.java @@ -0,0 +1,59 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.model.type; + +import junit.framework.TestCase; + +/** + * Test case for "Binary" type. + * + * @author Andrea Gazzarini + */ +public class BinaryTest extends TestCase +{ + /** + * Tests the lazy & once hash code computation behaviour of the binary type. + */ + public void testHashCodeComputation(){ + Binary binary = new Binary(new byte[]{1,2,3,4,5,6,7,6,3,3}); + assertSame(binary.state,binary.hashCodeNotYetComputed); + + int firstResult = binary.hashCode(); + assertSame(binary.state,binary.hashCodeAlreadyComputed); + + int secondResult = binary.hashCode(); + assertSame(binary.state,binary.hashCodeAlreadyComputed); + assertEquals(firstResult,secondResult); + } + + /** + * Tests the equals() method of the binary class. + * Two binary must be equals only if they contain the same array (that is, two arrays with the same size & content) + */ + public void testIdentity() { + Binary binary = new Binary(new byte[]{1,2,3,4,5,6,7,6,3,3}); + Binary theSame= new Binary(new byte[]{1,2,3,4,5,6,7,6,3,3}); + Binary aDifferentOne = new Binary(new byte[]{4,2,3,3,4,4,5,3,3,2}); + + assertTrue(binary.equals(theSame)); + assertFalse(binary.equals(aDifferentOne)); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java new file mode 100644 index 0000000000..805c039a6f --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java @@ -0,0 +1,241 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.domain.services; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import junit.framework.TestCase; + +import org.apache.qpid.api.Message; +import org.apache.qpid.management.TestConstants; +import org.apache.qpid.management.domain.handler.base.IMessageHandler; +import org.apache.qpid.management.domain.model.DomainModel; +import org.apache.qpid.nclient.util.ByteBufferMessage; +import org.apache.qpid.transport.codec.Decoder; + +/** + * Test case for Broker Message Listener. + * + * @author Andrea Gazzarini + */ +public class BrokerMessageListenerTest extends TestCase +{ + // An empty message handler user for test. + private IMessageHandler _emptyMessageHandler = new IMessageHandler() + { + public void process (Decoder decoder, int sequenceNumber) + { + } + public void setDomainModel (DomainModel domainModel) + { + } + }; + + // Another empty message handler user for test. + private IMessageHandler _anotherEmptyMessageHandler = new IMessageHandler() + { + public void process (Decoder decoder, int sequenceNumber) + { + } + public void setDomainModel (DomainModel domainModel) + { + } + }; + + private Map<Character,IMessageHandler> _handlers = new HashMap<Character, IMessageHandler>(); + private BrokerMessageListener _listener; + private final char opcode1 = 'x'; + private final char opcode2 = 'y'; + + + @Override + protected void setUp () throws Exception + { + DomainModel domainModel = new DomainModel(TestConstants.BROKER_ID); + _listener = new BrokerMessageListener(domainModel); + + _handlers.put(opcode1, _emptyMessageHandler); + _handlers.put(opcode2, _anotherEmptyMessageHandler); + } + + /** + * Tests the installation of message handlers on a broker message listener. + * + * <br>precondition : no message handler has been installed on message listener. + * <br>postcondition : two message handlers are installed on message listener. + */ + public void testSetHandlersOK() + { + assertTrue( + "No handler has yet been installed so how is it possible that the handlers map is not empty?", + _listener._handlers.isEmpty()); + + _listener.setHandlers(_handlers); + + assertEquals("Now we should have two handlers configured.",2,_listener._handlers.size()); + assertSame(_listener._handlers.get(opcode1),_emptyMessageHandler); + assertSame(_listener._handlers.get(opcode2),_anotherEmptyMessageHandler); + } + + /** + * Tests the installation of message handlers on a broker message listener. + * Specifically it tries to install three message handlers and one of them is throwing an exception at installation time. + * + * <br>precondition : no message handler has been installed on message listener. + * <br>postcondition : two message handlers are installed on message listener. (the one that thrown exception has been + * discarded). + */ + public void testSetHandlerOK() + { + IMessageHandler wrongMessageHandler = new IMessageHandler() + { + + public void process (Decoder decoder, int sequenceNumber) + { + } + + public void setDomainModel (DomainModel domainModel) + { + throw new RuntimeException(); + } + }; + + char opcodeForWrongHandler = 'k'; + + assertTrue( + "No handler has yet been installed so how is it possible that the handlers map is not empty?", + _listener._handlers.isEmpty()); + + _handlers.put(opcodeForWrongHandler,wrongMessageHandler); + + _listener.setHandlers(_handlers); + + assertEquals("Now we should have two handlers configured.",2,_listener._handlers.size()); + assertSame(_listener._handlers.get(opcode1),_emptyMessageHandler); + assertSame(_listener._handlers.get(opcode2),_anotherEmptyMessageHandler); + assertNull(_listener._handlers.get(opcodeForWrongHandler)); + } + + /** + * Tests the execution of the onMessage() method when a message with a bad magic number is received. + * + * <br>precondition : a message with a bad magic number is received. + * <br>postcondition : the processing of the incoming message is skipped and therefore no handler will be called. + */ + public void testOnMessageKO_withBadMagicNumber() throws IOException + { + IMessageHandler neverCallMe = new IMessageHandler() + { + + public void process (Decoder decoder, int sequenceNumber) + { + fail("This test shouldn't never arrive at this point..."); + } + + public void setDomainModel (DomainModel domainModel) + { + } + }; + + String opcodeForNeverCallMeHandler = "w"; + + _handlers.put('w',neverCallMe); + _listener.setHandlers(_handlers); + + Message message = new ByteBufferMessage(); + message.appendData( ("AMG"+opcodeForNeverCallMeHandler).getBytes()); + + _listener.onMessage(message); + } + + /** + * Tests the execution of the onMessage() method when the incoming message is a compound message. + * + * <br>precondition : the incoming message is a compound message. + * <br>postcondition : each tokenized message is forwarded to the appropriate handler. + */ + public void testOnMessageOK_WithCompoundMessage() throws Exception + { + final Map<Character,IMessageHandler> handlersMap = new HashMap<Character,IMessageHandler>(); + char [] opcodes = {'a','b','c','d','e'}; + + class MockMessageHandler implements IMessageHandler + { + private final char _opcode; + + public MockMessageHandler(char opcode) + { + this._opcode = opcode; + } + + public void process (Decoder decoder, int sequenceNumber) + { + handlersMap.remove(_opcode); + } + + public void setDomainModel (DomainModel domainModel) + { + // Do nothing here. It's just a mock handler. + } + }; + + for (char opcode : opcodes) + { + handlersMap.put(opcode, new MockMessageHandler(opcode)); + } + + // Removes previously injected handlers (i.e. x & y) + _listener._handlers.clear(); + _listener.setHandlers(handlersMap); + + Message compoundMessage = createCompoundMessage(opcodes); + _listener.onMessage(compoundMessage); + + assertTrue(handlersMap.isEmpty()); + } + + // Creates a (non valid) compound message. + private Message createCompoundMessage(char[] opcodes) throws IOException { + byte [] compoundMessageData = new byte [12 * opcodes.length]; + Random randomizer = new Random(); + int position = 0; + + for (char opcode : opcodes) { + System.arraycopy(MessageTokenizer.MAGIC_NUMBER_BYTES, 0, compoundMessageData, position, MessageTokenizer.MAGIC_NUMBER_BYTES.length); + position+=MessageTokenizer.MAGIC_NUMBER_BYTES.length; + + compoundMessageData[position++] = (byte)opcode; + + for (int c = 4; c < 12; c++) + { + byte aByte = (byte)randomizer.nextInt(127); + compoundMessageData[position++] = aByte; + } + } + + Message compoundMessage = new ByteBufferMessage(); + compoundMessage.appendData(compoundMessageData); + return compoundMessage; + } +} diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/MessageTokenizerTest.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/MessageTokenizerTest.java new file mode 100644 index 0000000000..55b8b17f9d --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/MessageTokenizerTest.java @@ -0,0 +1,140 @@ +/*
+*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.management.domain.services;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.*;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.api.Message;
+import org.apache.qpid.nclient.util.ByteBufferMessage;
+import org.apache.qpid.transport.codec.BBDecoder;
+
+/**
+ * Tests case for messaeg tokenizer.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MessageTokenizerTest extends TestCase {
+
+ /**
+ * Tests the execution of the message tokenizer when the given message is not a valid AMQP message.
+ *
+ * <br>precondition : the incoming message is not a valid AMQP message.
+ * <br>postcondition : no exception is thrown and there will be exactly one token with the given message.
+ */
+ public void testOK_WithNoMessage() throws IOException{
+ byte [] noMessage = {2,10,120,23,23,23,4,10,11,12,2,1,3,-22};
+
+ Message multiMessage = new ByteBufferMessage();
+ multiMessage.appendData(noMessage);
+ MessageTokenizer tokenizer = new MessageTokenizer(multiMessage);
+
+ assertEquals(1, tokenizer.countTokens());
+ assertEquals(tokenizer.nextElement(),noMessage);
+ assertFalse(tokenizer.hasMoreElements());
+ }
+
+ /**
+ * Tests the execution of the message tokenizer when the given message contains only one message.
+ *
+ * <br>precondition : the incoming message contains only one message.
+ * <br>postcondition : no exception is thrown and there will be exactly one token with the given message.
+ */
+ public void testOK_WithOneMessage() throws IOException{
+ byte [] oneEncodedMessage = {'A','M','2',23,23,23,4,10,11,12,2,1,3,-22};
+
+ Message multiMessage = new ByteBufferMessage();
+ multiMessage.appendData(oneEncodedMessage);
+ MessageTokenizer tokenizer = new MessageTokenizer(multiMessage);
+
+ assertEquals(1, tokenizer.countTokens());
+ assertEquals(tokenizer.nextElement(),oneEncodedMessage);
+ assertFalse(tokenizer.hasMoreElements());
+ }
+
+ /**
+ * Tests the execution of the message tokenizer when the given message contains a random number of messages.
+ *
+ * <br>precondition : the incoming message contains a random number of messages.
+ * <br>postcondition : no exception is thrown and each built token is a valid message starting with right header.
+ */
+ public void testOK_WithRandomNUmberOfMessages() throws IOException{
+ Random randomizer = new Random();
+
+ int howManyLoops = randomizer.nextInt(10000);
+ howManyLoops = (howManyLoops == 0) ? 10 : howManyLoops;
+ byte [] compoundMessageData = new byte [12 * howManyLoops];
+
+ List<byte []> messages = new ArrayList<byte[]>(howManyLoops);
+
+ int position = 0;
+ for (int i = 0; i < howManyLoops; i++)
+ {
+ byte [] message = new byte[12];
+ System.arraycopy(MessageTokenizer.MAGIC_NUMBER_BYTES, 0, compoundMessageData, position, MessageTokenizer.MAGIC_NUMBER_BYTES.length);
+ System.arraycopy(MessageTokenizer.MAGIC_NUMBER_BYTES, 0, message, 0, MessageTokenizer.MAGIC_NUMBER_BYTES.length);
+ position+=MessageTokenizer.MAGIC_NUMBER_BYTES.length;
+
+ for (int c = 3; c < 12; c++)
+ {
+ byte aByte = (byte)randomizer.nextInt(127);
+ aByte = (aByte == 77) ? (byte)c : aByte;
+ compoundMessageData[position++] = aByte;
+ message[c] = aByte;
+ }
+ messages.add(message);
+ }
+
+ Message multiMessage = new ByteBufferMessage();
+ multiMessage.appendData(compoundMessageData);
+ MessageTokenizer tokenizer = new MessageTokenizer(multiMessage);
+
+ int howManyTokens = tokenizer.countTokens();
+ assertEquals(howManyLoops, howManyTokens);
+
+ int index = 0;
+ while (tokenizer.hasMoreElements())
+ {
+ assertEquals(tokenizer.nextElement(),messages.get(index++));
+ }
+
+ assertEquals((index),howManyTokens);
+ }
+
+ /**
+ * Internal method used for comparison of two messages.
+ *
+ * @param message the token message just built by the tokenizer.
+ * @param expected the expected result.
+ */
+ private void assertEquals(Message message, byte [] expected) throws IOException
+ {
+ ByteBuffer messageContent = message.readData();
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(messageContent);
+ byte [] content = decoder.readReaminingBytes();
+ assertTrue(Arrays.equals(content, expected));
+ }
+}
diff --git a/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/online/BaseOnlineTestCase.java b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/online/BaseOnlineTestCase.java new file mode 100644 index 0000000000..82a7a1698c --- /dev/null +++ b/RC9/qpid/java/management/client/src/test/java/org/apache/qpid/management/online/BaseOnlineTestCase.java @@ -0,0 +1,58 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.online; + +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; + +import junit.framework.TestCase; + +/** + * Layer supertype for all online QMan test cases. + * Note that QMan must be running and up in order to run concrete subclasses (test cases). + * + * @author AGazzarini + */ +public abstract class BaseOnlineTestCase extends TestCase +{ + protected MBeanServerConnection connection; + + /** + * Setup fixture for this test case. + * Basically it estabilishes a connection to QMan using RMI JMX connector. + */ + @Override + protected void setUp () + { + try + { + JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi"); + JMXConnector jmxc = JMXConnectorFactory.connect(url); + connection = jmxc.getMBeanServerConnection(); + } catch(Exception exception) + { + fail("QMan must be running and up in order to run this test!"); + exception.printStackTrace(); + } + } +} diff --git a/RC9/qpid/java/management/client/web.xml b/RC9/qpid/java/management/client/web.xml new file mode 100644 index 0000000000..71ca74b2e5 --- /dev/null +++ b/RC9/qpid/java/management/client/web.xml @@ -0,0 +1,32 @@ +<!-- + - + - Licensed to the Apache Software Foundation (ASF) under one + - or more contributor license agreements. See the NOTICE file + - distributed with this work for additional information + - regarding copyright ownership. The ASF licenses this file + - to you under the Apache License, Version 2.0 (the + - "License"); you may not use this file except in compliance + - with the License. You may obtain a copy of the License at + - + - http://www.apache.org/licenses/LICENSE-2.0 + - + - Unless required by applicable law or agreed to in writing, + - software distributed under the License is distributed on an + - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + - KIND, either express or implied. See the License for the + - specific language governing permissions and limitations + - under the License. + - + --> + +<?xml version="1.0" encoding="UTF-8"?> +<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> + <display-name>QManEE</display-name> + <description>Web Application used for integrating QMan onto an Application Server.</description> + <servlet> + <display-name>QMan Servlet (Initializer)</display-name> + <servlet-name>QManServlet</servlet-name> + <servlet-class>org.apache.qpid.management.servlet.QManServlet</servlet-class> + <load-on-startup>1</load-on-startup> + </servlet> +</web-app> diff --git a/RC9/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF b/RC9/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..15fcd8d59a --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF @@ -0,0 +1,21 @@ +Manifest-Version: 1.0 +Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt +Bundle-ManifestVersion: 2 +Bundle-Name: Qpid Management Console Plug-in +Bundle-SymbolicName: org.apache.qpid.management.ui; singleton:=true +Bundle-Version: 0.1.0 +Bundle-Activator: org.apache.qpid.management.ui.Activator +Bundle-Vendor: Apache Software Foundation +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.ui.forms, + jmxremote.sasl;resolution:=optional +Eclipse-LazyStart: true +Export-Package: org.apache.qpid.management.ui, + org.apache.qpid.management.ui.actions, + org.apache.qpid.management.ui.exceptions, + org.apache.qpid.management.ui.jmx, + org.apache.qpid.management.ui.model, + org.apache.qpid.management.ui.sasl, + org.apache.qpid.management.ui.views diff --git a/RC9/qpid/java/management/eclipse-plugin/README.txt b/RC9/qpid/java/management/eclipse-plugin/README.txt new file mode 100644 index 0000000000..5325bf27ec --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/README.txt @@ -0,0 +1,21 @@ + +Running the Qpid Management Console (eclipse-plugin) +---------------------------------------------------- + +To run the management console, set the QPIDMC_HOME environment variable to +qpid management console root directory (e.g. C:/qpidmc)and add $QPIDMC_HOME/bin to your PATH. +Then run the script to launch the management console- +For Windows: +------------ +qpidmc.bat +qpidmc.sh (using cygwin) + +Unix: +----- +qpidmc.sh <operating system> <windowing system> <platform achitecture> +eg. qpidms.sh linux motif x86 +qpidmc_motif.sh +qpidmc_gtk.sh + +Apache confluence page for latest information: +http://cwiki.apache.org/confluence/display/qpid/Qpid+Management+Console diff --git a/RC9/qpid/java/management/eclipse-plugin/bin/qpidmc.bat b/RC9/qpid/java/management/eclipse-plugin/bin/qpidmc.bat new file mode 100644 index 0000000000..22a8a4d78c --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/bin/qpidmc.bat @@ -0,0 +1,55 @@ +@REM
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM
+
+@echo off
+REM Script to run the Qpid Management Console
+
+rem Guess QPIDMC_HOME if not defined
+set CURRENT_DIR=%cd%
+if not "%QPIDMC_HOME%" == "" goto gotHome
+set QPIDMC_HOME=%CURRENT_DIR%
+echo %QPIDMC_HOME%
+if exist "%QPIDMC_HOME%\bin\qpidmc.bat" goto okHome
+cd ..
+set QPIDMC_HOME=%cd%
+cd %CURRENT_DIR%
+:gotHome
+if exist "%QPIDMC_HOME%\bin\qpidmc.bat" goto okHome
+echo The QPIDMC_HOME environment variable is not defined correctly
+echo This environment variable is needed to run this program
+goto end
+:okHome
+
+if not "%JAVA_HOME%" == "" goto gotJavaHome
+echo The JAVA_HOME environment variable is not defined
+echo This environment variable is needed to run this program
+goto exit
+:gotJavaHome
+if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome
+goto okJavaHome
+:noJavaHome
+echo The JAVA_HOME environment variable is not defined correctly
+echo This environment variable is needed to run this program.
+goto exit
+:okJavaHome
+
+rem Slurp the command line arguments. This loop allows for an unlimited number
+rem of agruments (up to the command line limit, anyway).
+
+"%JAVA_HOME%\bin\java" -Xms40m -Xmx256m -Declipse.consoleLog=false -jar "%QPIDMC_HOME%\eclipse\startup.jar" org.eclipse.core.launcher.Main -launcher "%QPIDMC_HOME%\eclipse\eclipse" -name "Qpid Management Console" -showsplash 600 -configuration "file:%QPIDMC_HOME%\configuration" -os win32 -ws win32 -arch x86
diff --git a/RC9/qpid/java/management/eclipse-plugin/bin/qpidmc.sh b/RC9/qpid/java/management/eclipse-plugin/bin/qpidmc.sh new file mode 100755 index 0000000000..599d9bf7e0 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/bin/qpidmc.sh @@ -0,0 +1,75 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +if [ -z "$JAVA" ]; then + JAVA=java +fi + +if [ -z "$QPIDMC_HOME" ]; then + export QPIDMC_HOME=$(dirname $(dirname $(readlink -f $0))) + export PATH=${PATH}:${QPIDMC_HOME}/bin +fi + +# Test if we're running on cygwin. +cygwin=false +if [[ "$(uname -a | fgrep Cygwin)" != "" ]]; then + cygwin=true +fi + +if $cygwin; then + QPIDMC_HOME=$(cygpath -w $QPIDMC_HOME) +fi + + +## If this is to be run on different platform other than windows then following parameters should be passed +## qpidmc.sh <windowing system> +## eg. qpidmc.sh motif + +if [ $# -eq 1 ] ; then + QPIDMC_WS=$1 +else + # If the WS is not set via QPIDMC_WS then query uname for the WS + if [ -z "$QPIDMC_WS" ] ; then + echo "Usage qpidmc.sh <windowing system> + echo "Alternatively set QPIDMC_WS to the windowing system you wish to use + exit 1 + fi +fi + +# If the OS is not set via QPIDMC_OS then query uname for the OS +if [ -z "$QPIDMC_OS" ] ; then + QPIDMC_OS=`uname | tr A-Z a-z` +else + # Force OS to be lower case + QPIDMC_OS=`echo $QPIDMC_OS | tr A-Z a-z` +fi + +# If the ARCH is not set via QPIDMC_ARCH then query uname for the arch, +if [ -z "$QPIDMC_ARCH" ] ; then + QPIDMC_ARCH=`uname -i` +fi + +# Note that it sometimes returns i386 which needs to be changed to x86 +if [ "$QPIDMC_ARCH" == "i386" ] ; then + QPIDMC_ARCH="x86" +fi + + +"$JAVA" -Xms40m -Xmx256m -Declipse.consoleLog=true -jar $QPIDMC_HOME/eclipse/startup.jar org.eclipse.core.launcher.Main -name "Qpid Management Console" -showsplash 600 -configuration "file:$QPIDMC_HOME/configuration" -os $QPIDMC_OS -ws $QPIDMC_WS -arch $QPIDMC_ARCH diff --git a/RC9/qpid/java/management/eclipse-plugin/bin/qpidmc_gtk.sh b/RC9/qpid/java/management/eclipse-plugin/bin/qpidmc_gtk.sh new file mode 100755 index 0000000000..1d55743d84 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/bin/qpidmc_gtk.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +if [ -z "$QPIDMC_HOME" ]; then + export QPIDMC_HOME=$(dirname $(dirname $(readlink -f $0))) + export PATH=${PATH}:${QPIDMC_HOME}/bin +fi + +$QPIDMC_HOME/bin/qpidmc.sh gtk diff --git a/RC9/qpid/java/management/eclipse-plugin/bin/qpidmc_motif.sh b/RC9/qpid/java/management/eclipse-plugin/bin/qpidmc_motif.sh new file mode 100755 index 0000000000..f49759cc91 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/bin/qpidmc_motif.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +$QPIDMC_HOME/bin/qpidmc.sh motif diff --git a/RC9/qpid/java/management/eclipse-plugin/build-release-common.properties b/RC9/qpid/java/management/eclipse-plugin/build-release-common.properties new file mode 100644 index 0000000000..65ef9be092 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/build-release-common.properties @@ -0,0 +1,38 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# + +artifactId=org.apache.qpid.management.ui +mcplugin.version=0.1.0-${project.version} +mcplugin.filename=${artifactId}_${mcplugin.version} + +mcplugin.contents.dir=${module.classes} + +mcplugin.manifest=${module.manifest} + +bin.dir=bin + +startup.jar=src/main/resources/startup.jar + +eclipse.ini=src/main/resources/eclipse.ini + +license.eclipse.txt=src/main/resources/license.eclipse.txt + +jmxremote.sasl.manifest=src/main/resources/sasl/MANIFEST.MF diff --git a/RC9/qpid/java/management/eclipse-plugin/build-release-linux-gtk-x86.properties b/RC9/qpid/java/management/eclipse-plugin/build-release-linux-gtk-x86.properties new file mode 100644 index 0000000000..5aef021763 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/build-release-linux-gtk-x86.properties @@ -0,0 +1,34 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# + +release.name=${module.namever}-linux-gtk-x86 + +release.subdir=${module.release.base}/${release.name} + +release.tar.gz=${module.release.base}/${release.name}.tar.gz + +eclipse.ini=src/main/resources/unix/eclipse.ini + +rcp.libs=${management-eclipse-plugin-linux-gtk-x86.libs} + +rcp.configuration.dir=src/main/resources/unix/configuration + +bin.includes=qpidmc.sh qpidmc_gtk.sh diff --git a/RC9/qpid/java/management/eclipse-plugin/build-release-macosx.properties b/RC9/qpid/java/management/eclipse-plugin/build-release-macosx.properties new file mode 100644 index 0000000000..cdeef836ed --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/build-release-macosx.properties @@ -0,0 +1,40 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# + +application.name=Qpid Management Console + +application.dir=${application.name}.app + +release.name=${module.namever}-macosx + +release.subdir=${module.release.base}/${release.name} + +release.zip=${module.release.base}/${release.name}.zip + +rcp.libs=${management-eclipse-plugin-macosx.libs} + +rcp.configuration.dir=src/main/resources/macosx/Configuration + +eclipse.ini=src/main/resources/macosx/eclipse.ini +bin.includes=src/main/resources/macosx/eclipse + +eclipse.icns=src/main/resources/icons/Console.icns +macosx.plist=src/main/resources/macosx/Info.plist diff --git a/RC9/qpid/java/management/eclipse-plugin/build-release-macosx.xml b/RC9/qpid/java/management/eclipse-plugin/build-release-macosx.xml new file mode 100644 index 0000000000..4a51ab5727 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/build-release-macosx.xml @@ -0,0 +1,91 @@ +<!-- + - + - Licensed to the Apache Software Foundation (ASF) under one + - or more contributor license agreements. See the NOTICE file + - distributed with this work for additional information + - regarding copyright ownership. The ASF licenses this file + - to you under the Apache License, Version 2.0 (the + - "License"); you may not use this file except in compliance + - with the License. You may obtain a copy of the License at + - + - http://www.apache.org/licenses/LICENSE-2.0 + - + - Unless required by applicable law or agreed to in writing, + - software distributed under the License is distributed on an + - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + - KIND, either express or implied. See the License for the + - specific language governing permissions and limitations + - under the License. + - + --> +<project name="Eclipse Plugin Binary Release" default="release-bin"> + + <import file="build-release.xml"/> + + <property name="release.app" value="${release.subdir}/${application.dir}"/> + + <target name="release-bin-mcplugin-jar"> + <jar destfile="${release.app}/plugins/${mcplugin.filename}.jar" basedir="${mcplugin.contents.dir}" manifest="${mcplugin.manifest}"/> + </target> + + <target name="release-bin-jmxremote-plugin"> + <!-- Copy the jmxremote.sasl plugin's manifest, creating its plugin directory --> + <copy todir="${release.app}/plugins/jmxremote.sasl_1.0.1/META-INF" flatten="true" failonerror="true"> + <fileset file="${jmxremote.sasl.manifest}"/> + </copy> + </target> + + + <target name="release-bin-rcp-deps" description="copy eclipse-rcp dependencies into module release" + depends="copy-executable"> + + <!-- Copy remaining Eclipse binary and start-up files --> + <copy todir="${release.app}/Contents/MacOS" flatten="true" failonerror="true"> + <fileset file="${eclipse.ini}"/> + <fileset file="${bin.includes}"/> + </copy> + + <chmod dir="${release.app}/Contents/MacOS" perm="u+rx" includes="**/*"/> + + <!-- Copy MacOS plist file --> + <copy todir="${release.app}/Contents" flatten="true" failonerror="true"> + <fileset file="${macosx.plist}"/> + </copy> + + <!-- Copy remaining Eclipse binary and start-up files --> + <copy todir="${release.app}/Contents/Resources" flatten="true" failonerror="true"> + <fileset file="${eclipse.icns}"/> + </copy> + + <!-- Copy License file --> + <copy todir="${release.app}" flatten="true" failonerror="true"> + <fileset file="${license.eclipse.txt}"/> + </copy> + + <!-- Copy the eclipse rcp module libs --> + <copy todir="${release.app}/plugins" failonerror="true"> + <fileset dir="${project.root}" includes="${rcp.libs}"/> + <globmapper from="lib/*" to="*"/> + </copy> + + <!-- Copy the relevant configuration dir --> + <copy todir="${release.app}/Configuration" failonerror="true"> + <fileset dir="${rcp.configuration.dir}"/> + </copy> + <chmod dir="${release.app}/Configuration" perm="ugo+r" includes="**/*"/> + </target> + + <target name="release-bin-zip" if="release.zip" description="build mc zip archive"> + + <zip destfile="${release.zip}"> + <zipfileset dir="${release.subdir}" filemode="755"> + <include name="${application.dir}/Contents/MacOS/**"/> + </zipfileset> + + <zipfileset dir="${release.subdir}" filemode="644" dirmode="755"> + <exclude name="${application.dir}/Contents/MacOS/**"/> + </zipfileset> + </zip> + </target> + +</project> diff --git a/RC9/qpid/java/management/eclipse-plugin/build-release-win32-win32-x86.properties b/RC9/qpid/java/management/eclipse-plugin/build-release-win32-win32-x86.properties new file mode 100644 index 0000000000..1f28ccb99f --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/build-release-win32-win32-x86.properties @@ -0,0 +1,34 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# + +release.name=${module.namever}-win32-win32-x86 + +release.subdir=${module.release.base}/${release.name} + +release.zip=${module.release.base}/${release.name}.zip + +eclipse.executable=src/main/resources/eclipse.exe + +rcp.libs=${management-eclipse-plugin-win32-win32-x86.libs} + +rcp.configuration.dir=src/main/resources/win32/configuration + +bin.includes=qpidmc.bat diff --git a/RC9/qpid/java/management/eclipse-plugin/build-release.xml b/RC9/qpid/java/management/eclipse-plugin/build-release.xml new file mode 100644 index 0000000000..b116fcb55c --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/build-release.xml @@ -0,0 +1,152 @@ +<!-- + - + - Licensed to the Apache Software Foundation (ASF) under one + - or more contributor license agreements. See the NOTICE file + - distributed with this work for additional information + - regarding copyright ownership. The ASF licenses this file + - to you under the Apache License, Version 2.0 (the + - "License"); you may not use this file except in compliance + - with the License. You may obtain a copy of the License at + - + - http://www.apache.org/licenses/LICENSE-2.0 + - + - Unless required by applicable law or agreed to in writing, + - software distributed under the License is distributed on an + - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + - KIND, either express or implied. See the License for the + - specific language governing permissions and limitations + - under the License. + - + --> +<project name="Eclipse Plugin Binary Release" default="release-bin"> + + <!-- check properties that must be set by caller --> + <target name="check" description="ensure all required properties are set"> + <condition property="properties.set"> + <and> + <!-- common properties --> + <isset property ="mcplugin.contents.dir"/> + <isset property ="mcplugin.manifest"/> + <isset property ="mcplugin.filename"/> + <isset property ="bin.dir"/> + <isset property ="startup.jar"/> + <isset property ="eclipse.ini"/> + <isset property ="license.eclipse.txt"/> + <isset property ="jmxremote.sasl.manifest"/> + <!-- platform specific properties --> + <isset property ="bin.includes"/> + <isset property ="release.name"/> + <isset property ="release.subdir"/> + <isset property ="rcp.libs"/> + <isset property ="rcp.configuration.dir"/> + <or> + <isset property ="release.zip"/> + <isset property ="release.tar.gz"/> + </or> + </and> + <!-- Optional Properties --> + <!-- eclipse.executable.companion.library --> + </condition> + + <fail unless="properties.set" message="required properties not set"/> + </target> + + <target name="release-bin-prepare"> + <mkdir dir="${release.subdir}"/> + </target> + + <target name="release-bin-mcplugin-jar"> + <jar destfile="${release.subdir}/eclipse/plugins/${mcplugin.filename}.jar" basedir="${mcplugin.contents.dir}" manifest="${mcplugin.manifest}"/> + </target> + + <target name="release-bin-jmxremote-plugin"> + <!-- Copy the jmxremote.sasl plugin's manifest, creating its plugin directory --> + <copy todir="${release.subdir}/eclipse/plugins/jmxremote.sasl_1.0.1/META-INF" flatten="true" failonerror="true"> + <fileset file="${jmxremote.sasl.manifest}"/> + </copy> + </target> + + <target name="copy-executable" description="Copy eclipse-rcp execuitable" if="eclipse.executable"> + + <!-- Copy the eclipse rcp executable files --> + <copy todir="${release.subdir}/eclipse" flatten="true" failonerror="true"> + <fileset file="${eclipse.executable}"/> + </copy> + <chmod dir="${release.subdir}/eclipse" perm="u+rx" includes="**/*"/> + + + </target> + + <target name="release-bin-rcp-deps" description="copy eclipse-rcp dependencies into module release" + depends="copy-executable"> + + <!-- Copy remaining startup & license files --> + <copy todir="${release.subdir}/eclipse" flatten="true" failonerror="true"> + <fileset file="${startup.jar}"/> + <fileset file="${eclipse.ini}"/> + <fileset file="${license.eclipse.txt}"/> + </copy> + + <echo message="${ecl-swt-linux-gtk-x86}"/> + <echo message="${management-eclipse-plugin-linux-gtk-x86.libs}"/> + <echo message="${rcp.libs}"/> + <!-- Copy the eclipse rcp module libs --> + <copy todir="${release.subdir}/eclipse/plugins" failonerror="true"> + + <fileset dir="${project.root}" includes="${rcp.libs}"/> + <globmapper from="lib/*" to="*"/> + </copy> + + <!-- Copy the relevant bin dir files--> + <copy todir="${release.subdir}/bin" failonerror="true"> + <fileset dir="${bin.dir}" includes="${bin.includes}"/> + </copy> + <chmod dir="${release.subdir}/bin" perm="u+rx" includes="**/*"/> + + <!-- Copy the relevant configuration dir --> + <copy todir="${release.subdir}/configuration" failonerror="true"> + <fileset dir="${rcp.configuration.dir}"/> + </copy> + <chmod dir="${release.subdir}/configuration" perm="ugo+r" includes="**/*"/> + </target> + + <target name="release-bin-zip" if="release.zip" description="build mc zip archive"> + <zip destfile="${release.zip}"> + <zipfileset dir="${release.subdir}" prefix="${release.name}" filemode="755"> + <include name="bin/*"/> + </zipfileset> + + <zipfileset dir="${release.subdir}" prefix="${release.name}" filemode="755"> + <include name="eclipse/eclipse*"/> + </zipfileset> + + <zipfileset dir="${release.subdir}" prefix="${release.name}" filemode="644" dirmode="755"> + <exclude name="bin/**"/> + <exclude name="eclipse/eclipse*"/> + </zipfileset> + </zip> + </target> + + <target name="release-bin-gzip" if="release.tar.gz" description="build mc tar.gz archive"> + <tar destfile="${release.tar.gz}" longfile="gnu"> + <tarfileset dir="${release.subdir}" prefix="${release.name}" filemode="755"> + <include name="bin/*"/> + </tarfileset> + + <tarfileset dir="${release.subdir}" prefix="${release.name}" filemode="755"> + <include name="eclipse/eclipse*"/> + </tarfileset> + + <tarfileset dir="${release.subdir}" prefix="${release.name}" filemode="644" dirmode="755"> + <exclude name="bin/**"/> + <exclude name="eclipse/eclipse*"/> + </tarfileset> + </tar> + </target> + + + + <target name="release-bin" depends="check,release-bin-prepare,release-bin-rcp-deps, + release-bin-mcplugin-jar,release-bin-jmxremote-plugin,release-bin-zip,release-bin-gzip"/> + +</project> diff --git a/RC9/qpid/java/management/eclipse-plugin/build.xml b/RC9/qpid/java/management/eclipse-plugin/build.xml new file mode 100644 index 0000000000..2c36e79823 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/build.xml @@ -0,0 +1,88 @@ +<!-- + - + - Licensed to the Apache Software Foundation (ASF) under one + - or more contributor license agreements. See the NOTICE file + - distributed with this work for additional information + - regarding copyright ownership. The ASF licenses this file + - to you under the Apache License, Version 2.0 (the + - "License"); you may not use this file except in compliance + - with the License. You may obtain a copy of the License at + - + - http://www.apache.org/licenses/LICENSE-2.0 + - + - Unless required by applicable law or agreed to in writing, + - software distributed under the License is distributed on an + - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + - KIND, either express or implied. See the License for the + - specific language governing permissions and limitations + - under the License. + - + --> +<project name="Eclipse Plugin" default="build"> + + <property name="module.depends" value="broker common"/> + + <import file="../../module.xml"/> + + <!-- module.manifest property to invoke use of 'jar.manifest' jar target when building --> + <property name="module.manifest" value="${module.classes}/META-INF/MANIFEST.MF"/> + + <target name="copy-plugin-files" description="copy eclipse management plugin files into build tree"> + <copy todir="${module.classes}/icons" failonerror="true"> + <fileset dir="icons/"/> + </copy> + <copy todir="${module.classes}/META-INF/" failonerror="true"> + <fileset dir="META-INF/"/> + </copy> + <copy todir="${module.classes}" failonerror="true"> + <fileset file="icons/splash.bmp"/> + </copy> + <copy todir="${module.classes}" failonerror="true"> + <fileset file="plugin.properties"/> + </copy> + <copy todir="${module.classes}" failonerror="true"> + <fileset file="plugin.xml"/> + </copy> + </target> + + <target name="create-version" description="Create the version file"> + + <exec executable="svnversion" spawn="false" failifexecutionfails="false" + dir="." outputproperty="svnversion"> + <arg line="."/> + </exec> + + <!-- Write the version.properties out. --> + <propertyfile file="${module.classes}/qpidversion.properties"> + <entry key="qpid.version" value="${project.version}"/> + <entry key="qpid.svnversion" value="${svnversion}"/> + <entry key="qpid.name" value="${project.name}"/> + </propertyfile> + + </target> + + + <!-- Override imported module.xml build target, create module jar containing plugin files --> + <target name="build" depends="prepare, compile, copy-plugin-files, create-version, jar, jar-tests"/> + + <!-- Override imported module.xml release-bin target --> + <target name="release-bin" depends="build"> + <!-- linux gtk x86 --> + <ant antfile="build-release.xml"> + <property file="build-release-linux-gtk-x86.properties"/> + <property file="build-release-common.properties"/> + </ant> + <!-- mac os x --> + <ant antfile="build-release-macosx.xml"> + <property file="build-release-macosx.properties"/> + <property file="build-release-common.properties"/> + </ant> + + <!-- win32 win32 x86 --> + <ant antfile="build-release.xml"> + <property file="build-release-win32-win32-x86.properties"/> + <property file="build-release-common.properties"/> + </ant> + </target> + +</project> diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/Thumbs.db b/RC9/qpid/java/management/eclipse-plugin/icons/Thumbs.db Binary files differnew file mode 100644 index 0000000000..306bfb2eda --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/Thumbs.db diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/add.gif b/RC9/qpid/java/management/eclipse-plugin/icons/add.gif Binary files differnew file mode 100644 index 0000000000..252d7ebcb8 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/add.gif diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/delete.gif b/RC9/qpid/java/management/eclipse-plugin/icons/delete.gif Binary files differnew file mode 100644 index 0000000000..6f647666d3 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/delete.gif diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/icon_ClosedFolder.gif b/RC9/qpid/java/management/eclipse-plugin/icons/icon_ClosedFolder.gif Binary files differnew file mode 100644 index 0000000000..beb6ed134c --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/icon_ClosedFolder.gif diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/icon_OpenFolder.gif b/RC9/qpid/java/management/eclipse-plugin/icons/icon_OpenFolder.gif Binary files differnew file mode 100644 index 0000000000..a9c777343c --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/icon_OpenFolder.gif diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/mbean_view.png b/RC9/qpid/java/management/eclipse-plugin/icons/mbean_view.png Binary files differnew file mode 100644 index 0000000000..9871b72bb8 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/mbean_view.png diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/notifications.gif b/RC9/qpid/java/management/eclipse-plugin/icons/notifications.gif Binary files differnew file mode 100644 index 0000000000..f1e585bdf7 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/notifications.gif diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/qpidConnections.gif b/RC9/qpid/java/management/eclipse-plugin/icons/qpidConnections.gif Binary files differnew file mode 100644 index 0000000000..89489f11f2 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/qpidConnections.gif diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/qpidmc.gif b/RC9/qpid/java/management/eclipse-plugin/icons/qpidmc.gif Binary files differnew file mode 100644 index 0000000000..baf929fbc5 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/qpidmc.gif diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/qpidmc16.gif b/RC9/qpid/java/management/eclipse-plugin/icons/qpidmc16.gif Binary files differnew file mode 100644 index 0000000000..4df535bb9a --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/qpidmc16.gif diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/qpidmc32.bmp b/RC9/qpid/java/management/eclipse-plugin/icons/qpidmc32.bmp Binary files differnew file mode 100644 index 0000000000..e42ce01dff --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/qpidmc32.bmp diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/qpidmc32.gif b/RC9/qpid/java/management/eclipse-plugin/icons/qpidmc32.gif Binary files differnew file mode 100644 index 0000000000..e42ce01dff --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/qpidmc32.gif diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/reconnect.gif b/RC9/qpid/java/management/eclipse-plugin/icons/reconnect.gif Binary files differnew file mode 100644 index 0000000000..e2f8c3e1fe --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/reconnect.gif diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/refresh.gif b/RC9/qpid/java/management/eclipse-plugin/icons/refresh.gif Binary files differnew file mode 100644 index 0000000000..a063c230ac --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/refresh.gif diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/splash.bmp b/RC9/qpid/java/management/eclipse-plugin/icons/splash.bmp Binary files differnew file mode 100644 index 0000000000..b528a508c5 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/splash.bmp diff --git a/RC9/qpid/java/management/eclipse-plugin/icons/stop.gif b/RC9/qpid/java/management/eclipse-plugin/icons/stop.gif Binary files differnew file mode 100644 index 0000000000..dc47edf069 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/icons/stop.gif diff --git a/RC9/qpid/java/management/eclipse-plugin/plugin.properties b/RC9/qpid/java/management/eclipse-plugin/plugin.properties new file mode 100644 index 0000000000..8507441886 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/plugin.properties @@ -0,0 +1,20 @@ +############################################################################### +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +############################################################################### +pluginName = Qpid Management Console Plug-in +providerName = Apache Software Foundation
\ No newline at end of file diff --git a/RC9/qpid/java/management/eclipse-plugin/plugin.xml b/RC9/qpid/java/management/eclipse-plugin/plugin.xml new file mode 100644 index 0000000000..5774859b47 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/plugin.xml @@ -0,0 +1,223 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.2"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<plugin> + + <extension + id="application" + point="org.eclipse.core.runtime.applications"> + <application> + <run + class="org.apache.qpid.management.ui.Application"> + </run> + </application> + </extension> + <extension + point="org.eclipse.ui.perspectives"> + <perspective + name="qpid.management.perspective" + class="org.apache.qpid.management.ui.Perspective" + id="org.apache.qpid.management.ui.perspective"> + </perspective> + </extension> + <extension + point="org.eclipse.ui.views"> + <category + id="org.apache.qpid.management.ui.viewcategory" + name="Qpid Management Console"/> + <view + allowMultiple="false" + category="org.apache.qpid.management.ui.viewcategory" + class="org.apache.qpid.management.ui.views.NavigationView" + icon="icons/qpidConnections.gif" + id="org.apache.qpid.management.ui.navigationView" + name="Qpid Connections"> + </view> + <view + allowMultiple="false" + category="org.apache.qpid.management.ui.viewcategory" + class="org.apache.qpid.management.ui.views.MBeanView" + icon="icons/mbean_view.png" + id="org.apache.qpid.management.ui.mbeanView" + name="Qpid Management"> + </view> + </extension> + <extension + point="org.eclipse.ui.commands"> + <category + name="qpid.manager.commands" + id="org.apache.qpid.management.ui.category"> + </category> + <command + name="New Connection" + description="Created a new Qpid server connection" + categoryId="org.apache.qpid.management.ui.category" + id="org.apache.qpid.management.ui.actions.cmd_add"> + </command> + <command + categoryId="org.apache.qpid.management.ui.category" + description="Reconnect the Qpid server connection" + id="org.apache.qpid.management.ui.actions.cmd_reconnect" + name="Reconnect"/> + <command + categoryId="org.apache.qpid.management.ui.category" + description="Disconnects the Qpid server connection" + id="org.apache.qpid.management.ui.actions.cmd_disconnect" + name="Disconnect"/> + <command + categoryId="org.apache.qpid.management.ui.category" + description="Removes the server from management console" + id="org.apache.qpid.management.ui.actions.cmd_remove" + name="Remove Connection"/> + <command + categoryId="org.apache.qpid.management.ui.category" + description="refreshes the views" + id="org.apache.qpid.management.ui.actions.cmd_refresh" + name="Refresh"/> + <command + categoryId="org.apache.qpid.management.ui.category" + description="pops up the window for editing selected attribute" + id="org.apache.qpid.management.ui.actions.cmd_editAttribute" + name="Edit Attribute"/> + <command + categoryId="org.apache.qpid.management.ui.category" + description="About Qpid Management Console" + id="qpidmc.about" + name="About"/> + </extension> + <extension + point="org.eclipse.ui.bindings"> + <key + commandId="org.apache.qpid.management.ui.actions.cmd_add" + schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" + sequence="CTRL+Alt+N"> + </key> + <key + commandId="org.apache.qpid.management.ui.actions.cmd_reconnect" + schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" + sequence="CTRL+Alt+C"/> + <key + commandId="org.apache.qpid.management.ui.actions.cmd_disconnect" + schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" + sequence="CTRL+Alt+D"> + </key> + <key + commandId="org.apache.qpid.management.ui.actions.cmd_remove" + schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" + sequence="CTRL+Alt+R"/> + <key + commandId="org.apache.qpid.management.ui.actions.cmd_refresh" + schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" + sequence="CTRL+Alt+F5"/> + <key + commandId="org.apache.qpid.management.ui.actions.cmd_editAttribute" + schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" + sequence="CTRL+Alt+E"/> + <key + commandId="org.eclipse.ui.file.exit" + schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" + sequence="CTRL+Alt+X"> + </key> + </extension> + + <extension + id="product" + point="org.eclipse.core.runtime.products"> + <product + application="org.apache.qpid.management.ui.application" + name="Qpid Management Console"> + <property + name="windowImages" + value="icons/qpidmc16.gif,icons/qpidmc32.gif"> + </property> + <property + name="aboutText" + value="Qpid Management Console"/> + </product> + </extension> + <extension + point="org.eclipse.ui.actionSets"> + <actionSet + id="org.apache.qpid.management.ui.actionSet" + label="Qpid Action Set" + visible="true"> + <menu + id="qpidmanager" + label="&Qpid Manager"> + <separator name="qpidActionsGroup"/> + </menu> + <action + class="org.apache.qpid.management.ui.actions.EditAttribute" + definitionId="org.apache.qpid.management.ui.actions.cmd_editAttribute" + id="org.apache.qpid.management.ui.actions.editAttribute" + label="Edit Attribute" + menubarPath="qpidmanager/mbeanactions" + style="push" + tooltip="Edit Attribute"/> + <action + class="org.apache.qpid.management.ui.actions.Refresh" + definitionId="org.apache.qpid.management.ui.actions.cmd_refresh" + icon="icons/refresh.gif" + id="org.apache.qpid.management.ui.actions.refresh" + label="Refresh" + menubarPath="qpidmanager/additions" + style="push" + toolbarPath="qpidActionsGroup" + tooltip="Refresh"/> + <action + class="org.apache.qpid.management.ui.actions.RemoveServer" + definitionId="org.apache.qpid.management.ui.actions.cmd_remove" + icon="icons/delete.gif" + id="org.apache.qpid.management.ui.actions.remove" + label="Remove Connection" + menubarPath="qpidmanager/additions" + style="push" + toolbarPath="qpidActionsGroup"/> + <action + class="org.apache.qpid.management.ui.actions.CloseConnection" + definitionId="org.apache.qpid.management.ui.actions.cmd_disconnect" + icon="icons/stop.gif" + id="org.apache.qpid.management.ui.disconnect" + label="Disconnect" + menubarPath="qpidmanager/additions" + toolbarPath="qpidActionsGroup" + tooltip="Disconnect"/> + <action + class="org.apache.qpid.management.ui.actions.ReconnectServer" + definitionId="org.apache.qpid.management.ui.actions.cmd_reconnect" + icon="icons/reconnect.gif" + id="org.apache.qpid.management.ui.reconnect" + label="Reconnect" + menubarPath="qpidmanager/additions" + toolbarPath="qpidActionsGroup" + tooltip="Reconnect"/> + <action + class="org.apache.qpid.management.ui.actions.AddServer" + definitionId="org.apache.qpid.management.ui.actions.cmd_add" + icon="icons/add.gif" + id="org.apache.qpid.management.ui.add" + label="New Connection" + menubarPath="qpidmanager/additions" + toolbarPath="qpidActionsGroup" + tooltip="New Connection"/> + </actionSet> + </extension> + +</plugin> diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Activator.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Activator.java new file mode 100644 index 0000000000..5eab267c28 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Activator.java @@ -0,0 +1,84 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + * @author Bhupendra Bhardwaj + */ +public class Activator extends AbstractUIPlugin +{ + // The plug-in ID + public static final String PLUGIN_ID = "org.apache.qpid.management.ui"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() + { + plugin = this; + } + + /* + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception + { + super.start(context); + } + + /* + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception + { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() + { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given plug-in relative path + * + * @param path the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) + { + return imageDescriptorFromPlugin(PLUGIN_ID, path); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Application.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Application.java new file mode 100644 index 0000000000..a1c4b7ddb0 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Application.java @@ -0,0 +1,63 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +import org.eclipse.core.runtime.IPlatformRunnable; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; + +/** + * This class controls all aspects of the application's execution + * @author Bhupendra Bhardwaj + */ +public class Application implements IPlatformRunnable +{ + static Shell shell = null; + + /* + * The call to createAndRunWorkbench will not return until the workbench is closed. + * The SWT event loop and other low-level logistics are handled inside this method. + * @see org.eclipse.core.runtime.IPlatformRunnable#run(java.lang.Object) + */ + public Object run(Object args) throws Exception + { + Display display = PlatformUI.createDisplay(); + try + { + int returnCode = PlatformUI.createAndRunWorkbench(display, + new ApplicationWorkbenchAdvisor()); + if (returnCode == PlatformUI.RETURN_RESTART) + { + return IPlatformRunnable.EXIT_RESTART; + } + return IPlatformRunnable.EXIT_OK; + } finally + { + display.dispose(); + } + } + + static Shell getActiveShell() + { + return shell; + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationActionBarAdvisor.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationActionBarAdvisor.java new file mode 100644 index 0000000000..b5c1b5074a --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationActionBarAdvisor.java @@ -0,0 +1,96 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +import org.apache.qpid.management.ui.actions.VersionAction; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.GroupMarker; +import org.eclipse.jface.action.ICoolBarManager; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; + +/** + * An action bar advisor is responsible for creating, adding, and disposing of the + * actions added to a workbench window. Each window will be populated with + * new actions. + */ +public class ApplicationActionBarAdvisor extends ActionBarAdvisor +{ + + // Actions - important to allocate these only in makeActions, and then use them + // in the fill methods. This ensures that the actions aren't recreated + // when fillActionBars is called with FILL_PROXY. + private IWorkbenchAction exitAction; + private Action _aboutAction; + + public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) + { + super(configurer); + } + + protected void makeActions(final IWorkbenchWindow window) + { + // Creates the actions and registers them. + // Registering is needed to ensure that key bindings work. + // The corresponding commands keybindings are defined in the plugin.xml file. + // Registering also provides automatic disposal of the actions when + // the window is closed. + + exitAction = ActionFactory.QUIT.create(window); + register(exitAction); + + _aboutAction = new VersionAction(window); + register(_aboutAction); + } + + + protected void fillMenuBar(IMenuManager menuBar) + { + MenuManager fileMenu = new MenuManager("&Qpid Manager", "qpidmanager"); + MenuManager helpMenu = new MenuManager("&Help", IWorkbenchActionConstants.M_HELP); + + menuBar.add(fileMenu); + // Add a group marker indicating where action set menus will appear. + menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); + menuBar.add(helpMenu); + + fileMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); + fileMenu.add(new Separator()); + fileMenu.add(new GroupMarker("mbeanactions")); + fileMenu.add(new Separator()); + fileMenu.add(exitAction); + + // Help + helpMenu.add(_aboutAction); + } + + protected void fillCoolBar(ICoolBarManager coolBar) + { + + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java new file mode 100644 index 0000000000..f3b9943cbb --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java @@ -0,0 +1,136 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.eclipse.jface.resource.FontRegistry; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +/** + * Main Application Registry, which contains shared resources and map to all connected servers. + * @author Bhupendra Bhardwaj + */ +public abstract class ApplicationRegistry +{ + private static ImageRegistry imageRegistry = new ImageRegistry(); + private static FontRegistry fontRegistry = new FontRegistry(); + public static final boolean debug = Boolean.getBoolean("eclipse.consoleLog"); + public static final long timeout = Long.parseLong(System.getProperty("timeout", "5000")); + + static + { + imageRegistry.put(Constants.CONSOLE_IMAGE, + org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/qpidmc.gif")); + imageRegistry.put(Constants.CLOSED_FOLDER_IMAGE, + org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/icon_ClosedFolder.gif")); + imageRegistry.put(Constants.OPEN_FOLDER_IMAGE, + PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER)); + imageRegistry.put(Constants.MBEAN_IMAGE, + PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT)); + imageRegistry.put(Constants.NOTIFICATION_IMAGE, + org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/notifications.gif")); + } + + static + { + fontRegistry.put(Constants.FONT_BUTTON, new FontData[]{new FontData("Arial", 8, SWT.BOLD)} ); + fontRegistry.put(Constants.FONT_BOLD, new FontData[]{new FontData("Bold", 9, SWT.BOLD)} ); + fontRegistry.put(Constants.FONT_ITALIC, new FontData[]{new FontData("Italic", 9, SWT.ITALIC)} ); + fontRegistry.put(Constants.FONT_TABLE_CELL, new FontData[]{new FontData("Tablecell", 8, SWT.NORMAL)} ); + fontRegistry.put(Constants.FONT_NORMAL, new FontData[]{new FontData("Normal", 9, SWT.NORMAL)} ); + } + + /* + * This maps all the managed servers to the respective server registry. + * Server can be JMX MBeanServer or a C++ server + */ + private static HashMap<ManagedServer, ServerRegistry> _serverRegistryMap = new HashMap<ManagedServer, ServerRegistry>(); + + // This map gets updated when a server connection closes. + private static List<ManagedServer> _closedServerList = new CopyOnWriteArrayList<ManagedServer>(); + + public static Image getImage(String key) + { + return imageRegistry.get(key); + } + + public static Font getFont(String key) + { + return fontRegistry.get(key); + } + + public static void addServer(ManagedServer server, ServerRegistry registry) + { + _serverRegistryMap.put(server, registry); + } + + public static void removeServer(ManagedServer server) + { + _serverRegistryMap.remove(server); + } + + public static ServerRegistry getServerRegistry(ManagedServer server) + { + return _serverRegistryMap.get(server); + } + + public static ServerRegistry getServerRegistry(ManagedBean mbean) + { + ManagedServer server = mbean.getServer(); + return getServerRegistry(server); + } + + public static boolean isServerConnected(ManagedServer server) + { + return _serverRegistryMap.containsKey(server); + } + + // remove the server from the registry + public static void serverConnectionClosed(ManagedServer server) + { + _closedServerList.add(server); + removeServer(server); + } + + /* + * Returns the lis of closed servers. The Thread in GUI, which keeps checking for closed connection + * will check this and will remove the server links from the GUI. + */ + public static List<ManagedServer> getClosedServers() + { + if (_closedServerList.isEmpty()) + return null; + + List<ManagedServer> list = new CopyOnWriteArrayList<ManagedServer>(_closedServerList); + _closedServerList.clear(); + return list; + } + +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchAdvisor.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchAdvisor.java new file mode 100644 index 0000000000..a46fa870e4 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchAdvisor.java @@ -0,0 +1,46 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchAdvisor; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; + +/** + * This workbench advisor creates the window advisor, and specifies + * the perspective id for the initial window. + */ +public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor +{ + public static final String PERSPECTIVE_ID = "org.apache.qpid.management.ui.perspective"; + + public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) + { + return new ApplicationWorkbenchWindowAdvisor(configurer); + } + + + public String getInitialWindowPerspectiveId() + { + return PERSPECTIVE_ID; + } + +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java new file mode 100644 index 0000000000..e3aedef28e --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java @@ -0,0 +1,65 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; + +/** + * + * @author Bhupendra Bhardwaj + */ +public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor +{ + public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) + { + super(configurer); + } + + public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) + { + return new ApplicationActionBarAdvisor(configurer); + } + + public void preWindowOpen() + { + IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); + int x = Display.getDefault().getBounds().width; + int y = Display.getDefault().getBounds().height; + configurer.setInitialSize(new Point(9*x/10, 8*y/10)); + configurer.setShowCoolBar(true); + configurer.setShowStatusLine(false); + + configurer.setTitle(Constants.APPLICATION_NAME); + } + + public void postWindowCreate() + { + IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); + Shell shell = configurer.getWindow().getShell(); + shell.setImage(ApplicationRegistry.getImage(Constants.CONSOLE_IMAGE)); + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java new file mode 100644 index 0000000000..d6f895b64a --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java @@ -0,0 +1,140 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +/** + * Contains constants for the application + * @author Bhupendra Bhardwaj + * + */ +public class Constants +{ + public final static String APPLICATION_NAME = "Qpid Management Console"; + + public final static String ACTION_REMOVE_MBEANNODE = "Remove from list"; + public final static String VALUE = "value"; + public final static String TYPE = "type"; + public final static String NODE_TYPE_SERVER = "server"; + public final static String NODE_TYPE_DOMAIN = "domain"; + public final static String NODE_TYPE_MBEANTYPE = "mbeantype"; + // currently used only for virtual host instances, but will work as general also + public final static String NODE_TYPE_TYPEINSTANCE = "mbeantype_instance"; + public final static String MBEAN = "mbean"; + public final static String ATTRIBUTE = "Attribute"; + public final static String ATTRIBUTES = "Attributes"; + public final static String NOTIFICATIONS = "Notifications"; + public final static String RESULT = "Result"; + public final static String VIRTUAL_HOST = "VirtualHost"; + public final static String DEFAULT_VH = "Default"; + public final static String DEFAULT_USERNAME = "guest"; + public final static String DEFAULT_PASSWORD = "guest"; + + public final static String USERNAME = "Username"; + public final static String PASSWORD = "Password"; + + // Attributes and operations are used to customize the GUI for Qpid. If these are changes in the + // Qpid server, then these should be updated accordingly + public final static String ATTRIBUTE_QUEUE_OWNER = "owner"; + public final static String ATTRIBUTE_QUEUE_DEPTH = "QueueDepth"; + public final static String ATTRIBUTE_QUEUE_CONSUMERCOUNT = "ActiveConsumerCount"; + public final static String OPERATION_CREATE_QUEUE = "createNewQueue"; + public final static String OPERATION_CREATE_BINDING = "createNewBinding"; + public final static String OPERATION_MOVE_MESSAGES = "moveMessages"; + + public final static String OPERATION_CREATEUSER = "createUser"; + public final static String OPERATION_DELETEUSER = "deleteUser"; + public final static String OPERATION_VIEWUSERS = "viewUsers"; + public final static String OPERATION_PARAM_USERNAME = "username"; + + public final static String OPERATION_SUCCESSFUL = "Operation successful"; + public final static String OPERATION_UNSUCCESSFUL = "Operation unsuccessful"; + + public final static String ALL = "All"; + + public final static String NAVIGATION_ROOT = "Qpid Connections"; + public final static String DESCRIPTION = " Description"; + + public final static String ADMIN_MBEAN_TYPE = "UserManagement"; + public final static String QUEUE = "Queue"; + public final static String CONNECTION ="Connection"; + public final static String EXCHANGE = "Exchange"; + public final static String EXCHANGE_TYPE = "ExchangeType"; + public final static String[] EXCHANGE_TYPE_VALUES = {"direct", "fanout", "headers", "topic"}; + public final static String[] BOOLEAN_TYPE_VALUES = {"false", "true"}; + public final static String[] ATTRIBUTE_TABLE_TITLES = {"Attribute Name", "Value"}; + public static final String[] CONNECTION_PROTOCOLS ={"RMI"}; + public static final String DEFAULT_PROTOCOL = CONNECTION_PROTOCOLS[0]; + + public final static String ACTION_ADDSERVER = "New Connection"; + public final static String ACTION_RECONNECT = "Reconnect"; + public final static String ACTION_CLOSE = "Close Connection"; + public final static String ACTION_EDITATTRIBUTE = "Edit Attribute"; + public final static String ACTION_LOGIN = "Login"; + + public final static String QUEUE_SORT_BY_NAME = "Queue Name"; + public final static String QUEUE_SORT_BY_DEPTH = "Queue Depth"; + public final static String QUEUE_SORT_BY_CONSUMERCOUNT = "Consumer Count"; + public final static String QUEUE_SHOW_TEMP_QUEUES= "show temporary queues"; + + public final static String SUBSCRIBE_BUTTON = "Subscribe"; + public final static String UNSUBSCRIBE_BUTTON = "Unsubscribe"; + + public final static String CONSOLE_IMAGE = "ConsoelImage"; + public final static String CLOSED_FOLDER_IMAGE = "ClosedFolderImage"; + public final static String OPEN_FOLDER_IMAGE = "OpenFolderImage"; + public final static String MBEAN_IMAGE = "MBeanImage"; + public final static String NOTIFICATION_IMAGE = "NotificationImage"; + + public final static String FONT_BUTTON = "ButtonFont"; + public final static String FONT_BOLD = "BoldFont"; + public final static String FONT_ITALIC = "ItalicFont"; + public final static String FONT_TABLE_CELL = "TableCellFont"; + public final static String FONT_NORMAL = "Normal"; + + public final static String BUTTON_DETAILS = "Details"; + public final static String BUTTON_EDIT_ATTRIBUTE = "Edit Attribute"; + public final static String BUTTON_REFRESH = "Refresh"; + public final static String BUTTON_GRAPH = "Graph"; + public final static int TIMER_INTERVAL = 5000; + public final static String BUTTON_EXECUTE = "Execute"; + public final static String BUTTON_CLEAR = "Clear"; + public final static String BUTTON_CONNECT = "Connect"; + public final static String BUTTON_CANCEL = "Cancel"; + public final static String BUTTON_UPDATE = "Update"; + + + public final static int OPERATION_IMPACT_INFO = 0; + public final static int OPERATION_IMPACT_ACTION = 1; + public final static int OPERATION_IMPACT_ACTIONINFO = 2; + public final static int OPERATION_IMPACT_UNKNOWN = 3; + + public final static String ERROR_SERVER_CONNECTION = "Server Connection Failed"; + public final static String INFO_PROTOCOL = "Please select the protocol"; + public final static String INFO_HOST_ADDRESS = "Please enter the host address"; + public final static String INFO_HOST_PORT = "Please enter the port number"; + public final static String INFO_USERNAME = "Please enter the " + USERNAME; + public final static String INFO_PASSWORD = "Please enter the " + PASSWORD; + + public final static String MECH_CRAMMD5 = "CRAM-MD5"; + public final static String MECH_PLAIN = "PLAIN"; + public final static String SASL_CRAMMD5 = "SASL/CRAM-MD5"; + public final static String SASL_PLAIN = "SASL/PLAIN"; +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java new file mode 100644 index 0000000000..31825e925d --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java @@ -0,0 +1,132 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +import static org.apache.qpid.management.ui.Constants.*; +import java.util.HashMap; + +/** + * Class representing a managed bean on the managed server + * @author Bhupendra Bhardwaj + * + */ +public abstract class ManagedBean extends ManagedObject +{ + private String _uniqueName = ""; + private String _domain = ""; + private String _type = ""; + private String _virtualHostName = null; + private ManagedServer _server = null; + private HashMap _properties = null; + + public String getProperty(String key) + { + return (String)_properties.get(key); + } + + public HashMap getProperties() + { + return _properties; + } + public void setProperties(HashMap properties) + { + this._properties = properties; + setName(getProperty("name")); + setType(getProperty("type")); + _virtualHostName = getProperty(VIRTUAL_HOST); + } + public String getDomain() + { + return _domain; + } + public void setDomain(String domain) + { + this._domain = domain; + } + + public ManagedServer getServer() + { + return _server; + } + public void setServer(ManagedServer server) + { + this._server = server; + } + public String getType() + { + return _type; + } + public void setType(String type) + { + this._type = type; + } + public String getUniqueName() + { + return _uniqueName; + } + public void setUniqueName(String uniqueName) + { + this._uniqueName = uniqueName; + } + + public String getVirtualHostName() + { + // To make it work with the broker with no virtual host implementation + return _virtualHostName == null ? DEFAULT_VH : _virtualHostName; + } + + /** + * Returns mbean instance name. MBeans which have only one instance, the type attribute will be returned + * @return + */ + public String getInstanceName() + { + if (getName() != null) + return getName(); + else + return getType(); + } + + public boolean isQueue() + { + return _type.endsWith(QUEUE); + } + + public boolean isConnection() + { + return _type.endsWith(CONNECTION); + } + + public boolean isExchange() + { + return _type.endsWith(EXCHANGE); + } + + public boolean isTempQueue() + { + return (isQueue() && getName().startsWith("tmp_")); + } + + public boolean isAdmin() + { + return _type.endsWith(ADMIN_MBEAN_TYPE); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedObject.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedObject.java new file mode 100644 index 0000000000..96e0fa46c6 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedObject.java @@ -0,0 +1,40 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +/** + * Abstract class representing a managed object + * @author Bhupendra Bhardwaj + */ +public abstract class ManagedObject +{ + private String _name; + + public String getName() + { + return _name; + } + + public void setName(String name) + { + this._name = name; + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java new file mode 100644 index 0000000000..480fdb429a --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java @@ -0,0 +1,103 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +import static org.apache.qpid.management.ui.Constants.DEFAULT_PROTOCOL; +/** + * Class representing a server being managed eg. MBeanServer + * @author Bhupendra Bhardwaj + */ +public class ManagedServer extends ManagedObject +{ + private String _host; + private int _port; + private String _url; + private String _domain; + private String _user; + private String _password; + private String _protocol = DEFAULT_PROTOCOL; + + public ManagedServer(String host, int port, String domain) + { + this(host, port, domain, null, null); + } + + public ManagedServer(String host, int port, String domain, String user, String password) + { + setName(host + ":" + port); + _host = host; + _port = port; + _domain = domain; + _url = getRMIURL(host, port); + _user = user; + _password = password; + } + + public String getDomain() + { + return _domain; + } + + public String getHost() + { + return _host; + } + + public int getPort() + { + return _port; + } + + public String getUrl() + { + return _url; + } + + public String getProtocol() + { + return _protocol; + } + + public String getPassword() + { + return _password; + } + + public void setPassword(String password) + { + _password = password; + } + + public String getUser() + { + return _user; + } + + public void setUser(String user) + { + _user = user; + } + + private String getRMIURL(String host, int port) + { + return "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi"; + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java new file mode 100644 index 0000000000..f93200cadf --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java @@ -0,0 +1,46 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +import org.apache.qpid.management.ui.views.MBeanView; +import org.apache.qpid.management.ui.views.NavigationView; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** + * + * @author Bhupendra Bhardwaj + */ +public class Perspective implements IPerspectiveFactory +{ + public void createInitialLayout(IPageLayout layout) + { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(false); + + // standalone view meaning it can't be docked or stacked with other views, and it doesn't have a title bar. + layout.addStandaloneView(NavigationView.ID, true, IPageLayout.LEFT, 0.30f, editorArea); + layout.addStandaloneView(MBeanView.ID, true, IPageLayout.RIGHT, 0.70f, editorArea); + + layout.getViewLayout(NavigationView.ID).setCloseable(false); + layout.getViewLayout(MBeanView.ID).setCloseable(false); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java new file mode 100644 index 0000000000..313e143df5 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java @@ -0,0 +1,172 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.apache.qpid.management.ui.jmx.ClientListener; +import org.apache.qpid.management.ui.model.ManagedAttributeModel; +import org.apache.qpid.management.ui.model.NotificationObject; +import org.apache.qpid.management.ui.model.OperationDataModel; + +public abstract class ServerRegistry +{ + private ManagedServer _managedServer = null; + + // list of virtual hosts for this server + private List<String> _virtualHosts = new ArrayList<String>(); + // map of all Connection mbeans + private ConcurrentMap<String,List<ManagedBean>> _connections = new ConcurrentHashMap<String,List<ManagedBean>>(); + // map of all exchange mbeans + private ConcurrentMap<String,List<ManagedBean>> _exchanges = new ConcurrentHashMap<String,List<ManagedBean>>(); + // map of all queue mbenas + private ConcurrentMap<String,List<ManagedBean>> _queues = new ConcurrentHashMap<String,List<ManagedBean>>(); + + public ServerRegistry() + { + + } + + public ServerRegistry(ManagedServer server) + { + _managedServer = server; + } + + public ManagedServer getManagedServer() + { + return _managedServer; + } + + public void setManagedServer(ManagedServer server) + { + _managedServer = server; + } + + protected void addConnectionMBean(ManagedBean mbean) + { + String vHost = mbean.getVirtualHostName(); + _connections.putIfAbsent(vHost, new ArrayList<ManagedBean>()); + _connections.get(vHost).add(mbean); + } + + protected void addExchangeMBean(ManagedBean mbean) + { + String vHost = mbean.getVirtualHostName(); + _exchanges.putIfAbsent(vHost, new ArrayList<ManagedBean>()); + _exchanges.get(vHost).add(mbean); + } + + protected void addQueueMBean(ManagedBean mbean) + { + String vHost = mbean.getVirtualHostName(); + _queues.putIfAbsent(vHost, new ArrayList<ManagedBean>()); + _queues.get(vHost).add(mbean); + } + + protected void removeConnectionMBean(ManagedBean mbean) + { + _connections.get(mbean.getVirtualHostName()).remove(mbean); + } + + protected void removeExchangeMBean(ManagedBean mbean) + { + _exchanges.get(mbean.getVirtualHostName()).remove(mbean); + } + + protected void removeQueueMBean(ManagedBean mbean) + { + _queues.get(mbean.getVirtualHostName()).remove(mbean); + } + + public List<ManagedBean> getConnections(String virtualHost) + { + return _connections.get(virtualHost); + } + + public List<ManagedBean> getExchanges(String virtualHost) + { + return _exchanges.get(virtualHost); + } + + public List<ManagedBean> getQueues(String virtualHost) + { + return _queues.get(virtualHost); + } + + public void addVirtualHost(String name) + { + if (!_virtualHosts.contains(name)) + { + _virtualHosts.add(name); + } + } + + public List<String> getVirtualHosts() + { + return _virtualHosts; + } + + public abstract void setUserList(List<String> list); + + public abstract List<String> getUsernames(); + + public abstract void addManagedObject(ManagedBean key); + + public abstract List<ManagedBean> getMBeans(); + + public abstract void removeManagedObject(ManagedBean mbean); + + public abstract List<ManagedBean> getObjectsToBeRemoved(); + + public abstract ManagedAttributeModel getAttributeModel(ManagedBean mbean); + + public abstract Object getServerConnection(); + + public abstract void closeServerConnection() throws Exception; + + public abstract OperationDataModel getOperationModel(ManagedBean mbean); + + public abstract List<String> getQueueNames(String vistualHostName); + + public abstract String[] getExchangeNames(String vistualHostName); + + public abstract String[] getConnectionNames(String vistualHostName); + + public abstract List<NotificationObject> getNotifications(ManagedBean mbean); + + public abstract boolean hasSubscribedForNotifications(ManagedBean mbean, String name, String type); + + public abstract void clearNotifications(ManagedBean mbean, List<NotificationObject> list); + + public ClientListener getNotificationListener() + { + return null; + } + + public ClientListener getClientListener() + { + return null; + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AbstractAction.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AbstractAction.java new file mode 100644 index 0000000000..f74ab54cc3 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AbstractAction.java @@ -0,0 +1,146 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.actions; + +import static org.apache.qpid.management.ui.Constants.ERROR_SERVER_CONNECTION; + +import java.io.IOException; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor; +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.apache.qpid.management.ui.views.NavigationView; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +public class AbstractAction +{ + private NavigationView _navigationView; + + protected IWorkbenchWindow _window; + + public static final String RMI_SASL_ERROR = "non-JRMP server"; + public static final String SECURITY_FAILURE = "User authentication has failed"; + public static final String SERVER_UNAVAILABLE = "Qpid server is not running"; + public static final String INVALID_PERSPECTIVE = "Invalid Perspective"; + public static final String CHANGE_PERSPECTIVE = "Please use the Qpid Management Perspective"; + + /** + * We will cache window object in order to + * be able to provide parent shell for the message dialog. + * @see IWorkbenchWindowActionDelegate#init + */ + public void init(IWorkbenchWindow window) + { + this._window = window; + if (_window.getShell() != null) + { + _window.getShell().setImage(ApplicationRegistry.getImage(Constants.CONSOLE_IMAGE)); + } + } + + protected NavigationView getNavigationView() + { + if (_navigationView == null) + { + _navigationView = (NavigationView)_window.getActivePage().findView(NavigationView.ID); + } + + return _navigationView; + } + + + protected void handleException(Throwable ex, String title, String msg) + { + MBeanUtility.printStackTrace(ex); + NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID); + if (view == null) + { + IStatus status = new Status(IStatus.WARNING, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID, + IStatus.OK, CHANGE_PERSPECTIVE, null); + ErrorDialog.openError(_window.getShell(), "Warning", INVALID_PERSPECTIVE, status); + return; + } + if (msg == null) + { + if (ex instanceof IOException) + { + if ((ex.getMessage() != null) && (ex.getMessage().indexOf(RMI_SASL_ERROR) != -1)) + { + msg = SECURITY_FAILURE; + } + else + { + msg = SERVER_UNAVAILABLE; + } + } + else if (ex instanceof SecurityException) + { + msg = SECURITY_FAILURE; + } + else + { + msg = ex.getMessage(); + } + } + + if ((msg == null) && (ex.getCause() != null)) + { + msg = ex.getCause().getMessage(); + } + + if (msg == null) + { + msg = ERROR_SERVER_CONNECTION; + } + + if (title == null) + { + title = ERROR_SERVER_CONNECTION; + } + IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID, + IStatus.OK, msg, null); + ErrorDialog.openError(_window.getShell(), "Error", title, status); + } + + + /** + * Selection in the workbench has been changed. We can change the state of the 'real' action here + * if we want, but this can only happen after the delegate has been created. + * @see IWorkbenchWindowActionDelegate#selectionChanged + */ + public void selectionChanged(IAction action, ISelection selection) { + } + + /** + * We can use this method to dispose of any system resources we previously allocated. + * @see IWorkbenchWindowActionDelegate#dispose + */ + public void dispose() { + + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java new file mode 100644 index 0000000000..ce7d8816ba --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java @@ -0,0 +1,326 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.actions; + +import static org.apache.qpid.management.ui.Constants.*; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.exceptions.InfoRequiredException; +import org.apache.qpid.management.ui.views.NumberVerifyListener; +import org.apache.qpid.management.ui.views.ViewUtility; +import org.eclipse.jface.action.IAction; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +public class AddServer extends AbstractAction implements IWorkbenchWindowActionDelegate +{ + private static final String[] _domains ={"org.apache.qpid"}; + + private String _transport = DEFAULT_PROTOCOL; + private String _host; + private String _port; + private String _domain; + private String _user; + private String _password; + + private boolean _addServer; + + public AddServer() + { + + } + + public void run(IAction action) + { + if(_window == null) + return; + + reset(); + createAddServerPopup(); + try + { + if (_addServer) + { + getNavigationView().addNewServer(_transport, _host, Integer.parseInt(_port), _domain, _user, _password); + } + } + catch(InfoRequiredException ex) + { + ViewUtility.popupInfoMessage(ACTION_ADDSERVER, ex.getMessage()); + } + catch (Exception ex) + { + handleException(ex, null, null); + } + } + + private void reset() + { + _addServer = false; + _host = null; + _port = null; + _domain = null; + _user = null; + _password = null; + } + + /** + * Creates the shell and then opens the popup where user can enter new connection details. + * Connects to the new server and adds the server in the navigation page. + * Pops up any error occured in connecting to the new server + */ + private void createAddServerPopup() + { + Display display = Display.getCurrent(); + final Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE); + shell.setText(ACTION_ADDSERVER); + shell.setImage(ApplicationRegistry.getImage(CONSOLE_IMAGE)); + shell.setLayout(new GridLayout()); + + createWidgets(shell); + shell.pack(); + + //get current size dialog, and screen size + int displayWidth = display.getBounds().width; + int displayHeight = display.getBounds().height; + int currentShellWidth = shell.getSize().x; + int currentShellHeight = shell.getSize().y; + + //default sizes for the dialog + int minShellWidth = 425; + int minShellHeight= 290; + //ensure this is large enough, increase it if its not + int newShellWidth = currentShellWidth > minShellWidth ? currentShellWidth : minShellWidth; + int newShellHeight = currentShellHeight > minShellHeight ? currentShellHeight : minShellHeight; + + //set the final size and centre the dialog + shell.setBounds((displayWidth - newShellWidth)/2 , (displayHeight - newShellHeight)/2, newShellWidth, newShellHeight); + + shell.open(); + _window.getShell().setEnabled(false); + + while (!shell.isDisposed()) + { + if (!display.readAndDispatch()) + { + display.sleep(); + } + } + + // enable the main shell + _window.getShell().setEnabled(true); + _window.getShell().open(); + } + + // Creates SWT widgets for the user to add server connection details. + // Adds listeners to the widgets to take appropriate action + private void createWidgets(final Shell shell) + { + Composite composite = new Composite(shell, SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout layout = new GridLayout(2, false); + layout.horizontalSpacing = 10; + layout.verticalSpacing = 10; + layout.marginHeight = 20; + layout.marginWidth = 20; + composite.setLayout(layout); + + /* Commenting this, as there is only one protocol at the moment. + * This can be uncommented and enhanced, if more protocols are added in future + Label name = new Label(composite, SWT.NONE); + name.setText("Connection Type"); + GridData layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false); + name.setLayoutData(layoutData); + + final Combo comboTransport = new Combo(composite, SWT.READ_ONLY); + comboTransport.setItems(CONNECTION_PROTOCOLS); + comboTransport.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + comboTransport.select(0); + */ + + Label host = new Label(composite, SWT.NONE); + host.setText("Host"); + host.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + + final Text textHost = new Text(composite, SWT.BORDER); + textHost.setText(""); + textHost.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + textHost.setFocus(); + + Label port = new Label(composite, SWT.NONE); + port.setText("Port"); + port.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + + final Text textPort = new Text(composite, SWT.BORDER); + textPort.setText(""); + textPort.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + // Verify if the value entered is numeric + textPort.addVerifyListener(new NumberVerifyListener()); + + + Label domain = new Label(composite, SWT.NONE); + domain.setText("Domain"); + domain.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + + final Combo comboDomain = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY); + comboDomain.setItems(_domains); + comboDomain.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + comboDomain.select(0); + + + Label user = new Label(composite, SWT.NONE); + user.setText(USERNAME); + user.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + + final Text textUser = new Text(composite, SWT.BORDER); + textUser.setText(""); + textUser.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + + Label password = new Label(composite, SWT.NONE); + password.setText(PASSWORD); + password.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + + final Text textPwd = new Text(composite, SWT.BORDER | SWT.SINGLE | SWT.PASSWORD); + textPwd.setText(""); + //textPwd.setEchoChar('*'); + textPwd.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + + //Get the text widgets + Control[] widgets = composite.getChildren(); + for (int i=0; i < widgets.length; i++) + { + widgets[i].addKeyListener(new KeyAdapter() + { + public void keyPressed(KeyEvent event) + { + if (event.character == SWT.ESC) + { + //Escape key acts as cancel on all widgets + shell.close(); + } + } + }); + } + + Composite buttonsComposite = new Composite(composite, SWT.NONE); + buttonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); + buttonsComposite.setLayout(new GridLayout(2, true)); + + final Button connectButton = new Button(buttonsComposite, SWT.PUSH | SWT.CENTER); + connectButton.setText(BUTTON_CONNECT); + GridData gridData = new GridData (SWT.TRAIL, SWT.BOTTOM, true, true); + gridData.widthHint = 100; + connectButton.setLayoutData(gridData); + connectButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); + connectButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent event) + { + _host = textHost.getText(); + if ((_host == null) || (_host.trim().length() == 0)) + { + ViewUtility.popupInfoMessage(ACTION_ADDSERVER, INFO_HOST_ADDRESS); + textHost.setText(""); + textHost.setFocus(); + return; + } + + _port = textPort.getText(); + if ((_port == null) || (_port.trim().length() == 0)) + { + ViewUtility.popupInfoMessage(ACTION_ADDSERVER, INFO_HOST_PORT); + textPort.setText(""); + textPort.setFocus(); + return; + } + + _user = textUser.getText(); + if ((_user == null) || (_user.trim().length() == 0)) + { + ViewUtility.popupInfoMessage(ACTION_ADDSERVER, INFO_USERNAME); + textUser.setText(""); + textUser.setFocus(); + return; + } + + _password = textPwd.getText(); + if (_password == null) + { + ViewUtility.popupInfoMessage(ACTION_ADDSERVER, INFO_PASSWORD); + textPwd.setText(""); + textPwd.setFocus(); + return; + } + + _domain = comboDomain.getText(); + _addServer = true; + shell.dispose(); + } + }); + + final Button cancelButton = new Button(buttonsComposite, SWT.PUSH); + cancelButton.setText(BUTTON_CANCEL); + gridData = new GridData (SWT.LEAD, SWT.BOTTOM, true, true); + gridData.widthHint = 100; + cancelButton.setLayoutData(gridData); + cancelButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); + cancelButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent event) + { + shell.dispose(); + } + }); + + //Get the ok/cancel button widgets and add a new key listener + widgets = buttonsComposite.getChildren(); + for (int i=0; i < widgets.length; i++) + { + widgets[i].addKeyListener(new KeyAdapter() + { + public void keyPressed(KeyEvent event) + { + if (event.character == SWT.ESC) + { + //Escape key acts as cancel on all widgets + shell.close(); + } + } + }); + } + + shell.setDefaultButton(connectButton); + } + +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/CloseConnection.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/CloseConnection.java new file mode 100644 index 0000000000..a3e52149df --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/CloseConnection.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.ui.actions; + +import static org.apache.qpid.management.ui.Constants.ACTION_CLOSE; +import org.apache.qpid.management.ui.exceptions.InfoRequiredException; +import org.apache.qpid.management.ui.views.NavigationView; +import org.apache.qpid.management.ui.views.ViewUtility; +import org.eclipse.jface.action.IAction; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +public class CloseConnection extends AbstractAction implements IWorkbenchWindowActionDelegate +{ + public CloseConnection() + { + + } + + public void run(IAction action) + { + if(_window != null) + { + NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID); + try + { + view.disconnect(); + } + catch(InfoRequiredException ex) + { + ViewUtility.popupInfoMessage(ACTION_CLOSE, ex.getMessage()); + } + catch(Exception ex) + { + handleException(ex, null, null); + } + } + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/EditAttribute.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/EditAttribute.java new file mode 100644 index 0000000000..d3af3661b0 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/EditAttribute.java @@ -0,0 +1,51 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.actions; + +import static org.apache.qpid.management.ui.Constants.ACTION_EDITATTRIBUTE; +import org.apache.qpid.management.ui.exceptions.InfoRequiredException; +import org.apache.qpid.management.ui.views.MBeanView; +import org.apache.qpid.management.ui.views.ViewUtility; +import org.eclipse.jface.action.IAction; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +public class EditAttribute extends AbstractAction implements IWorkbenchWindowActionDelegate +{ + public void run(IAction action) + { + if(_window != null) + { + MBeanView view = (MBeanView)_window.getActivePage().findView(MBeanView.ID); + try + { + view.editAttribute(); + } + catch(InfoRequiredException ex) + { + ViewUtility.popupInfoMessage(ACTION_EDITATTRIBUTE, ex.getMessage()); + } + catch(Exception ex) + { + handleException(ex, "Attribute could not be edited", null); + } + } + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java new file mode 100644 index 0000000000..ce9d80d49b --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java @@ -0,0 +1,260 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.actions; + +import static org.apache.qpid.management.ui.Constants.ACTION_LOGIN; +import static org.apache.qpid.management.ui.Constants.CONSOLE_IMAGE; +import static org.apache.qpid.management.ui.Constants.INFO_PASSWORD; +import static org.apache.qpid.management.ui.Constants.INFO_USERNAME; +import static org.apache.qpid.management.ui.Constants.PASSWORD; +import static org.apache.qpid.management.ui.Constants.USERNAME; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.exceptions.InfoRequiredException; +import org.apache.qpid.management.ui.views.TreeObject; +import org.apache.qpid.management.ui.views.ViewUtility; +import org.eclipse.jface.action.IAction; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +public class ReconnectServer extends AbstractAction implements IWorkbenchWindowActionDelegate +{ + private String _title; + private String _serverName; + private String _user; + private String _password; + private boolean _connect; + + public void run(IAction action) + { + if(_window == null) + return; + + try + { + reset(); + // Check if a server node is selected to be reconnected. + TreeObject serverNode = getNavigationView().getSelectedServerNode(); + _serverName = serverNode.getName(); + _title = ACTION_LOGIN + " (" + _serverName + ")"; + + // Get the login details(username/password) + createLoginPopup(); + + if (_connect) + { + // Connect the server + getNavigationView().reconnect(_user, _password); + } + } + catch(InfoRequiredException ex) + { + ViewUtility.popupInfoMessage("Reconnect Qpid server", ex.getMessage()); + } + catch (Exception ex) + { + handleException(ex, null, null); + } + } + + private void reset() + { + _connect = false; + _user = null; + _password = null; + } + + // Create the login popup fot th user to enter usernaem and password + private void createLoginPopup() + { + Display display = Display.getCurrent(); + final Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE); + shell.setText(_title); + shell.setImage(ApplicationRegistry.getImage(CONSOLE_IMAGE)); + shell.setLayout(new GridLayout()); + + createWidgets(shell); + shell.pack(); + + //get current size dialog, and screen size + int displayWidth = display.getBounds().width; + int displayHeight = display.getBounds().height; + int currentShellWidth = shell.getSize().x; + int currentShellHeight = shell.getSize().y; + + //default sizes for the dialog + int minShellWidth = 350; + int minShellHeight= 200; + //ensure this is large enough, increase it if its not + int newShellWidth = currentShellWidth > minShellWidth ? currentShellWidth : minShellWidth; + int newShellHeight = currentShellHeight > minShellHeight ? currentShellHeight : minShellHeight; + + //set the final size and centre the dialog + shell.setBounds((displayWidth - newShellWidth)/2 , (displayHeight - newShellHeight)/2, newShellWidth, newShellHeight); + + shell.open(); + _window.getShell().setEnabled(false); + + while (!shell.isDisposed()) + { + if (!display.readAndDispatch()) + { + display.sleep(); + } + } + + // enable the main shell + _window.getShell().setEnabled(true); + _window.getShell().open(); + } + + // Creates the SWT widgets in the popup shell, to enter username and password. + // Adds listeners to the widgets to take appropriate action + private void createWidgets(final Shell shell) + { + Composite composite = new Composite(shell, SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout layout = new GridLayout(2, false); + layout.horizontalSpacing = 10; + layout.verticalSpacing = 10; + layout.marginHeight = 20; + layout.marginWidth = 20; + composite.setLayout(layout); + + Label user = new Label(composite, SWT.NONE); + user.setText(USERNAME); + user.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + + final Text textUser = new Text(composite, SWT.BORDER); + textUser.setText(""); + textUser.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + // Put cursor on this field + textUser.setFocus(); + + Label password = new Label(composite, SWT.NONE); + password.setText(PASSWORD); + password.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + + final Text textPwd = new Text(composite, SWT.BORDER | SWT.SINGLE | SWT.PASSWORD); + textPwd.setText(""); + textPwd.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + + //Get the text widgets + Control[] widgets = composite.getChildren(); + for (int i=0; i < widgets.length; i++) + { + widgets[i].addKeyListener(new KeyAdapter() + { + public void keyPressed(KeyEvent event) + { + if (event.character == SWT.ESC) + { + //Escape key acts as cancel on all widgets + shell.close(); + } + } + }); + } + + Composite buttonsComposite = new Composite(composite, SWT.NONE); + buttonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); + buttonsComposite.setLayout(new GridLayout(2, true)); + + final Button connectButton = new Button(buttonsComposite, SWT.PUSH | SWT.CENTER); + connectButton.setText(Constants.BUTTON_CONNECT); + GridData gridData = new GridData (SWT.TRAIL, SWT.BOTTOM, true, true); + gridData.widthHint = 100; + connectButton.setLayoutData(gridData); + connectButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); + connectButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent event) + { + _user = textUser.getText(); + if ((_user == null) || (_user.trim().length() == 0)) + { + ViewUtility.popupInfoMessage(_title, INFO_USERNAME); + textUser.setText(""); + textUser.setFocus(); + return; + } + + _password = textPwd.getText(); + if (_password == null) + { + ViewUtility.popupInfoMessage(_title, INFO_PASSWORD); + textPwd.setText(""); + textPwd.setFocus(); + return; + } + + _connect = true; + shell.dispose(); + } + }); + + final Button cancelButton = new Button(buttonsComposite, SWT.PUSH); + cancelButton.setText(Constants.BUTTON_CANCEL); + gridData = new GridData (SWT.LEAD, SWT.BOTTOM, true, true); + gridData.widthHint = 100; + cancelButton.setLayoutData(gridData); + cancelButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); + cancelButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent event) + { + shell.dispose(); + } + }); + + //Get the ok/cancel button widgets and add a new key listener + widgets = buttonsComposite.getChildren(); + for (int i=0; i < widgets.length; i++) + { + widgets[i].addKeyListener(new KeyAdapter() + { + public void keyPressed(KeyEvent event) + { + if (event.character == SWT.ESC) + { + //Escape key acts as cancel on all widgets + shell.close(); + } + } + }); + } + + shell.setDefaultButton(connectButton); + } + +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java new file mode 100644 index 0000000000..34251c12d7 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java @@ -0,0 +1,53 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.actions; + +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.apache.qpid.management.ui.views.MBeanView; +import org.apache.qpid.management.ui.views.NavigationView; +import org.eclipse.jface.action.IAction; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +/** + * This action refreshes both the views -Navigation and MBeanView + * @author Bhupendra Bhardwaj + */ +public class Refresh extends AbstractAction implements IWorkbenchWindowActionDelegate +{ + public void run(IAction action) + { + if(_window != null) + { + NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID); + view.refresh(); + + MBeanView mbeanview = (MBeanView)_window.getActivePage().findView(MBeanView.ID); + try + { + mbeanview.refreshMBeanView(); + } + catch (Exception ex) + { + MBeanUtility.handleException(ex); + } + } + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/RemoveServer.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/RemoveServer.java new file mode 100644 index 0000000000..e329255414 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/RemoveServer.java @@ -0,0 +1,50 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.actions; + +import org.apache.qpid.management.ui.exceptions.InfoRequiredException; +import org.apache.qpid.management.ui.views.NavigationView; +import org.apache.qpid.management.ui.views.ViewUtility; +import org.eclipse.jface.action.IAction; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +public class RemoveServer extends AbstractAction implements IWorkbenchWindowActionDelegate +{ + public void run(IAction action) + { + if(_window != null) + { + NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID); + try + { + view.removeServer(); + } + catch(InfoRequiredException ex) + { + ViewUtility.popupInfoMessage("Remove Qpid server", ex.getMessage()); + } + catch(Exception ex) + { + handleException(ex, "Server could not be removed", null); + } + } + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/VersionAction.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/VersionAction.java new file mode 100644 index 0000000000..be69fadbe8 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/VersionAction.java @@ -0,0 +1,94 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.actions; + +import java.io.InputStream; +import java.util.Properties; + +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.ui.IWorkbenchWindow; + +public class VersionAction extends Action +{ + private IWorkbenchWindow _window; + public static final String VERSION_RESOURCE = "qpidversion.properties"; + + public static final String PRODUCT_NAME_PROPERTY = "qpid.name"; + public static final String RELEASE_VERSION_PROPERTY = "qpid.version"; + public static final String BUILD_VERSION_PROPERTY = "qpid.svnversion"; + + private static final String DEFAULT = "unknown"; + private static String _releaseVersion; + private static String _buildVersion; + private static String _text; + + static + { + Properties props = new Properties(); + try + { + InputStream propertyStream = VersionAction.class.getClassLoader().getResourceAsStream(VERSION_RESOURCE); + if (propertyStream != null) + { + props.load(propertyStream); + _releaseVersion = readPropertyValue(props, RELEASE_VERSION_PROPERTY); + _buildVersion = readPropertyValue(props, BUILD_VERSION_PROPERTY); + _text = "Build Version : " + _buildVersion + "\n" + + "Release Version : " + _releaseVersion; + } + else + { + _text = "Build Version : \n" + + "Release Version : "; + } + } + catch (Exception ex) + { + MBeanUtility.printStackTrace(ex); + } + } + + public VersionAction(IWorkbenchWindow window) + { + _window = window; + setText("About " + Constants.APPLICATION_NAME); + setId("qpidmc.about"); + setActionDefinitionId("qpidmc.about"); + } + + private static String readPropertyValue(Properties props, String propertyName) + { + String retVal = (String) props.get(propertyName); + if (retVal == null) + { + retVal = DEFAULT; + } + return retVal; + } + + public void run() + { + MessageDialog.openInformation(_window.getShell(), Constants.APPLICATION_NAME, _text); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/exceptions/InfoRequiredException.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/exceptions/InfoRequiredException.java new file mode 100644 index 0000000000..672426a59d --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/exceptions/InfoRequiredException.java @@ -0,0 +1,36 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.exceptions; + +public class InfoRequiredException extends Exception +{ + private static final long serialVersionUID = 1L; + + public InfoRequiredException(String message) + { + super(message); + } + + public InfoRequiredException(String msg, Throwable t) + { + super(msg, t); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/exceptions/ManagementConsoleException.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/exceptions/ManagementConsoleException.java new file mode 100644 index 0000000000..17c127c01a --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/exceptions/ManagementConsoleException.java @@ -0,0 +1,31 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.management.ui.exceptions; + +@SuppressWarnings("serial") +public class ManagementConsoleException extends Exception +{ + public ManagementConsoleException(String message) + { + super(message); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java new file mode 100644 index 0000000000..2be0ddbebf --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.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.ui.jmx; + +import javax.management.MBeanServerNotification; +import javax.management.Notification; +import javax.management.NotificationListener; +import javax.management.ObjectName; +import javax.management.remote.JMXConnectionNotification; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ManagedServer; + + +public class ClientListener implements NotificationListener +{ + protected ManagedServer server = null; + protected JMXServerRegistry serverRegistry = null; + + public ClientListener(ManagedServer server) + { + this.server = server; + serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + } + + public void handleNotification(Notification notification, Object handback) + { + ObjectName objName = null; + String type = notification.getType(); + MBeanUtility.printOutput(type + ":" + objName); + + if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(type)) + { + objName = ((MBeanServerNotification)notification).getMBeanName(); + getServerRegistry().registerManagedObject(objName); + } + else if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(type)) + { + objName = ((MBeanServerNotification)notification).getMBeanName(); + getServerRegistry().unregisterManagedObject(objName); + } + else if (JMXConnectionNotification.FAILED.equals(type)) + { + ApplicationRegistry.serverConnectionClosed(server); + } + } + + protected JMXServerRegistry getServerRegistry() + { + if (serverRegistry == null) + serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + + return serverRegistry; + } + public ManagedServer getServer() + { + return server; + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java new file mode 100644 index 0000000000..c6ecda4b4c --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.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.ui.jmx; + +import javax.management.Notification; +import javax.management.ObjectName; + +import org.apache.qpid.management.ui.ManagedServer; + +public class ClientNotificationListener extends ClientListener +{ + public ClientNotificationListener(ManagedServer server) + { + super(server); + } + + public void handleNotification(Notification notification, Object handback) + { + ObjectName objName = (ObjectName)notification.getSource(); + //String type = notification.getType(); + getServerRegistry().addNotification(objName, notification); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java new file mode 100644 index 0000000000..3561e16098 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java @@ -0,0 +1,48 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.jmx; + +import java.util.HashMap; + +import javax.management.ObjectName; + +import org.apache.qpid.management.ui.ManagedBean; + + +public class JMXManagedObject extends ManagedBean +{ + private ObjectName _objName; + + @SuppressWarnings("unchecked") + public JMXManagedObject(ObjectName objName) + { + super(); + this._objName = objName; + setUniqueName(_objName.toString()); + setDomain(_objName.getDomain()); + super.setProperties(new HashMap(_objName.getKeyPropertyList())); + } + + public ObjectName getObjectName() + { + return _objName; + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java new file mode 100644 index 0000000000..b27661e56c --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java @@ -0,0 +1,714 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.jmx; + +import static org.apache.qpid.management.ui.Constants.*; + +import java.io.IOException; +import java.security.Security; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; + +import javax.management.ListenerNotFoundException; +import javax.management.MBeanInfo; +import javax.management.MBeanServerConnection; +import javax.management.Notification; +import javax.management.ObjectName; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; +import javax.security.auth.callback.CallbackHandler; +import javax.security.sasl.SaslClientFactory; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ManagedServer; +import org.apache.qpid.management.ui.ServerRegistry; +import org.apache.qpid.management.ui.model.ManagedAttributeModel; +import org.apache.qpid.management.ui.model.NotificationInfoModel; +import org.apache.qpid.management.ui.model.NotificationObject; +import org.apache.qpid.management.ui.model.OperationDataModel; +import org.apache.qpid.management.ui.sasl.JCAProvider; +import org.apache.qpid.management.ui.sasl.SaslProvider; +import org.apache.qpid.management.ui.sasl.UserPasswordCallbackHandler; +import org.apache.qpid.management.ui.sasl.UsernameHashedPasswordCallbackHandler; + + +public class JMXServerRegistry extends ServerRegistry +{ + private boolean _connected = false; + private ObjectName _serverObjectName = null; + private Map<String, Object> _env = null; + private JMXServiceURL _jmxUrl = null; + private JMXConnector _jmxc = null; + private MBeanServerConnection _mbsc = null; + private Exception _connectionException = null; + private String _securityMechanism = null; + + private List<String> _usersList; + // When an mbean gets removed from mbean server, then the notification listener + // will add that mbean in this list. + private List<ManagedBean> _mbeansToBeRemoved = new ArrayList<ManagedBean>(); + + // Map containing all managed beans and mapped with unique mbean name + private HashMap<String, ManagedBean> _mbeansMap = new HashMap<String, ManagedBean>(); + // Map containing MBeanInfo for all mbeans and mapped with unique mbean name + private HashMap<String, MBeanInfo> _mbeanInfoMap = new HashMap<String, MBeanInfo>(); + // Map containing attribute model for all mbeans and mapped with unique mbean name + private HashMap<String, ManagedAttributeModel> _attributeModelMap = new HashMap<String, ManagedAttributeModel>(); + // Map containing operation model for all mbeans and mapped with unique mbean name + private HashMap<String, OperationDataModel> _operationModelMap = new HashMap<String, OperationDataModel>(); + // Map containing NotificationInfo for all mbeans and mapped with unique mbean name + private HashMap<String, List<NotificationInfoModel>> _notificationInfoMap = new HashMap<String, List<NotificationInfoModel>>(); + // Map containing all notifications sent for all mbeans, which are registered for notification + private HashMap<String, List<NotificationObject>> _notificationsMap = new HashMap<String, List<NotificationObject>>(); + // For mbeans which have subscribed for a notification type + // mbean unique name mapped with notification map. Notification map contains list of notification type + // mapped with notification name. Notification type list contains those notification types, + // which are subscribed for notification. + private HashMap<String, HashMap<String, List<String>>> _subscribedNotificationMap = new HashMap<String, HashMap<String, List<String>>>(); + + // listener for registration or unregistratioj of mbeans on mbean server + private ClientNotificationListener _notificationListener = null; + // listener for server connection. Receives notification if server connection goes down + private ClientListener _clientListener = null; + + public JMXServerRegistry(ManagedServer server) throws Exception + { + super(server); + + long timeNow; + + //auto-negotiate an RMI or JMXMP (SASL/CRAM-MD5 or SASL/PLAIN) JMX connection to broker + try + { + timeNow = System.currentTimeMillis(); + createJMXconnector("RMI"); + } + catch (IOException rmiIOE) + { + // check if the ioe was raised because we tried connecting to a non RMI-JRMP based JMX server + boolean jrmpServer = !rmiIOE.getMessage().contains("non-JRMP server at remote endpoint"); + + if (jrmpServer) + { + IOException nioe = new IOException(); + nioe.initCause(rmiIOE); + throw nioe; + } + else + { + try + { + //It wasnt an RMI ConnectorServer at the broker end. Try to establish a JMXMP SASL/CRAM-MD5 connection instead. + timeNow = System.currentTimeMillis(); + createJMXconnector("JMXMP_CRAM-MD5"); + } + catch (IOException cramIOE) + { + // check if the IOE was raised because we tried connecting to a SASL/PLAIN server using SASL/CRAM-MD5 + boolean plainProfileServer = cramIOE.getMessage().contains("The server supported profiles [SASL/PLAIN]" + + " do not match the client required profiles [SASL/CRAM-MD5]"); + + if (!plainProfileServer) + { + IOException nioe = new IOException(); + nioe.initCause(cramIOE); + throw nioe; + } + else + { + try + { + // Try to establish a JMXMP SASL/PLAIN connection instead. + timeNow = System.currentTimeMillis(); + createJMXconnector("JMXMP_PLAIN"); + } + catch (IOException plainIOE) + { + /* Out of options now. Check that the IOE was raised because we tried connecting to a server + * which didnt support SASL/PLAIN. If so, signal an unknown profile type. If not, raise the exception. */ + boolean unknownProfile = cramIOE.getMessage().contains("do not match the client required profiles [SASL/PLAIN]"); + + if (unknownProfile) + { + throw new Exception("Unknown JMXMP authentication mechanism, unable to connect."); + } + else + { + IOException nioe = new IOException(); + nioe.initCause(plainIOE); + throw nioe; + } + } + } + } + } + } + + if (_connected) + { + _mbsc = _jmxc.getMBeanServerConnection(); + + _clientListener = new ClientListener(server); + _notificationListener = new ClientNotificationListener(server); + + _jmxc.addConnectionNotificationListener(_clientListener, null, null); + _serverObjectName = new ObjectName("JMImplementation:type=MBeanServerDelegate"); + _mbsc.addNotificationListener(_serverObjectName, _clientListener, null, null); + } + else + { + if (System.currentTimeMillis() - timeNow >= ApplicationRegistry.timeout) + throw new Exception("Qpid server connection timed out"); + else + throw new Exception("Qpid server connection failed"); + } + } + + public MBeanServerConnection getServerConnection() + { + return _mbsc; + } + + private void createJMXconnector(String connectionType) throws IOException, Exception + { + if (connectionType == "RMI") + { + _securityMechanism = MECH_PLAIN; + + _jmxUrl = new JMXServiceURL(getManagedServer().getUrl()); + _env = null; + } + else if (connectionType.contains("JMXMP")) + { + // Check that the JMXMPConnector is available to provide SASL support + final String jmxmpcClass = "javax.management.remote.jmxmp.JMXMPConnector"; + + try + { + Class.forName(jmxmpcClass, false, this.getClass().getClassLoader()); + } + catch (ClassNotFoundException cnfe) + { + throw new Exception("JMXMPConnector class not found, unable to connect to specified server.\n\n" + + "Please add the jmxremote_optional.jar to the jmxremote.sasl plugin folder, or the classpath."); + } + + _jmxUrl = new JMXServiceURL("jmxmp", getManagedServer().getHost(), getManagedServer().getPort()); + _env = new HashMap<String, Object>(); + + /* set the package in which to find the JMXMP ClientProvider.class file loaded by the + * jmxremote.sasl plugin (from the jmxremote_optional.jar) */ + _env.put("jmx.remote.protocol.provider.pkgs", "com.sun.jmx.remote.protocol"); + + if (connectionType == "JMXMP_CRAM-MD5") + { + _securityMechanism = MECH_CRAMMD5; + + Map<String, Class<? extends SaslClientFactory>> map = new HashMap<String, Class<? extends SaslClientFactory>>(); + Class<?> clazz = Class.forName("org.apache.qpid.management.ui.sasl.CRAMMD5HashedSaslClientFactory"); + map.put("CRAM-MD5-HASHED", (Class<? extends SaslClientFactory>) clazz); + Security.addProvider(new JCAProvider(map)); + + CallbackHandler handler = new UsernameHashedPasswordCallbackHandler( + getManagedServer().getUser(), + getManagedServer().getPassword()); + _env.put("jmx.remote.profiles", SASL_CRAMMD5); + _env.put("jmx.remote.sasl.callback.handler", handler); + } + else if (connectionType == "JMXMP_PLAIN") + { + _securityMechanism = MECH_PLAIN; + + Security.addProvider(new SaslProvider()); + CallbackHandler handler = new UserPasswordCallbackHandler(getManagedServer().getUser(), getManagedServer().getPassword()); + _env.put("jmx.remote.profiles", SASL_PLAIN); + _env.put("jmx.remote.sasl.callback.handler", handler); + } + else + { + throw new Exception("Unknown authentication mechanism"); + } + } + else + { + throw new Exception("Unknown connection type"); + } + + Thread connectorThread = new Thread(new ConnectorThread()); + connectorThread.start(); + connectorThread.join(ApplicationRegistry.timeout); + + if (_connectionException != null) + { + throw _connectionException; + } + } + + public String getSecurityMechanism() + { + return _securityMechanism; + } + + private class ConnectorThread implements Runnable + { + public void run() + { + try + { + _connected = false; + _connectionException = null; + + _jmxc = JMXConnectorFactory.connect(_jmxUrl, _env); + + _connected = true; + } + catch (Exception ex) + { + _connectionException = ex; + } + } + } + + /** + * removes all listeners from the mbean server. This is required when user + * disconnects the Qpid server connection + */ + public void closeServerConnection() throws Exception + { + try + { + if (_jmxc != null && _clientListener != null) + _jmxc.removeConnectionNotificationListener(_clientListener); + + if (_mbsc != null && _clientListener != null) + _mbsc.removeNotificationListener(_serverObjectName, _clientListener); + + // remove mbean notification listeners + for (String mbeanName : _subscribedNotificationMap.keySet()) + { + _mbsc.removeNotificationListener(new ObjectName(mbeanName), _notificationListener); + } + } + catch (ListenerNotFoundException ex) + { + MBeanUtility.printOutput(ex.toString()); + } + } + + public ManagedBean getManagedObject(String uniqueName) + { + return _mbeansMap.get(uniqueName); + } + + public void addManagedObject(ManagedBean mbean) + { + if (mbean.isQueue()) + { + addQueueMBean(mbean); + } + else if (mbean.isExchange()) + { + addExchangeMBean(mbean); + } + else if (mbean.isConnection()) + { + addConnectionMBean(mbean); + } + + addVirtualHost(mbean.getVirtualHostName()); + _mbeansMap.put(mbean.getUniqueName(), mbean); + } + + public void removeManagedObject(ManagedBean mbean) + { + MBeanUtility.printOutput("Removing MBean:" + mbean.getUniqueName()); + + if (mbean.isQueue()) + { + removeQueueMBean(mbean); + } + else if (mbean.isExchange()) + { + removeExchangeMBean(mbean); + } + else if (mbean.isConnection()) + { + removeConnectionMBean(mbean); + } + + _mbeansMap.remove(mbean.getUniqueName()); + } + + public void putMBeanInfo(ManagedBean mbean, MBeanInfo mbeanInfo) + { + _mbeanInfoMap.put(mbean.getUniqueName(), mbeanInfo); + } + public MBeanInfo getMBeanInfo(ManagedBean mbean) + { + return _mbeanInfoMap.get(mbean.getUniqueName()); + } + + public List<ManagedBean> getMBeans() + { + return new ArrayList<ManagedBean>(_mbeansMap.values()); + } + + public void setNotificationInfo(ManagedBean mbean, List<NotificationInfoModel>value) + { + _notificationInfoMap.put(mbean.getUniqueName(), value); + } + + public List<NotificationInfoModel> getNotificationInfo(ManagedBean mbean) + { + return _notificationInfoMap.get(mbean.getUniqueName()); + } + + public void addNotification(ObjectName objName, Notification notification) + { + List<NotificationObject> list = _notificationsMap.get(objName.toString()); + NotificationObject obj = new NotificationObject(notification.getSequenceNumber(), + new Date(notification.getTimeStamp()), + notification.getMessage(), + notification.getSource(), + notification.getType()); + + if (list == null) + { + list = new ArrayList<NotificationObject>(); + _notificationsMap.put(objName.toString(), list); + } + + list.add(obj); + } + + /** + * Returns all the notification objects for a given mbean. If mbean is null, it returns + * notification objects for all the mbeans. + */ + public List<NotificationObject> getNotifications(ManagedBean mbean) + { + if (mbean == null) + { + List<NotificationObject> totalList = new ArrayList<NotificationObject>(); + for (List<NotificationObject> list : _notificationsMap.values()) + { + totalList.addAll(list); + } + return totalList; + } + else + { + return _notificationsMap.get(mbean.getUniqueName()); + } + } + + public void clearNotifications(ManagedBean mbean, List<NotificationObject> list) + { + if (mbean == null) + { + if (list == null || list.isEmpty()) + { + // All notifications of all mbeans to be cleared + _notificationsMap.clear(); + } + else + { + // Clear the selected notifications + for (NotificationObject obj : list) + { + mbean = _mbeansMap.get(obj.getSource().toString()); + List<NotificationObject> nList = _notificationsMap.get(mbean.getUniqueName()); + if (nList != null && !nList.isEmpty()) + { + nList.remove(obj); + } + } + } + } + else + { + if (list == null || list.isEmpty()) + { + // All notifications of this mbean to be cleared + List<NotificationObject> nList = _notificationsMap.get(mbean.getUniqueName()); + if (nList != null && !nList.isEmpty()) + { + nList.clear(); + } + } + else + { + // Clear the selected notifications + for (NotificationObject obj : list) + { + List<NotificationObject> nList = _notificationsMap.get(mbean.getUniqueName()); + if (nList != null && !nList.isEmpty()) + { + nList.remove(obj); + } + } + } + } + } + + + + /** + * Adds notification name and type to the map. The map contains all the notification names, + * subscribed for an mbean. + * @param mbean + * @param name + * @param type + */ + public void addNotificationListener(ManagedBean mbean, String name, String type) + { + // Get the subscribed notifications map for given mbean. If map is null then create a new one. + HashMap<String, List<String>> map = _subscribedNotificationMap.get(mbean.getUniqueName()); + if (map == null) + { + map = new HashMap<String, List<String>>(); + _subscribedNotificationMap.put(mbean.getUniqueName(),map); + } + + // Get the list of notification types for given notification name. If null, then create a new list. + List<String> list = map.get(name); + if (list == null) + { + list = new ArrayList<String>(); + map.put(name, list); + } + // Now add the notification type to the list + if (ALL.equals(type)) + { + List<NotificationInfoModel> infoList = _notificationInfoMap.get(mbean.getUniqueName()); + for (NotificationInfoModel model : infoList) + { + if (model.getName().equals(name)) + { + String[] types = model.getTypes(); + for (int i = 0; i < types.length; i++) + { + list.add(types[i]); + } + } + } + } + else + { + list.add(type); + } + + //System.out.println("Subscribed for notification :" + mbean.getUniqueName()); + } + + /** + * Checks if the given notification name and type are subscribed for the mbean. + */ + public boolean hasSubscribedForNotifications(ManagedBean mbean, String name, String type) + { + if (_subscribedNotificationMap.containsKey(mbean.getUniqueName())) + { + HashMap<String, List<String>> map = _subscribedNotificationMap.get(mbean.getUniqueName()); + if (map.containsKey(name)) + { + if (map.get(name).contains(type)) + { + return true; + } + } + } + return false; + } + + /** + * Clears the notification name and type information from the subscribed notifications map + * and removes the listener from mbeanserver connection + * @param mbean + * @param name + * @param type + * @throws Exception + */ + public void removeNotificationListener(ManagedBean mbean, String name, String type) throws Exception + { + //System.out.println("Removed notification listener :" + mbean.getUniqueName() + name +type); + if (_subscribedNotificationMap.containsKey(mbean.getUniqueName())) + { + // get the notifications map. This map contains the notification name mapped with the notification types + HashMap<String, List<String>> map = _subscribedNotificationMap.get(mbean.getUniqueName()); + if (map.containsKey(name)) + { + if (ALL.equals(type)) + { + map.remove(name); + } + else if (type != null) + { + map.get(name).remove(type); + if (map.get(name).isEmpty()) + { + map.remove(name); + } + } + } + if (map.size() == 0) + { + _subscribedNotificationMap.remove(mbean.getUniqueName()); + } + + JMXManagedObject jmxbean = (JMXManagedObject)mbean; + _mbsc.removeNotificationListener(jmxbean.getObjectName(), _notificationListener); + } + } + + /** + * When the mbean registration request is received from the mbean server, then the client listener + * can use this method. It will add the mbean to a list, which will be used to add the mbean to + * the registry and gui + * @param objName + */ + public void registerManagedObject(ObjectName objName) + { + JMXManagedObject managedObject = new JMXManagedObject(objName); + managedObject.setServer(getManagedServer()); + addManagedObject(managedObject); + } + + /** + * When mbean unregistration notification is received from the mbean server, then client listener + * can invoke this method. It will add the mbean to the list of mbeans to be removed from registry + * @param objName + */ + public void unregisterManagedObject(ObjectName objName) + { + ManagedBean mbean = _mbeansMap.get(objName.toString()); + removeManagedObject(mbean); + // Check if mbean was not available in the map. It can happen if mbean unregistration + // notification is received and the mbean is not added in the map. + if (mbean != null) + { + _mbeansToBeRemoved.add(mbean); + } + } + + public List<ManagedBean> getObjectsToBeRemoved() + { + if (_mbeansToBeRemoved.isEmpty()) + return null; + else + { + List<ManagedBean> list = new CopyOnWriteArrayList<ManagedBean>(_mbeansToBeRemoved); + _mbeansToBeRemoved.clear(); + return list; + } + } + + public void setAttributeModel(ManagedBean mbean, ManagedAttributeModel value) + { + _attributeModelMap.put(mbean.getUniqueName(), value); + } + + public ManagedAttributeModel getAttributeModel(ManagedBean mbean) + { + return _attributeModelMap.get(mbean.getUniqueName()); + } + + public void setOperationModel(ManagedBean mbean, OperationDataModel value) + { + _operationModelMap.put(mbean.getUniqueName(), value); + } + + public OperationDataModel getOperationModel(ManagedBean mbean) + { + return _operationModelMap.get(mbean.getUniqueName()); + } + + public List<String> getQueueNames(String virtualHostName) + { + List<ManagedBean> list = getQueues(virtualHostName); + if (list == null) + return null; + + List<String> queueNames = new ArrayList<String>(); + for (ManagedBean mbean : list) + { + queueNames.add(mbean.getName()); + } + return queueNames; + } + + public String[] getExchangeNames(String virtualHostName) + { + List<ManagedBean> list = getExchanges(virtualHostName); + if (list == null) + return null; + + String[] exchanges = new String[list.size()]; + int i = 0; + for (ManagedBean mbean : list) + { + exchanges[i++] = mbean.getName(); + } + return exchanges; + } + + public String[] getConnectionNames(String virtualHostName) + { + List<ManagedBean> list = getExchanges(virtualHostName); + if (list == null) + return null; + + String[] connections = new String[list.size()]; + int i = 0; + for (ManagedBean mbean : list) + { + connections[i++] = mbean.getName(); + } + return connections; + } + + public void setUserList(List<String> list) + { + _usersList = list; + Collections.sort(_usersList); + } + + public List<String> getUsernames() + { + return _usersList; + } + + public ClientNotificationListener getNotificationListener() + { + return _notificationListener; + } + + public ClientListener getClientListener() + { + return _clientListener; + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java new file mode 100644 index 0000000000..2d1883533b --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java @@ -0,0 +1,466 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.jmx; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.InstanceNotFoundException; +import javax.management.JMException; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanServerConnection; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.ReflectionException; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ManagedServer; +import org.apache.qpid.management.ui.exceptions.ManagementConsoleException; +import org.apache.qpid.management.ui.model.AttributeData; +import org.apache.qpid.management.ui.model.ManagedAttributeModel; +import org.apache.qpid.management.ui.model.NotificationInfoModel; +import org.apache.qpid.management.ui.model.OperationData; +import org.apache.qpid.management.ui.model.OperationDataModel; +import org.apache.qpid.management.ui.model.ParameterData; +import org.apache.qpid.management.ui.views.ViewUtility; + +/** + * Utility class for all mbeanserver related operations. Keeps all JMX code out from view and model classes + * @author Bhupendra Bhardwaj + */ +public class MBeanUtility +{ + public static final BigInteger MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE); + public static final BigInteger MAX_INT = BigInteger.valueOf(Integer.MAX_VALUE); + /** + * Retrieves the MBeanInfo from MBeanServer and stores in the application registry + * @param mbean managed bean + * @return MBeanInfo + * @throws Exception, if server connection is null or if server throws Exception + */ + public static MBeanInfo getMBeanInfo(ManagedBean mbean) throws Exception + { + ManagedServer server = mbean.getServer(); + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + if (mbsc == null) + { + throw new ManagementConsoleException("Server connection is broken"); + } + + JMXManagedObject jmxbean = (JMXManagedObject)mbean; + MBeanInfo mbeanInfo = mbsc.getMBeanInfo(jmxbean.getObjectName()); + serverRegistry.putMBeanInfo(mbean, mbeanInfo); + + // populate the server registry with attribute and operation info + getAttributes(mbean); + getOperations(mbean); + + return mbeanInfo; + } + + /** + * executes the MBean operation + * @param mbean + * @param opData + * @return MBean operation return value + * @throws Exception if server connection is broken or if operation execution fails on the mbean server + */ + public static Object execute(ManagedBean mbean, OperationData opData) throws Exception + { + String opName = opData.getName(); + Object[] values = null; + String[] signature = null; + + List<ParameterData> params = opData.getParameters(); + if (params != null && !params.isEmpty()) + { + signature = new String[params.size()];; + values = new Object[params.size()]; + for (int i = 0; i < params.size(); i++) + { + signature[i] = params.get(i).getType(); + values[i] = params.get(i).getValue(); + } + } + + ManagedServer server = mbean.getServer(); + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + if (mbsc == null) + { + throw new ManagementConsoleException("Server connection is broken"); + // TODO + // try and get the connection again if it was disconnected + } + JMXManagedObject jmxbean = (JMXManagedObject)mbean; + return mbsc.invoke(jmxbean.getObjectName(), opName, values, signature); + } + + /** + * @see MBeanUtility#handleException(ManagedBean, Exception) + */ + public static void handleException(Exception ex) + { + handleException(null, ex); + } + + /** + * handels the exception received. Shows the exception to the user in best suitable way + * @param mbean managed bean + * @param ex Exception + */ + public static void handleException(ManagedBean mbean, Throwable ex) + { + if (mbean == null) + { + ViewUtility.popupErrorMessage("Error", "Managed Object is null \n" + ex.toString()); + printStackTrace(ex); + } + else if (ex instanceof ReflectionException) + { + ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Server has thrown error \n" + ex.toString()); + printStackTrace(ex); + } + else if (ex instanceof InstanceNotFoundException) + { + ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Managed Object Not Found \n" + ex.toString()); + printStackTrace(ex); + } + else if (ex instanceof MBeanException) + { + String cause = ((MBeanException)ex).getTargetException().getMessage(); + if (cause == null) + cause = ex.toString(); + ViewUtility.popupInfoMessage(mbean.getInstanceName(), cause); + } + else if (ex instanceof JMException) + { + ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Management Exception occured \n" + ex.toString()); + } + else if (ex instanceof ManagementConsoleException) + { + ViewUtility.popupErrorMessage(mbean.getInstanceName(), ex.getMessage()); + } + else + { + if (ex.getCause() != null) + { + handleException(mbean, ex.getCause()); + } + else + { + String msg = ex.getMessage(); + if (msg == null) + { + msg = ex.toString(); + } + ViewUtility.popupErrorMessage(mbean.getInstanceName(), msg); + printStackTrace(ex); + } + } + + } + + /** + * Registers the notification listener with the MBeanServer + * @param mbean managed bean + * @param name notification name + * @param type notification type + * @throws Exception if server connection is broken or if listener could not be created + */ + public static void createNotificationlistener(ManagedBean mbean, String name, String type) + throws Exception + { + JMXManagedObject jmxbean = (JMXManagedObject)mbean; + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + serverRegistry.addNotificationListener(mbean, name, type); + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + + if (mbsc == null) + { + throw new ManagementConsoleException("Server connection is broken"); + } + mbsc.addNotificationListener(jmxbean.getObjectName(), serverRegistry.getNotificationListener(), null, null); + } + + public static void removeNotificationListener(ManagedBean mbean, String name, String type) throws Exception + { + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + serverRegistry.removeNotificationListener(mbean, name, type); + } + + /** + * Checks if the server registry contains attribute information for this mbean. If not then it queries the + * mbean server for complete mbean information, else it gets the latest value of the given attribute + * from mbean server. + * @return attribute data for the given mbean attribute + */ + public static AttributeData getAttributeData(ManagedBean mbean, String attribute) throws Exception + { + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean); + if (attributeModel == null) + { + // If process is here, it means the mbeanInfo is not retrieved from mbean server even once for this mbean + getMBeanInfo(mbean); + } + else + { + // refresh attribute value from mbean server + refreshAttribute(mbean, attribute); + } + attributeModel = serverRegistry.getAttributeModel(mbean); + return attributeModel.getAttribute(attribute); + } + + /** + * Retrieves the latest attribute value from mbean server for the given mbean attribute + * and also sets that value in the attribute model in the server registry + * @return latest attribute value for the given mbean attribute + */ + public static Object refreshAttribute(ManagedBean mbean, String attribute) throws Exception + { + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + + if (mbsc == null) + { + throw new ManagementConsoleException("Server connection is broken"); + } + + Object value = mbsc.getAttribute(((JMXManagedObject)mbean).getObjectName(), attribute); + // update the attribute data in server registry for this attribute + ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean); + attributeModel.setAttributeValue(attribute, value); + return value; + } + + /** + * Retrieves the attribute values from MBeanSever and stores in the server registry. + * @param mbean + * @return the attribute model + * @throws Exception if attributes can not be retrieved from MBeanServer + */ + public static ManagedAttributeModel getAttributes(ManagedBean mbean) throws Exception + { + ObjectName objName = ((JMXManagedObject)mbean).getObjectName(); + String[] attributes = null; + AttributeList list = null; + + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + MBeanAttributeInfo[] attributesInfo = null; + ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean); + + if (attributeModel == null) + { + // If the process is here, then it means the attribute values are not retrieved from mbean server + // even once for this mbean. Create attribute model, retrieve values from mbean server and + // set the attribute model in server registry for this mbean + attributeModel = new ManagedAttributeModel(); + attributesInfo = serverRegistry.getMBeanInfo(mbean).getAttributes(); + attributes = new String[attributesInfo.length]; + for (int i = 0; i< attributesInfo.length ; i++) + { + attributes[i] = attributesInfo[i].getName(); + attributeModel.setAttributeDescription(attributes[i], attributesInfo[i].getDescription()); + attributeModel.setAttributeWritable(attributes[i], attributesInfo[i].isWritable()); + attributeModel.setAttributeReadable(attributes[i], attributesInfo[i].isReadable()); + } + } + else + { + attributes = attributeModel.getAttributeNames().toArray(new String[0]); + } + + if (attributes.length != 0) + { + list = mbsc.getAttributes(objName, attributes); + for (Iterator itr = list.iterator(); itr.hasNext();) + { + Attribute attrib = (Attribute)itr.next(); + attributeModel.setAttributeValue(attrib.getName(), attrib.getValue()); + } + } + + serverRegistry.setAttributeModel(mbean, attributeModel); + return attributeModel; + } + + /** + * Updates the attribute value of an MBean + * @param mbean + * @param attribute + * @param value + * @throws Exception if MBeanServer throws exception in updating the attribute value + */ + public static void updateAttribute(ManagedBean mbean, AttributeData attribute, String value) throws Exception + { + JMXManagedObject jmxbean = (JMXManagedObject)mbean; + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + + Object newValue = value; + if (attribute.getDataType().equals(Long.class.getName())) + { + if (MAX_LONG.compareTo(new BigInteger(value)) == -1) + { + throw new ManagementConsoleException("Entered value is too big for \"" + + ViewUtility.getDisplayText(attribute.getName()) + "\""); + } + newValue = new Long(Long.parseLong(value)); + } + else if (attribute.getDataType().equals(Integer.class.getName())) + { + if (MAX_INT.compareTo(new BigInteger(value)) == -1) + { + throw new ManagementConsoleException("Entered value is too big for " + attribute.getName()); + } + newValue = new Integer(Integer.parseInt(value)); + } + + mbsc.setAttribute(jmxbean.getObjectName(), new Attribute(attribute.getName(), newValue)); + // Update the value in the registry, to avoid refreshing from mbsc + ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean); + attributeModel.setAttributeValue(attribute.getName(), newValue); + } + + /** + * populates the operation data model in server registry for given mbean + * @param mbean + * @return operation data model + */ + public static OperationDataModel getOperations(ManagedBean mbean) + { + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + OperationDataModel dataModel = serverRegistry.getOperationModel(mbean); + if (dataModel == null) + { + // Create operation model and set it in server registry for this mbean + MBeanOperationInfo[] operationsInfo = serverRegistry.getMBeanInfo(mbean).getOperations(); + dataModel = new OperationDataModel(); + + for (int i = 0; i < operationsInfo.length; i++) + { + dataModel.addOperation(operationsInfo[i]); + } + + serverRegistry.setOperationModel(mbean, dataModel); + } + return dataModel; + } + + /** + * populates the notification in the server registry for given mbean + * @param mbean + * @return notification info model + */ + public static NotificationInfoModel[] getNotificationInfo(ManagedBean mbean) + { + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + MBeanNotificationInfo[] info = serverRegistry.getMBeanInfo(mbean).getNotifications(); + + // Check if this mbean sends any notification + if (info == null || info.length == 0) + return null; + + // Create notification model if not already set in the server registry for this mbean + List<NotificationInfoModel> list = serverRegistry.getNotificationInfo(mbean); + if (list != null) + return list.toArray(new NotificationInfoModel[0]); + else + list = new ArrayList<NotificationInfoModel>(); + + for (int i = 0; i < info.length; i++) + { + list.add(new NotificationInfoModel(info[i].getName(), info[i].getDescription(), info[i].getNotifTypes())); + } + + // Set the notification model in the server registry for this mbean + serverRegistry.setNotificationInfo(mbean, list); + return list.toArray(new NotificationInfoModel[0]); + } + + /** + * Retrieves all the MBeans from mbean server for a given domain + * @return list of ManagedBeans + */ + public static List<ManagedBean> getManagedObjectsForDomain(ManagedServer server, String domain) throws Exception + { + List<ManagedBean> mbeans = new ArrayList<ManagedBean>(); + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + ObjectName objName = new ObjectName(domain + ":*"); + Set objectInstances = mbsc.queryMBeans(objName, null); + + for (Iterator itr = objectInstances.iterator(); itr.hasNext();) + { + ObjectInstance instance = (ObjectInstance)itr.next(); + ManagedBean obj = new JMXManagedObject(instance.getObjectName()); + mbeans.add(obj); + } + + return mbeans; + } + + /** + * Returns all the domains for the given server. This method can be removed as now this RCP is specific to + * Qpid and domain is also fixed + */ + public static List<String> getAllDomains(ManagedServer server) throws Exception + { + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + String[] domains = mbsc.getDomains(); + return Arrays.asList(domains); + } + + public static void printOutput(String statement) + { + if (ApplicationRegistry.debug) + { + System.out.println(statement); + } + } + + public static void printStackTrace(Throwable ex) + { + if (ApplicationRegistry.debug) + { + ex.printStackTrace(); + } + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/AttributeData.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/AttributeData.java new file mode 100644 index 0000000000..ccd4cf8df8 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/AttributeData.java @@ -0,0 +1,96 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.model; + +public class AttributeData +{ + String name = ""; + String description = ""; + String dataType = ""; + Object value = ""; + boolean readable = true; + boolean writable = false; + + + public String getDataType() + { + return dataType; + } + public void setDataType(String dataType) + { + this.dataType = dataType; + } + + public String getDescription() + { + return description; + } + public void setDescription(String description) + { + this.description = description; + } + + public String getName() + { + return name; + } + public void setName(String name) + { + this.name = name; + } + + public Object getValue() + { + return value; + } + public void setValue(Object value) + { + if (value != null) + this.value = value; + } + public boolean isReadable() + { + return readable; + } + public void setReadable(boolean readable) + { + this.readable = readable; + } + public boolean isWritable() + { + return writable; + } + public void setWritable(boolean writable) + { + this.writable = writable; + } + + public boolean isNumber() + { + if ("int".equals(dataType) || "java.lang.Integer".equals(dataType) || + "long".equals(dataType) || "java.lang.Long".equals(dataType) ) + { + return true; + } + else + return false; + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.java new file mode 100644 index 0000000000..b3219f15ea --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.java @@ -0,0 +1,118 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.model; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class ManagedAttributeModel +{ + HashMap<String, AttributeData> _attributeMap = new HashMap<String, AttributeData>(); + + public void setAttributeValue(String name, Object value) + { + if (value == null) + return; + + AttributeData data = null; + String dataType = value.getClass().getName(); + if (_attributeMap.containsKey(name)) + { + data = _attributeMap.get(name); + data.setValue(value); + } + else + { + data = new AttributeData(); + data.setName(name); + data.setValue(value); + _attributeMap.put(name, data); + } + data.setDataType(dataType); + } + + + public void setAttributeDescription(String name, String value) + { + if (_attributeMap.containsKey(name)) + { + _attributeMap.get(name).setDescription(value); + } + else + { + AttributeData data = new AttributeData(); + data.setName(name); + data.setDescription(value); + _attributeMap.put(name, data); + } + } + + public void setAttributeReadable(String name, boolean readable) + { + if (_attributeMap.containsKey(name)) + { + _attributeMap.get(name).setReadable(readable); + } + else + { + AttributeData data = new AttributeData(); + data.setName(name); + data.setReadable(readable); + _attributeMap.put(name, data); + } + } + + public void setAttributeWritable(String name, boolean writable) + { + if (_attributeMap.containsKey(name)) + { + _attributeMap.get(name).setWritable(writable); + } + else + { + AttributeData data = new AttributeData(); + data.setName(name); + data.setWritable(writable); + _attributeMap.put(name, data); + } + } + + public List<String> getAttributeNames() + { + return new ArrayList<String>(_attributeMap.keySet()); + } + + public AttributeData[] getAttributes() + { + return _attributeMap.values().toArray(new AttributeData[0]); + } + + public AttributeData getAttribute(String name) + { + return _attributeMap.get(name); + } + + public int getCount() + { + return _attributeMap.size(); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationInfoModel.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationInfoModel.java new file mode 100644 index 0000000000..6d4160889e --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationInfoModel.java @@ -0,0 +1,51 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.model; + +public class NotificationInfoModel +{ + String name; + String description; + String[] types; + + public NotificationInfoModel(String name, String desc, String[] types) + { + this.name = name; + this.description = desc; + this.types = types; + } + + public String getDescription() + { + return description; + } + + public String getName() + { + return name; + } + + public String[] getTypes() + { + return types; + } + +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java new file mode 100644 index 0000000000..926e5f0a24 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java @@ -0,0 +1,101 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.model; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +import javax.management.ObjectName; + +public class NotificationObject +{ + + private long _sequenceNo; + private Date _timeStamp; + private String _message; + private Object _source; + private String _type; // INFO, WARN, etc + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm:ss dd/MM/yy z"); + + public NotificationObject(long seqNo, Date timeStamp, String message, Object source, String type) + { + this._sequenceNo = seqNo; + this._message = message; + this._source = source; + this._type = type; + this._timeStamp = timeStamp; + dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); + } + + public Object getSource() + { + return _source; + } + public void setSource(Object _source) + { + this._source = _source; + } + + public String getSourceName() + { + if (_source instanceof ObjectName) + { + return ((ObjectName)_source).getKeyProperty("name"); + } + + return null; + } + + public String getMessage() + { + return _message; + } + public void setMessage(String _message) + { + this._message = _message; + } + public long getSequenceNo() + { + return _sequenceNo; + } + public void setSequenceNo(long no) + { + _sequenceNo = no; + } + public String getTimeStamp() + { + return dateFormat.format(_timeStamp); + } + public void setTimeStamp(Date stamp) + { + _timeStamp = stamp; + } + public String getType() + { + return _type; + } + public void setType(String _type) + { + this._type = _type; + } + +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java new file mode 100644 index 0000000000..bf3b730b3e --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java @@ -0,0 +1,110 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.model; + +import java.util.List; + +public class OperationData +{ + private String _name; + private String _description; + private String _returnType; + private int _impact; + private List<ParameterData> _parameters; + + public OperationData(String value) + { + this._name = value; + } + + public String getName() + { + return _name; + } + + public String getDescription() + { + return _description; + } + + public void setDescription(String description) + { + this._description = description; + } + + public List<ParameterData> getParameters() + { + return _parameters; + } + + public void setParameters(List<ParameterData> parameters) + { + this._parameters = parameters; + } + + public int getImpact() + { + return _impact; + } + + public void setImpact(int impact) + { + this._impact = impact; + } + + public String getReturnType() + { + return _returnType; + } + + public void setReturnType(String returnType) + { + this._returnType = returnType; + } + + public boolean isReturnTypeBoolean() + { + return (_returnType.equals("boolean") || _returnType.equals("java.lang.Boolean")); + } + + public boolean isReturnTypeVoid() + { + return (_returnType.equals("void") || _returnType.equals("java.lang.Void")); + } + + public Object getParameterValue(String paramName) + { + if (_parameters == null) + { + return null; + } + + for (int i = 0; i < _parameters.size(); i++) + { + if (paramName.equalsIgnoreCase(_parameters.get(i).getName())) + { + return _parameters.get(i).getValue(); + } + } + + return null; + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationDataModel.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationDataModel.java new file mode 100644 index 0000000000..96964a81ef --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationDataModel.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.ui.model; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import javax.management.MBeanOperationInfo; +import javax.management.MBeanParameterInfo; + +public class OperationDataModel +{ + HashMap<String, OperationData> _operationMap = new HashMap<String, OperationData>(); + + public void addOperation(MBeanOperationInfo opInfo) + { + OperationData opData = new OperationData(opInfo.getName()); + opData.setDescription(opInfo.getDescription()); + opData.setImpact(opInfo.getImpact()); + opData.setReturnType(opInfo.getReturnType()); + + int parametersCount = opInfo.getSignature().length; + if (parametersCount != 0) + { + List<ParameterData> paramList = new ArrayList<ParameterData>(); + for (int i = 0; i < parametersCount; i++) + { + MBeanParameterInfo paramInfo = opInfo.getSignature()[i]; + ParameterData param = new ParameterData(paramInfo.getName(), paramInfo.getDescription(), + paramInfo.getType()); + paramList.add(param); + } + opData.setParameters(paramList); + } + + _operationMap.put(opInfo.getName(), opData); + } + + public OperationData getOperation(String name) + { + return _operationMap.get(name); + } + + public List<OperationData> getOperations() + { + return new ArrayList<OperationData>(_operationMap.values()); + } + + public int getCount() + { + return _operationMap.size(); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ParameterData.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ParameterData.java new file mode 100644 index 0000000000..d12217c6eb --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ParameterData.java @@ -0,0 +1,95 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.model; + +/** + * Class representing an mbean operation parameter + * @author Bhupendra Bhardwaj + */ +public class ParameterData +{ + private String _name; + private String _description; + private String _type; + private Object _value; + + ParameterData(String name, String desc, String type) + { + this._name = name; + this._description = desc; + this._type = type; + setDefaultValue(); + } + + public String getDescription() + { + return _description; + } + + public String getName() + { + return _name; + } + + public String getType() + { + return _type; + } + + public Object getValue() + { + return _value; + } + + public void setValueFromString(String strValue) + { + if ("int".equals(_type)) + _value = Integer.parseInt(strValue); + else if (isBoolean()) + _value = Boolean.valueOf(strValue); + else if ("long".equals(_type)) + _value = Long.parseLong(strValue); + else + _value = strValue; + } + + public void setValue(Object value) + { + this._value = value; + } + + public boolean isBoolean() + { + return (_type.equals("boolean") || _type.equals("java.lang.Boolean")); + } + + public void setDefaultValue() + { + if (isBoolean()) + { + _value = Boolean.valueOf("false"); + } + else + { + _value = null; + } + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java new file mode 100644 index 0000000000..32a0c12344 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java @@ -0,0 +1,60 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.sasl; + +import java.util.Map; + +import javax.security.auth.callback.CallbackHandler; +import javax.security.sasl.Sasl; +import javax.security.sasl.SaslClient; +import javax.security.sasl.SaslClientFactory; +import javax.security.sasl.SaslException; + +public class CRAMMD5HashedSaslClientFactory implements SaslClientFactory +{ + /** The name of this mechanism */ + public static final String MECHANISM = "CRAM-MD5-HASHED"; + + public SaslClient createSaslClient(String[] mechanisms, String authorizationId, String protocol, + String serverName, Map<String, ?> props, CallbackHandler cbh) + throws SaslException + { + for (int i = 0; i < mechanisms.length; i++) + { + if (mechanisms[i].equals(MECHANISM)) + { + if (cbh == null) + { + throw new SaslException("CallbackHandler must not be null"); + } + + String[] mechs = {"CRAM-MD5"}; + return Sasl.createSaslClient(mechs, authorizationId, protocol, serverName, props, cbh); + } + } + return null; + } + + public String[] getMechanismNames(Map props) + { + return new String[]{MECHANISM}; + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java new file mode 100644 index 0000000000..ce9a273eaa --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java @@ -0,0 +1,54 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.sasl; + +import java.util.Map; + +import javax.security.auth.callback.CallbackHandler; +import javax.security.sasl.SaslClient; +import javax.security.sasl.SaslClientFactory; +import javax.security.sasl.SaslException; + +public class ClientSaslFactory implements SaslClientFactory +{ + public SaslClient createSaslClient(String[] mechs, String authorizationId, String protocol, + String serverName, Map props, CallbackHandler cbh) + throws SaslException + { + for (int i = 0; i < mechs.length; i++) + { + if (mechs[i].equals("PLAIN")) + { + return new PlainSaslClient(authorizationId, cbh); + } + } + return null; + } + + /** + * Simple-minded implementation that ignores props + */ + public String[] getMechanismNames(Map props) + { + return new String[]{"PLAIN"}; + } + +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java new file mode 100644 index 0000000000..d8189f3ac3 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.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.ui.sasl; + +import java.security.Provider; +import java.util.Map; + +import javax.security.sasl.SaslClientFactory; + +public class JCAProvider extends Provider +{ + private static final long serialVersionUID = 1L; + + /** + * Creates the security provider with a map from SASL mechanisms to implementing factories. + * + * @param providerMap The map from SASL mechanims to implementing factory classes. + */ + public JCAProvider(Map<String, Class<? extends SaslClientFactory>> providerMap) + { + super("AMQSASLProvider", 1.0, "A JCA provider that registers all " + + "AMQ SASL providers that want to be registered"); + register(providerMap); + } + + /** + * Registers client factory classes for a map of mechanism names to client factory classes. + * + * @param providerMap The map from SASL mechanims to implementing factory classes. + */ + private void register(Map<String, Class<? extends SaslClientFactory>> providerMap) + { + for (Map.Entry<String, Class<? extends SaslClientFactory>> me : providerMap.entrySet()) + { + put("SaslClientFactory." + me.getKey(), me.getValue().getName()); + } + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java new file mode 100644 index 0000000000..22190f29eb --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java @@ -0,0 +1,203 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.sasl; + +import java.io.*; +import javax.security.auth.callback.*; +import javax.security.sasl.*; + +public class PlainSaslClient implements SaslClient +{ + + private boolean completed; + private CallbackHandler cbh; + private String authorizationID; + private String authenticationID; + private byte password[]; + private static byte SEPARATOR = 0; + + public PlainSaslClient(String authorizationID, CallbackHandler cbh) throws SaslException + { + completed = false; + this.cbh = cbh; + Object[] userInfo = getUserInfo(); + this.authorizationID = authorizationID; + this.authenticationID = (String) userInfo[0]; + this.password = (byte[]) userInfo[1]; + if (authenticationID == null || password == null) + { + throw new SaslException("PLAIN: authenticationID and password must be specified"); + } + } + + public byte[] evaluateChallenge(byte[] challenge) throws SaslException + { + if (completed) + { + throw new IllegalStateException("PLAIN: authentication already " + + "completed"); + } + completed = true; + try + { + byte authzid[] = + authorizationID == null ? null : authorizationID.getBytes("UTF8"); + byte authnid[] = authenticationID.getBytes("UTF8"); + byte response[] = + new byte[ + password.length + + authnid.length + + 2 + // SEPARATOR + (authzid != null ? authzid.length : 0) + ]; + int size = 0; + if (authzid != null) { + System.arraycopy(authzid, 0, response, 0, authzid.length); + size = authzid.length; + } + response[size++] = SEPARATOR; + System.arraycopy(authnid, 0, response, size, authnid.length); + size += authnid.length; + response[size++] = SEPARATOR; + System.arraycopy(password, 0, response, size, password.length); + clearPassword(); + return response; + } catch (UnsupportedEncodingException e) { + throw new SaslException("PLAIN: Cannot get UTF-8 encoding of ids", + e); + } + } + + public String getMechanismName() + { + return "PLAIN"; + } + + public boolean hasInitialResponse() + { + return true; + } + + public boolean isComplete() + { + return completed; + } + + public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException + { + if (completed) { + throw new IllegalStateException("PLAIN: this mechanism supports " + + "neither integrity nor privacy"); + } else { + throw new IllegalStateException("PLAIN: authentication not " + + "completed"); + } + } + + public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException + { + if (completed) + { + throw new IllegalStateException("PLAIN: this mechanism supports " + + "neither integrity nor privacy"); + } + else + { + throw new IllegalStateException("PLAIN: authentication not " + + "completed"); + } + } + + public Object getNegotiatedProperty(String propName) + { + if (completed) + { + if (propName.equals(Sasl.QOP)) + { + return "auth"; + } + else + { + return null; + } + } + else + { + throw new IllegalStateException("PLAIN: authentication not " + + "completed"); + } + } + + private void clearPassword() + { + if (password != null) + { + for (int i = 0 ; i < password.length ; i++) + { + password[i] = 0; + } + password = null; + } + } + + public void dispose() throws SaslException + { + clearPassword(); + } + + protected void finalize() + { + clearPassword(); + } + + private Object[] getUserInfo() throws SaslException + { + try + { + final String userPrompt = "PLAIN authentication id: "; + final String pwPrompt = "PLAIN password: "; + NameCallback nameCb = new NameCallback(userPrompt); + PasswordCallback passwordCb = new PasswordCallback(pwPrompt, false); + cbh.handle(new Callback[] { nameCb, passwordCb }); + String userid = nameCb.getName(); + char pwchars[] = passwordCb.getPassword(); + byte pwbytes[]; + if (pwchars != null) + { + pwbytes = (new String(pwchars)).getBytes("UTF8"); + passwordCb.clearPassword(); + } + else + { + pwbytes = null; + } + return (new Object[] { userid, pwbytes }); + } + catch (IOException e) + { + throw new SaslException("Cannot get password", e); + } + catch (UnsupportedCallbackException e) + { + throw new SaslException("Cannot get userid/password", e); + } + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java new file mode 100644 index 0000000000..2917de8740 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java @@ -0,0 +1,35 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.sasl; + +import java.security.Provider; + +public class SaslProvider extends Provider +{ + private static final long serialVersionUID = -6978096016899676466L; + + public SaslProvider() + { + super("SaslClientFactory", 1.0, "SASL PLAIN CLIENT MECHANISM"); + put("SaslClientFactory.PLAIN", "ClientSaslFactory"); + } + +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java new file mode 100644 index 0000000000..1602229c85 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.sasl; + +import java.io.*; +import javax.security.auth.callback.*; + +public class UserPasswordCallbackHandler implements CallbackHandler +{ + private String user; + private char[] pwchars; + + public UserPasswordCallbackHandler(String user, String password) + { + this.user = user; + this.pwchars = password.toCharArray(); + } + + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException + { + for (int i = 0; i < callbacks.length; i++) + { + if (callbacks[i] instanceof NameCallback) + { + NameCallback ncb = (NameCallback) callbacks[i]; + ncb.setName(user); + } + else if (callbacks[i] instanceof PasswordCallback) + { + PasswordCallback pcb = (PasswordCallback) callbacks[i]; + pcb.setPassword(pwchars); + } + else + { + throw new UnsupportedCallbackException(callbacks[i]); + } + } + } + + private void clearPassword() + { + if (pwchars != null) + { + for (int i = 0 ; i < pwchars.length ; i++) + { + pwchars[i] = 0; + } + pwchars = null; + } + } + + protected void finalize() + { + clearPassword(); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java new file mode 100644 index 0000000000..f4e3d2661e --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.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.ui.sasl; + +import java.io.IOException; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; + +import org.apache.qpid.management.ui.views.ViewUtility; + +public class UsernameHashedPasswordCallbackHandler implements CallbackHandler +{ + private String user; + private char[] pwchars; + + public UsernameHashedPasswordCallbackHandler(String user, String password) throws Exception + { + this.user = user; + this.pwchars = ViewUtility.getHash(password); + } + + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException + { + for (int i = 0; i < callbacks.length; i++) + { + if (callbacks[i] instanceof NameCallback) + { + NameCallback ncb = (NameCallback) callbacks[i]; + ncb.setName(user); + } + else if (callbacks[i] instanceof PasswordCallback) + { + PasswordCallback pcb = (PasswordCallback) callbacks[i]; + pcb.setPassword(pwchars); + } + else + { + throw new UnsupportedCallbackException(callbacks[i]); + } + } + } + + + private void clearPassword() + { + if (pwchars != null) + { + for (int i = 0 ; i < pwchars.length ; i++) + { + pwchars[i] = 0; + } + pwchars = null; + } + } + + protected void finalize() + { + clearPassword(); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java new file mode 100644 index 0000000000..3234503fb5 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java @@ -0,0 +1,936 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.views; + +import static org.apache.qpid.management.ui.Constants.*; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.jmx.JMXServerRegistry; +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.apache.qpid.management.ui.model.AttributeData; +import org.apache.qpid.management.ui.model.ManagedAttributeModel; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.widgets.Form; +import org.eclipse.ui.forms.widgets.FormToolkit; + + +/** + * Creates controller composite for the attribute's tab. + * @author Bhupendra Bhardwaj + */ +public class AttributesTabControl extends TabControl +{ + private FormToolkit _toolkit; + private Form _form; + private Table _table = null; + private TableViewer _tableViewer = null; + private static final int[] tableWidths = new int[] {300, 300}; + + private Composite _tableComposite = null; + private Composite _buttonsComposite = null; + + private DisposeListener tableDisposeListener = new DisposeListenerImpl(); + final Image image; + private Button _detailsButton = null; + private Button _editButton = null; + private Button _graphButton = null; + private Button _refreshButton = null; + private boolean disableEditing = false; + + private static final String MAX_VALUE = "MaxValue"; + private static final String GRAPH_VALUES = "GraphValues"; + private int GRAPH_WIDTH = 700; + private int GRAPH_HEIGHT = 450; + private int GRAPH_ITEM_GAP = 100; + private int startX = 80; + private int startY = 60; + + public AttributesTabControl(TabFolder tabFolder) + { + super(tabFolder); + _toolkit = new FormToolkit(_tabFolder.getDisplay()); + _form = _toolkit.createForm(_tabFolder); + GridLayout gridLayout = new GridLayout(2, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + _form.getBody().setLayout(gridLayout); + _tableComposite = _toolkit.createComposite(_form.getBody()); + _tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + _tableComposite.setLayout(new GridLayout()); + _buttonsComposite = _toolkit.createComposite(_form.getBody()); + _buttonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true)); + _buttonsComposite.setLayout(new GridLayout()); + + image = Display.getCurrent().getSystemImage(SWT.ICON_INFORMATION); + createWidgets(); + } + + /** + * @see TabControl#getControl() + */ + public Control getControl() + { + return _form; + } + + /** + * Creates required widgets for Attribute's tab + */ + protected void createWidgets() + { + createTable(); + createTableViewer(); + createButtons(); + addTableListeners(); + } + + /** + * Creates table for listing the MBean attributes + */ + private void createTable() + { + _table = _toolkit.createTable(_tableComposite, SWT.FULL_SELECTION); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + _table.setLayoutData(gridData); + + for (int i = 0; i < ATTRIBUTE_TABLE_TITLES.length; ++i) + { + final TableColumn column = new TableColumn(_table, SWT.NONE); + column.setText(ATTRIBUTE_TABLE_TITLES[i]); + column.setWidth(tableWidths[i]); + column.setResizable(false); + } + + _table.setLinesVisible (true); + _table.setHeaderVisible (true); + } + + /** + * Creates tableviewer for the attribute's table + */ + private void createTableViewer() + { + _tableViewer = new TableViewer(_table); + _tableViewer.setUseHashlookup(true); + _tableViewer.setColumnProperties(ATTRIBUTE_TABLE_TITLES); + _tableViewer.setContentProvider(new ContentProviderImpl()); + _tableViewer.setLabelProvider(new LabelProviderImpl()); + _tableViewer.setSorter(new ViewerSorterImpl()); + } + + private void createButtons() + { + addDetailsButton(); + addEditButton(); + addGraphButton(); + addRefreshButton(); + } + + private void addDetailsButton() + { + // Create and configure the button for attribute details + _detailsButton = _toolkit.createButton(_buttonsComposite, BUTTON_DETAILS, SWT.PUSH | SWT.CENTER); + _detailsButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); + GridData gridData = new GridData(SWT.CENTER, SWT.TOP, false, false); + gridData.widthHint = 80; + _detailsButton.setLayoutData(gridData); + _detailsButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + disableEditing = true; + int index = _table.getSelectionIndex(); + TableItem item = _table.getItem(index); + createDetailsPopup((AttributeData)item.getData()); + disableEditing = false; + setFocus(); + } + }); + } + + /** + * Creates the button for editing attributes. + */ + private void addEditButton() + { + // Create and configure the button for editing attribute + _editButton = _toolkit.createButton(_buttonsComposite, BUTTON_EDIT_ATTRIBUTE, SWT.PUSH | SWT.CENTER); + _editButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); + GridData gridData = new GridData(SWT.CENTER, SWT.TOP, false, false); + gridData.widthHint = 80; + _editButton.setLayoutData(gridData); + _editButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + int index = _table.getSelectionIndex(); + TableItem item = _table.getItem(index); + createDetailsPopup((AttributeData)item.getData()); + setFocus(); + } + }); + } + + /** + * Creates the button for viewing Graphs + */ + private void addGraphButton() + { + _graphButton = _toolkit.createButton(_buttonsComposite, BUTTON_GRAPH, SWT.PUSH | SWT.CENTER); + _graphButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); + GridData gridData = new GridData(SWT.CENTER, SWT.TOP, false, false); + gridData.widthHint = 80; + _graphButton.setLayoutData(gridData); + _graphButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent event) + { + int selectionIndex = _table.getSelectionIndex(); + AttributeData data = (AttributeData)_table.getItem(selectionIndex).getData(); + createGraph(data); + setFocus(); + } + }); + } + + /** + * Creates the "Refresh" button + */ + private void addRefreshButton() + { + _refreshButton = _toolkit.createButton(_buttonsComposite, BUTTON_REFRESH, SWT.PUSH | SWT.CENTER); + + _refreshButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); + GridData gridData = new GridData(SWT.CENTER, SWT.TOP, false, false); + gridData.widthHint = 80; + _refreshButton.setLayoutData(gridData); + _refreshButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + try + { + // refresh the attributes list + refresh(_mbean); + } + catch (Exception ex) + { + MBeanUtility.handleException(_mbean, ex); + } + + } + }); + } + + private void addTableListeners() + { + _tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){ + public void selectionChanged(SelectionChangedEvent evt) + { + IStructuredSelection ss = (IStructuredSelection)evt.getSelection(); + checkForEnablingButtons((AttributeData)ss.getFirstElement()); + } + }); + + MouseListenerImpl listener = new MouseListenerImpl(); + _tableViewer.getTable().addMouseTrackListener(listener); + _tableViewer.getTable().addMouseMoveListener(listener); + _tableViewer.getTable().addMouseListener(listener); + + _table.addDisposeListener(tableDisposeListener); + + // _table is equal to _tableViewer.getControl() + _table.addListener(SWT.MeasureItem, new Listener() { + public void handleEvent(Event event) + { + event.height = event.gc.getFontMetrics().getHeight() * 3/2; + } + }); + } + + /** + * Listeners implementation class for showing table tooltip + * @author Bhupendra Bhardwaj + */ + private class MouseListenerImpl implements MouseTrackListener, MouseMoveListener, KeyListener, MouseListener + { + Shell tooltipShell = null; + Label tooltipLabel = null; + public void mouseHover(MouseEvent event) + { + TableItem item = _table.getItem (new Point (event.x, event.y)); + + if (item != null) + { + AttributeData data = (AttributeData)item.getData(); + if (tooltipShell != null && !tooltipShell.isDisposed ()) tooltipShell.dispose (); + tooltipShell = new Shell(_table.getShell(), SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL); + tooltipShell.setBackground(event.display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + FillLayout layout = new FillLayout(); + layout.marginWidth = 2; + tooltipShell.setLayout(layout); + tooltipLabel = new Label(tooltipShell, SWT.NONE); + tooltipLabel.setForeground(event.display.getSystemColor(SWT.COLOR_INFO_FOREGROUND)); + tooltipLabel.setBackground(event.display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + tooltipLabel.setText(data.getDescription()); + tooltipLabel.setData("_TABLEITEM", item); + tooltipLabel.addListener(SWT.MouseExit, tooltipLabelListener); + tooltipLabel.addListener(SWT.MouseDown, tooltipLabelListener); + Point size = tooltipShell.computeSize(SWT.DEFAULT, SWT.DEFAULT); + Rectangle rect = item.getBounds(0); + Point pt = _table.toDisplay(rect.x, rect.y); + tooltipShell.setBounds(pt.x, pt.y, size.x, size.y); + tooltipShell.setVisible(true); + } + } + public void mouseEnter(MouseEvent e) + { + } + public void mouseExit(MouseEvent e) + { + } + + // MouseMoveListener implementation + public void mouseMove(MouseEvent event) + { + if (tooltipShell == null) + return; + + tooltipShell.dispose(); + tooltipShell = null; + tooltipLabel = null; + } + + // KeyListener implementation + public void keyPressed(KeyEvent e) + { + if (tooltipShell == null) + return; + + tooltipShell.dispose(); + tooltipShell = null; + tooltipLabel = null; + } + public void keyReleased(KeyEvent e) + { + + } + + // MouseListener implementation + public void mouseDoubleClick(MouseEvent event) + { + if (tooltipShell != null) + { + tooltipShell.dispose(); + tooltipShell = null; + tooltipLabel = null; + } + Table table = (Table)event.getSource(); + int selectionIndex = table.getSelectionIndex(); + AttributeData data = (AttributeData)table.getItem(selectionIndex).getData(); + createDetailsPopup(data); + } + public void mouseDown(MouseEvent e) + { + if (tooltipShell != null) + { + tooltipShell.dispose(); + tooltipShell = null; + tooltipLabel = null; + } + } + public void mouseUp(MouseEvent e) + { + + } + } // end of MouseListenerImpl + + /** + * Creates pop-up window for showing attribute details + * @param data - Selectes attribute + */ + public void createDetailsPopup(AttributeData data) + { + int width = 500; + int height = 250; + if (!isSimpleType(data.getValue())) + { + width = 650; + height = 450; + } + + Display display = Display.getCurrent(); + Shell shell = ViewUtility.createPopupShell(ATTRIBUTE, width, height); + createDetailsPopupContents(shell, data); + + shell.open(); + while (!shell.isDisposed()) + { + if (!display.readAndDispatch()) + { + display.sleep(); + } + } + shell.dispose(); + } + + /** + * Listener class for table tooltip label + */ + final Listener tooltipLabelListener = new Listener () + { + public void handleEvent (Event event) + { + Label label = (Label)event.widget; + Shell shell = label.getShell(); + switch (event.type) + { + case SWT.MouseDown: + Event e = new Event(); + e.item = (TableItem)label.getData ("_TABLEITEM"); + _table.setSelection(new TableItem[] {(TableItem)e.item}); + shell.dispose(); + _table.setFocus(); + break; + case SWT.MouseExit: + shell.dispose(); + break; + } + } + }; + + + /** + * Create the contents for the attribute details window pop-up + * @param shell - The shell that will be filled with details. + * @param attribute - Selected attribute + */ + private void createDetailsPopupContents(Composite shell, AttributeData attribute) + { + GridLayout layout = new GridLayout(2, false); + layout.horizontalSpacing = 10; + layout.verticalSpacing = 10; + layout.marginHeight = 20; + layout.marginWidth = 20; + + Composite parent = _toolkit.createComposite(shell, SWT.NONE); + parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + parent.setLayout(layout); + + // Name + Label label = _toolkit.createLabel(parent, ATTRIBUTE_TABLE_TITLES[0], SWT.NONE); + GridData layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false); + label.setLayoutData(layoutData); + int textStyle = SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY; + Text value = _toolkit.createText(parent, ViewUtility.getDisplayText(attribute.getName()), textStyle); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + + + // Description + label = _toolkit.createLabel(parent, DESCRIPTION, SWT.NONE); + label.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + value = _toolkit.createText(parent, attribute.getDescription(), textStyle); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + + // value + label = _toolkit.createLabel(parent, ATTRIBUTE_TABLE_TITLES[1], SWT.NONE); + label.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + + if (!attribute.isReadable()) + { + value = _toolkit.createText(parent, "", textStyle); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + } + else + { + if (!isSimpleType(attribute.getValue())) + { + Composite composite = new Composite(parent, SWT.BORDER); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + ViewUtility.populateCompositeWithData(_toolkit, composite, attribute.getValue()); + } + else + { + if (attribute.isWritable()) + { + value = _toolkit.createText(parent, "", SWT.BEGINNING | SWT.BORDER); + value.addVerifyListener(new NumberVerifyListener()); + + // set data to access in the listener + parent.setData(attribute); + } + else + { + value = _toolkit.createText(parent, "", textStyle); + } + + value.setText(attribute.getValue().toString()); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + } + } + + + // Update button + Button updateButton = addUpdateButton(parent); + updateButton.setData(value); + if (!attribute.isWritable()) + { + updateButton.setVisible(false); + } + + if (disableEditing) + { + value.setEditable(false); + updateButton.setVisible(false); + } + } + + /** + * Create the button for updating attributes. This should be enabled for writable attribute + */ + private Button addUpdateButton(Composite parent) + { + final Button updateButton = new Button(parent, SWT.PUSH | SWT.CENTER); + // set the data to access in the listener + parent.setData(BUTTON_UPDATE, updateButton); + + updateButton.setText(BUTTON_UPDATE); + GridData gridData = new GridData (SWT.CENTER, SWT.BOTTOM, true, true, 2, 1); + gridData.widthHint = 100; + updateButton.setLayoutData(gridData); + updateButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent event) + { + try + { + Button button = (Button)event.widget; + Text text = (Text)button.getData(); + AttributeData data = (AttributeData)button.getParent().getData(); + MBeanUtility.updateAttribute(_mbean, data, text.getText()); + button.getShell().close(); + refresh(); + } + catch (Exception ex) + { + MBeanUtility.handleException(_mbean, ex); + } + } + }); + + return updateButton; + } + + // Refresh from the server registry + public void refresh() + { + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_mbean); + ManagedAttributeModel attributesList = serverRegistry.getAttributeModel(_mbean); + _tableViewer.setInput(attributesList); + } + + /** + * Refreshes the attribute tab by querying the mbean server for latest values + */ + @Override + public void refresh(ManagedBean mbean) + { + _mbean = mbean; + if (_mbean == null) + { + _tableViewer.setInput(null); + return; + } + ManagedAttributeModel attributesList = null; + try + { + attributesList = MBeanUtility.getAttributes(mbean); + } + catch(Exception ex) + { + MBeanUtility.handleException(_mbean, ex); + } + _tableViewer.setInput(attributesList); + checkForEnablingButtons(getSelectionAttribute()); + + _form.layout(true); + _form.getBody().layout(true, true); + } + + /** + * @see TabControl#setFocus() + */ + public void setFocus() + { + _table.setFocus(); + } + + /** + * Checks which buttons are to be enabled or disabled. The graph button will be enabled only + * for readable number attributes. Editing is enabled for writeable attribtues. + * @param attribute + */ + private void checkForEnablingButtons(AttributeData attribute) + { + if (attribute == null) + { + _detailsButton.setEnabled(false); + _editButton.setEnabled(false); + _graphButton.setEnabled(false); + _refreshButton.setEnabled(false); + return; + } + + _detailsButton.setEnabled(true); + _refreshButton.setEnabled(true); + if (attribute.isWritable()) + { + _editButton.setEnabled(true); + _graphButton.setEnabled(false); + } + else + { + _editButton.setEnabled(false); + // Currently only Queues are having attributes, which are suitable for a graph + if (attribute.isNumber() && _mbean.isQueue()) + { + _graphButton.setEnabled(true); + } + else + { + _graphButton.setEnabled(false); + } + } + } + + /** + * Creates graph in a pop-up window for given attribute. + * @param data + */ + private void createGraph(final AttributeData data) + { + Display display = Display.getCurrent(); + Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN | SWT.MAX); + shell.setText(_mbean.getName()); + int x = display.getBounds().width; + int y = display.getBounds().height; + shell.setBounds(x/4, y/4, GRAPH_WIDTH, GRAPH_HEIGHT); + shell.setLayout(new FillLayout()); + + final Canvas canvas = new Canvas(shell, SWT.NONE); + long currentValue = Long.parseLong(data.getValue().toString()); + long mValue = getGraphMaxValue(currentValue); + canvas.setData(MAX_VALUE, mValue); + canvas.setData(GRAPH_VALUES, new long[] {0,0,0,0,0,currentValue}); + + canvas.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + canvas.addPaintListener(new PaintListener() + { + public void paintControl(PaintEvent event) + { + Canvas canvas = (Canvas)event.widget; + int maxX = canvas.getSize().x; + int maxY = canvas.getSize().y; + event.gc.fillRectangle(canvas.getBounds()); + event.gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); + event.gc.setLineWidth(4); + + Object canvasData = canvas.getData(MAX_VALUE); + String str = canvasData.toString(); + long maxValue = Long.parseLong(str); + // Set the graph dimensions + event.gc.drawText("0", startX - 40, maxY - startY - 10); + event.gc.drawText("" + maxValue/2, startX - 40, maxY/2); + event.gc.drawText("" + maxValue, startX - 40, startY); + + // horizontal line + event.gc.drawLine(startX, maxY - startY, maxX - 60, maxY - startY); + // vertical line + event.gc.drawLine(startX, maxY - startY, startX, startY); + // set graph text + event.gc.drawText(data.getName(), startX - 40, startY - 40); + event.gc.drawText("25 sec", startX, maxY - startY + 10); + event.gc.drawText("20 sec", startX + GRAPH_ITEM_GAP, maxY - startY + 10); + event.gc.drawText("15 sec", startX + GRAPH_ITEM_GAP * 2, maxY - startY + 10); + event.gc.drawText("10 sec", startX + GRAPH_ITEM_GAP * 3, maxY - startY + 10); + event.gc.drawText(" 5 sec", startX + GRAPH_ITEM_GAP * 4, maxY - startY + 10); + event.gc.drawText(" 0 sec", startX + GRAPH_ITEM_GAP * 5, maxY - startY + 10); + + // plot the graph now for values + event.gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLUE)); + canvasData = canvas.getData(GRAPH_VALUES); + long[] graphValues = (long[]) canvasData; + for (int i = 0; i < graphValues.length; i++) + { + int x = startX + i * GRAPH_ITEM_GAP; + int yTotalLength = (maxY - 2 * startY); + float ratio = ((float)graphValues[i]/(float)maxValue); + int itemlength = (int)(yTotalLength * ratio); + int y = maxY - startY - itemlength; + event.gc.drawLine(x, maxY- startY, x, y); + event.gc.drawText(String.valueOf(graphValues[i]), x, y - 20); + } + } + }); + + shell.open(); + + // Set up the timer for the animation + Runnable runnable = new Runnable() + { + public void run() + { + try + { + animate(canvas, data); + Display.getCurrent().timerExec(TIMER_INTERVAL, this); + } + catch(Exception ex) + { + MBeanUtility.handleException(ex); + } + } + }; + + // Launch the timer + display.timerExec(TIMER_INTERVAL, runnable); + + while (!shell.isDisposed()) + { + if (!display.readAndDispatch()) + { + display.sleep(); + } + } + + // Kill the timer + display.timerExec(-1, runnable); + shell.dispose(); + } + + /** + * @return selected attribute in the table + */ + public AttributeData getSelectionAttribute() + { + int index = _table.getSelectionIndex(); + if (index == -1) + return null; + + return (AttributeData)_table.getItem(index).getData(); + } + + /** + * checks for newer values of selected attribute to update the graph + * @param canvas + * @param data + * @throws Exception + */ + private void animate(Canvas canvas, AttributeData data) throws Exception + { + String attribute = data.getName(); + Object valueObj = MBeanUtility.refreshAttribute(_mbean, attribute); + int value = Integer.parseInt(String.valueOf(valueObj)); + Object canvasData = canvas.getData(GRAPH_VALUES); + long[] graphValues = (long[]) canvasData; + + for (int i = 0; i < graphValues.length -1; i++) + { + graphValues[i] = graphValues[i + 1]; + } + graphValues[graphValues.length - 1] = value; + + canvasData = canvas.getData(MAX_VALUE); + long maxValue = Long.parseLong(String.valueOf(canvasData)); + if (maxValue < value) + { + maxValue = getGraphMaxValue(value); + canvas.setData(MAX_VALUE, maxValue); + } + + canvas.redraw(); + } + + /** + * @param maxAttributeValue + * @return dynamically calculated value for y-axis on the graph + */ + private long getGraphMaxValue(long maxAttributeValue) + { + long maxGraphValue = 100; + long temp = maxAttributeValue * 3/2; + if (temp > maxGraphValue) + { + long modulus = temp % 100; + maxGraphValue = temp + ( 100 - modulus); + } + + return maxGraphValue; + } + + /** + * Content Provider class for the table viewer + * @author Bhupendra Bhardwaj + */ + private class ContentProviderImpl implements IStructuredContentProvider + { + + public void inputChanged(Viewer v, Object oldInput, Object newInput) + { + + } + + public void dispose() + { + + } + + public Object[] getElements(Object parent) + { + return ((ManagedAttributeModel)parent).getAttributes(); + } + } + + /** + * Label Provider class for the table viewer + * @author Bhupendra Bhardwaj + */ + private class LabelProviderImpl extends LabelProvider implements ITableLabelProvider, + IFontProvider, + IColorProvider + { + AttributeData attribute = null; + public String getColumnText(Object element, int columnIndex) + { + String result = ""; + attribute = (AttributeData) element; + + switch (columnIndex) + { + case 0 : // attribute name column + result = ViewUtility.getDisplayText(attribute.getName()); + break; + case 1 : // attribute value column + if (attribute.getValue() != null) + result = String.valueOf(attribute.getValue()); + break; + default : + result = ""; + } + + return result; + } + + public Image getColumnImage(Object element, int columnIndex) + { + return null; + } + + public Font getFont(Object element) + { + return ApplicationRegistry.getFont(FONT_TABLE_CELL); + } + + public Color getForeground(Object element) + { + attribute = (AttributeData) element; + if (attribute.isWritable()) + return Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE); + else + return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK); + } + public Color getBackground(Object element) + { + return _form.getBackground(); + } + } + + private class DisposeListenerImpl implements DisposeListener + { + public void widgetDisposed(DisposeEvent e) + { + + } + } + + /** + * Sorter class for the table viewer. It sorts the table for according to attribute name. + * @author Bhupendra Bhardwaj + * + */ + private class ViewerSorterImpl extends ViewerSorter + { + public int compare(Viewer viewer, Object o1, Object o2) + { + AttributeData attribtue1 = (AttributeData)o1; + AttributeData attribtue2 = (AttributeData)o2; + + return collator.compare(attribtue1.getName(), attribtue2.getName()); + } + } +}
\ No newline at end of file diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ConnectionTypeTabControl.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ConnectionTypeTabControl.java new file mode 100644 index 0000000000..d891a45210 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ConnectionTypeTabControl.java @@ -0,0 +1,59 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.management.ui.views; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ServerRegistry; +import org.eclipse.swt.widgets.TabFolder; + +/** + * Controller class, which takes care of displaying appropriate information and widgets for Connections. + * This allows user to select Connections and add those to the navigation view + */ +public class ConnectionTypeTabControl extends MBeanTypeTabControl +{ + + public ConnectionTypeTabControl(TabFolder tabFolder) + { + super(tabFolder, Constants.CONNECTION); + createWidgets(); + } + + protected void createWidgets() + { + createHeaderComposite(getFormComposite()); + createButtonsComposite(getFormComposite()); + createListComposite(getFormComposite()); + } + + protected void populateList() throws Exception + { + // map should be cleared before populating it with new values + getMBeansMap().clear(); + + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer()); + java.util.List<ManagedBean> list = serverRegistry.getConnections(MBeanView.getVirtualHost()); + getListWidget().setItems(getItems(list)); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ExchangeTypeTabControl.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ExchangeTypeTabControl.java new file mode 100644 index 0000000000..ee55b251ee --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ExchangeTypeTabControl.java @@ -0,0 +1,60 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.management.ui.views; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ServerRegistry; +import org.eclipse.swt.widgets.TabFolder; + +/** + * Controller class, which takes care of displaying appropriate information and widgets for Exchanges. + * This allows user to select Exchanges and add those to the navigation view + * @author Bhupendra Bhardwaj + */ +public class ExchangeTypeTabControl extends MBeanTypeTabControl +{ + + public ExchangeTypeTabControl(TabFolder tabFolder) + { + super(tabFolder, Constants.EXCHANGE); + createWidgets(); + } + + protected void createWidgets() + { + createHeaderComposite(getFormComposite()); + createButtonsComposite(getFormComposite()); + createListComposite(getFormComposite()); + } + + protected void populateList() throws Exception + { + // map should be cleared before populating it with new values + getMBeansMap().clear(); + + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer()); + java.util.List<ManagedBean> list = serverRegistry.getExchanges(MBeanView.getVirtualHost()); + getListWidget().setItems(getItems(list)); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/INotificationViewer.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/INotificationViewer.java new file mode 100644 index 0000000000..bc560b6064 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/INotificationViewer.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.ui.views; + +import java.util.List; + +import org.apache.qpid.management.ui.model.NotificationObject; + +public interface INotificationViewer +{ + public void addNotification(NotificationObject notification); + + public void addNotification(List<NotificationObject> notificationList); +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java new file mode 100644 index 0000000000..24dfb519fd --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java @@ -0,0 +1,336 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.management.ui.views; + +import static org.apache.qpid.management.ui.Constants.BUTTON_REFRESH; +import static org.apache.qpid.management.ui.Constants.FONT_BOLD; +import static org.apache.qpid.management.ui.Constants.FONT_ITALIC; +import static org.apache.qpid.management.ui.Constants.FONT_NORMAL; + +import java.util.Collections; +import java.util.HashMap; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.apache.qpid.management.ui.model.AttributeData; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.forms.widgets.Form; +import org.eclipse.ui.forms.widgets.FormToolkit; + +/** + * Abstract class to be extended by the Controller classes for different MBean types (Connection, Queue, Exchange) + */ +public abstract class MBeanTypeTabControl +{ + private FormToolkit _toolkit = null; + private Form _form = null; + private TabFolder _tabFolder = null; + private Composite _composite = null; + private Composite _headerComposite = null; + private Composite _listComposite = null; + private Label _labelName = null; + private Label _labelDesc = null; + private Label _labelList = null; + + private org.eclipse.swt.widgets.List _list = null; + private Button _refreshButton = null; + private Button _addButton = null; + + private String _type = null; + + // maps an mbean name with the mbean object. Required to get mbean object when an mbean + // is to be added to the navigation view. + private HashMap<String, ManagedBean> _objectsMap = new HashMap<String, ManagedBean>(); + private Sorter _sorterByName = new Sorter(); + + public MBeanTypeTabControl(TabFolder tabFolder, String type) + { + _type = type; + _tabFolder = tabFolder; + _toolkit = new FormToolkit(_tabFolder.getDisplay()); + _form = _toolkit.createForm(_tabFolder); + createFormComposite(); + } + + public FormToolkit getToolkit() + { + return _toolkit; + } + + public Control getControl() + { + return _form; + } + + public String getType() + { + return _type; + } + + protected List getListWidget() + { + return _list; + } + + protected HashMap<String, ManagedBean> getMBeansMap() + { + return _objectsMap; + } + + public Sorter getMBeanNameSorter() + { + return _sorterByName; + } + + public Button getAddButton() + { + return _addButton; + } + + public Button getRefreshButton() + { + return _refreshButton; + } + + /** + * Creates the main Composite, which will contain all other Composites and Widgets + */ + protected void createFormComposite() + { + _form.getBody().setLayout(new GridLayout()); + _composite = _toolkit.createComposite(_form.getBody(), SWT.NONE); + _composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout layout = new GridLayout(); + layout.verticalSpacing = 10; + layout.horizontalSpacing = 0; + _composite.setLayout(layout); + } + + protected Composite getFormComposite() + { + return _composite; + } + + /** + * Creates the header composite, which has MBean type name and description + * @param parentComposite + */ + protected void createHeaderComposite(Composite parentComposite) + { + _headerComposite = _toolkit.createComposite(parentComposite); + _headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + GridLayout layout = new GridLayout(); + layout.verticalSpacing = 10; + layout.horizontalSpacing = 0; + _headerComposite.setLayout(layout); + + _labelName = _toolkit.createLabel(_headerComposite, "Type:", SWT.NONE); + GridData gridData = new GridData(SWT.CENTER, SWT.TOP, true, false); + _labelName.setLayoutData(gridData); + _labelName.setFont(ApplicationRegistry.getFont(FONT_BOLD)); + + _labelDesc = _toolkit.createLabel(_headerComposite, " ", SWT.NONE); + _labelDesc.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false)); + _labelDesc.setFont(ApplicationRegistry.getFont(FONT_ITALIC)); + + _headerComposite.layout(); + } + + /** + * Creates Composite, which contains the common buttons - Add and Refresh. + * @param parentComposite + */ + protected void createButtonsComposite(Composite parentComposite) + { + Composite composite = _toolkit.createComposite(parentComposite); + composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + GridLayout layout = new GridLayout(2, true); + layout.verticalSpacing = 10; + layout.horizontalSpacing = 20; + composite.setLayout(layout); + + createAddButton(composite); + createRefreshButton(composite); + } + + /** + * Creates the Add button, which adds the selected item to the navigation view + * @param parentComposite + */ + protected void createAddButton(Composite parentComposite) + { + Button _addButton = _toolkit.createButton(parentComposite, "<- Add to Navigation", SWT.PUSH); + GridData gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false); + _addButton.setLayoutData(gridData); + _addButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e) + { + if (_list.getSelectionCount() == 0) + return; + + String[] selectedItems = _list.getSelection(); + for (int i = 0; i < selectedItems.length; i++) + { + String name = selectedItems[i]; + // pass the ManagedBean to the navigation view to be added + ManagedBean mbean = _objectsMap.get(name); + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + NavigationView view = (NavigationView)window.getActivePage().findView(NavigationView.ID); + try + { + view.addManagedBean(mbean); + } + catch (Exception ex) + { + MBeanUtility.handleException(mbean, ex); + } + } + } + }); + } + + /** + * Creates the Refresh button, which gets syncs the items with the broker server + * @param parentComposite + */ + protected void createRefreshButton(Composite parentComposite) + { + Button _refreshButton = _toolkit.createButton(parentComposite, BUTTON_REFRESH, SWT.PUSH); + GridData gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false); + gridData.widthHint = 120; + _refreshButton.setLayoutData(gridData); + _refreshButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e) + { + try + { + // refresh the list from the broker server + populateList(); + } + catch (Exception ex) + { + MBeanUtility.handleException(ex); + } + } + }); + } + + /** + * Creates the Composite, which contains the items ( Connections, Exchanges or Queues) + * @param parentComposite + */ + protected void createListComposite(Composite parentComposite) + { + // Composite to contain the item list + _listComposite = _toolkit.createComposite(parentComposite); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + _listComposite.setLayoutData(gridData); + GridLayout layout = new GridLayout(); + layout.verticalSpacing = 0; + _listComposite.setLayout(layout); + + // Label for item name + _labelList = _toolkit.createLabel(_listComposite, " ", SWT.CENTER); + gridData = new GridData(SWT.CENTER, SWT.TOP, true, false, 1, 1); + _labelList.setLayoutData(gridData); + _labelList.setFont(ApplicationRegistry.getFont(FONT_NORMAL)); + + _list = new List(_listComposite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + gridData = new GridData(SWT.FILL, SWT.FILL, true, true,1, 1); + _list.setLayoutData(gridData); + + } + + /** + * This is called from MBean View to refresh the tab contents + * @throws Exception + */ + public void refresh() throws Exception + { + setLabelValues(); + populateList(); + layout(); + } + + protected void setLabelValues() + { + _labelName.setText("Type : " + _type); + _labelDesc.setText("Select the " + _type + "(s) to add in the Navigation View"); + _labelList.setText("-- List of " + _type + "s --"); + } + + protected abstract void populateList() throws Exception; + + public void layout() + { + _form.layout(true); + _form.getBody().layout(true, true); + } + + // sets the map with appropriate mbean and name + protected String[] getItems(java.util.List<ManagedBean> list) + { + if (list == null) + return new String[0]; + + Collections.sort(list, _sorterByName); + String[] items = new String[list.size()]; + int i = 0; + for (ManagedBean mbean : list) + { + items[i++] = mbean.getName(); + _objectsMap.put(mbean.getName(), mbean); + } + return items; + } + + protected class ComparatorImpl implements java.util.Comparator<AttributeData> + { + public int compare(AttributeData data1, AttributeData data2) + { + Integer int1 = Integer.parseInt(data1.getValue().toString()); + Integer int2 = Integer.parseInt(data2.getValue().toString()); + return int1.compareTo(int2) * -1; + } + } + + protected class Sorter implements java.util.Comparator<ManagedBean> + { + public int compare(ManagedBean mbean1, ManagedBean mbean2) + { + return mbean1.getName().compareTo(mbean2.getName()); + } + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java new file mode 100644 index 0000000000..5476c27871 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java @@ -0,0 +1,545 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.views; + +import java.util.HashMap; + +import static org.apache.qpid.management.ui.Constants.*; +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ManagedServer; +import org.apache.qpid.management.ui.ServerRegistry; +import org.apache.qpid.management.ui.exceptions.InfoRequiredException; +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.apache.qpid.management.ui.model.AttributeData; +import org.apache.qpid.management.ui.model.OperationData; +import org.apache.qpid.management.ui.model.OperationDataModel; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.forms.widgets.Form; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.part.ViewPart; + +/** + * MBean View create appropriate view based on the user selection on the Navigation View. + * Create TabFolder for all MBeans and displays the attribtues and method tabs. + * @author Bhupendra Bhardwaj + * + */ +public class MBeanView extends ViewPart +{ + public static final String ID = "org.apache.qpid.management.ui.mbeanView"; + private static final String CONTROLLER = "CONTROLLER"; + + private FormToolkit _toolkit = null; + private Form _form = null; + private String _formText = APPLICATION_NAME; + private static ManagedServer _server = null; + private TreeObject _selectedNode = null; + private ManagedBean _mbean = null; + private static String _virtualHostName = null; + // This map contains a TabFolder for each kind of MBean. + // TabFolder is mapped with mbeantype(Connection, Queue and Exchange) + private HashMap<String, TabFolder> tabFolderMap = new HashMap<String, TabFolder>(); + private ISelectionListener selectionListener = new SelectionListenerImpl(); + + // TabFolder to list all the mbeans for a given mbeantype(eg Connection, Queue, Exchange) + private TabFolder typeTabFolder = null; + + private TabFolder notificationTabFolder = null; + /* + * Listener for the selection events in the navigation view + */ + private class SelectionListenerImpl implements ISelectionListener + { + public void selectionChanged(IWorkbenchPart part, ISelection sel) + { + if (!(sel instanceof IStructuredSelection)) + return; + + IStructuredSelection ss = (IStructuredSelection) sel; + _selectedNode = (TreeObject)ss.getFirstElement(); + + + // mbean should be set to null. A selection done on the navigation view can be either an mbean or + // an mbeantype. For mbeantype selection(eg Connection, Queue, Exchange) _mbean will remain null. + _mbean = null; + setInvisible(); + + // If a selected node(mbean) gets unregistered from mbean server, mbeanview should + // make the tabfolber for that mbean invisible + if (_selectedNode == null) + return; + + setServer(); + refreshMBeanView(); + setFormTitle(); + } + } + + private void setFormTitle() + { + if (_mbean != null) + { + _formText = _mbean.getType(); + if ((_mbean.getVirtualHostName() != null) && (!DEFAULT_VH.equals(_mbean.getVirtualHostName())) ) + { + _formText = _formText.replaceFirst(VIRTUAL_HOST, _mbean.getVirtualHostName()); + if (_mbean.getName() != null && _mbean.getName().length() != 0) + { + _formText = _formText + ": " + _mbean.getName(); + } + } + } + else if ((_selectedNode.getVirtualHost() != null) && (!DEFAULT_VH.equals(_selectedNode.getVirtualHost()))) + { + _formText = _selectedNode.getVirtualHost(); + } + else + { + _formText = APPLICATION_NAME; + } + _form.setText(_formText); + } + + public void refreshMBeanView() + { + try + { + if (_selectedNode == null || NODE_TYPE_SERVER.equals(_selectedNode.getType()) || + NODE_TYPE_DOMAIN.equals(_selectedNode.getType()) ) + { + return; + } + else if (NODE_TYPE_TYPEINSTANCE.equals(_selectedNode.getType())) + { + // An virtual host instance is selected + refreshTypeTabFolder(typeTabFolder.getItem(0)); + } + else if (NODE_TYPE_MBEANTYPE.equals(_selectedNode.getType())) + { + refreshTypeTabFolder(_selectedNode.getName()); + } + else if (NOTIFICATIONS.equals(_selectedNode.getType())) + { + refreshNotificationPage(); + } + else if (MBEAN.equals(_selectedNode.getType())) + { + _mbean = (ManagedBean)_selectedNode.getManagedObject(); + showSelectedMBean(); + } + + _form.layout(true); + _form.getBody().layout(true, true); + } + catch(Exception ex) + { + MBeanUtility.handleException(_mbean, ex); + } + } + + /** + * Sets the managedServer based on the selection in the navigation view + * At any given time MBeanView will be displaying information for an mbean of mbeantype + * for a specifiv managed server. This server information will be used by the tab controllers + * to get server registry. + */ + private void setServer() + { + if (NODE_TYPE_SERVER.equals(_selectedNode.getType()) || + NODE_TYPE_DOMAIN.equals(_selectedNode.getType()) ) + { + _server = (ManagedServer)_selectedNode.getManagedObject(); + _virtualHostName = null; + } + else + { + TreeObject parent = _selectedNode.getParent(); + while (parent != null && !parent.getType().equals(NODE_TYPE_SERVER)) + { + parent = parent.getParent(); + } + + if (parent != null && parent.getType().equals(NODE_TYPE_SERVER)) + _server = (ManagedServer)parent.getManagedObject(); + + _virtualHostName = _selectedNode.getVirtualHost(); + } + } + + public static ManagedServer getServer() + { + return _server; + } + + public static String getVirtualHost() + { + return _virtualHostName; + } + + private void showSelectedMBean() throws Exception + { + try + { + MBeanUtility.getMBeanInfo(_mbean); + } + catch(Exception ex) + { + MBeanUtility.handleException(_mbean, ex); + return; + } + + TabFolder tabFolder = tabFolderMap.get(_mbean.getType()); + /* + * This solution can be used if there are many versions of Qpid running. Otherwise + * there is no need to create a tabFolder everytime a bean is selected. + if (tabFolder != null && !tabFolder.isDisposed()) + { + tabFolder.dispose(); + } + tabFolder = createTabFolder(); + */ + if (tabFolder == null) + { + tabFolder = createMBeanTabFolder(); + } + + int tabIndex = 0; + if (NOTIFICATIONS.equals(_selectedNode.getType())) + { + tabIndex = tabFolder.getItemCount() -1; + } + + TabItem tab = tabFolder.getItem(tabIndex); + // If folder is being set as visible after tab refresh, then the tab + // doesn't have the focus. + tabFolder.setSelection(tabIndex); + refreshTab(tab); + setVisible(tabFolder); + } + + public void createPartControl(Composite parent) + { + // Create the Form + _toolkit = new FormToolkit(parent.getDisplay()); + _form = _toolkit.createForm(parent); + _form.getBody().setLayout(new FormLayout()); + _form.setText(APPLICATION_NAME); + + // Add selection listener for selection events in the Navigation view + getSite().getPage().addSelectionListener(NavigationView.ID, selectionListener); + + // Add mbeantype TabFolder. This will list all the mbeans under a mbeantype (eg Queue, Exchange). + // Using this list mbeans will be added in the navigation view + createMBeanTypeTabFolder(); + + createNotificationsTabFolder(); + } + + private TabFolder createMBeanTabFolder() + { + TabFolder tabFolder = new TabFolder(_form.getBody(), SWT.NONE); + FormData layoutData = new FormData(); + layoutData.left = new FormAttachment(0); + layoutData.top = new FormAttachment(0); + layoutData.right = new FormAttachment(100); + layoutData.bottom = new FormAttachment(100); + tabFolder.setLayoutData(layoutData); + tabFolder.setVisible(false); + + createAttributesTab(tabFolder); + createOperationTabs(tabFolder); + createNotificationsTab(tabFolder); + + tabFolder.addListener(SWT.Selection, new Listener() + { + public void handleEvent(Event evt) + { + TabItem tab = (TabItem)evt.item; + refreshTab(tab); + } + }); + + tabFolderMap.put(_mbean.getType(), tabFolder); + return tabFolder; + } + + private void refreshTab(TabItem tab) + { + // We can avoid refreshing the attributes tab because it's control + // already contains the required values. But it is added for now and + // will remove if there is any performance issue or any other issue. + // The operations control should be refreshed because there is only one + // controller for all operations tab. + // The Notifications control needs to refresh with latest set of notifications + + if (tab == null) + return; + + TabControl controller = (TabControl)tab.getData(CONTROLLER); + controller.refresh(_mbean); + } + + public void setFocus() + { + //_form.setFocus(); + } + + public void dispose() + { + _toolkit.dispose(); + super.dispose(); + } + + private void createAttributesTab(TabFolder tabFolder) + { + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); + if (serverRegistry.getAttributeModel(_mbean).getCount() == 0) + { + return; + } + + TabItem tab = new TabItem(tabFolder, SWT.NONE); + tab.setText(ATTRIBUTES); + AttributesTabControl controller = new AttributesTabControl(tabFolder); + tab.setControl(controller.getControl()); + tab.setData(CONTROLLER, controller); + } + + private void createOperationTabs(TabFolder tabFolder) + { + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); + int operationsCount = serverRegistry.getOperationModel(_mbean).getCount(); + if (operationsCount == 0) + { + return; + } + + OperationDataModel operationModel = serverRegistry.getOperationModel(_mbean); + for (OperationData operationData : operationModel.getOperations()) + { + TabItem operationTab = new TabItem(tabFolder, SWT.NONE); + operationTab.setText(ViewUtility.getDisplayText(operationData.getName())); + operationTab.setData(operationData); + OperationTabControl control = new OperationTabControl(tabFolder, operationData); + operationTab.setData(CONTROLLER, control); + operationTab.setControl(control.getControl()); + } + } + + private void createNotificationsTab(TabFolder tabFolder) + { + NotificationsTabControl controller = new NotificationsTabControl(tabFolder); + + TabItem tab = new TabItem(tabFolder, SWT.NONE); + tab.setText(NOTIFICATIONS); + tab.setData(CONTROLLER, controller); + tab.setControl(controller.getControl()); + } + + /** + * For the EditAttribtue Action. Invoking this from action is same as clicking + * "EditAttribute" button from Attribute tab. + */ + public void editAttribute() throws Exception + { + if (_mbean == null) + throw new InfoRequiredException("Please select the managed object and then attribute to be edited"); + + String name = (_mbean.getName() != null) ? _mbean.getName() : _mbean.getType(); + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); + if (serverRegistry.getAttributeModel(_mbean).getCount() == 0) + { + throw new InfoRequiredException("There are no attributes to be edited for " + name); + } + + TabFolder tabFolder = tabFolderMap.get(_mbean.getType()); + int index = tabFolder.getSelectionIndex(); + if (index != 0) + { + tabFolder.setSelection(0); + throw new InfoRequiredException("Please select the attribute to be edited"); + } + + TabItem tab = tabFolder.getItem(0); + AttributesTabControl tabControl = (AttributesTabControl)tab.getData(CONTROLLER); + AttributeData attribute = tabControl.getSelectionAttribute(); + if (attribute == null) + throw new InfoRequiredException("Please select the attribute to be edited"); + + tabControl.createDetailsPopup(attribute); + } + + /** + * Creates TabFolder and tabs for each mbeantype (eg Connection, Queue, Exchange) + */ + private void createMBeanTypeTabFolder() + { + typeTabFolder = new TabFolder(_form.getBody(), SWT.NONE); + FormData layoutData = new FormData(); + layoutData.left = new FormAttachment(0); + layoutData.top = new FormAttachment(0); + layoutData.right = new FormAttachment(100); + layoutData.bottom = new FormAttachment(100); + typeTabFolder.setLayoutData(layoutData); + typeTabFolder.setVisible(false); + + TabItem tab = new TabItem(typeTabFolder, SWT.NONE); + tab.setText(CONNECTION); + MBeanTypeTabControl controller = new ConnectionTypeTabControl(typeTabFolder); + tab.setData(CONTROLLER, controller); + tab.setControl(controller.getControl()); + + tab = new TabItem(typeTabFolder, SWT.NONE); + tab.setText(EXCHANGE); + controller = new ExchangeTypeTabControl(typeTabFolder); + tab.setData(CONTROLLER, controller); + tab.setControl(controller.getControl()); + + tab = new TabItem(typeTabFolder, SWT.NONE); + tab.setText(QUEUE); + controller = new QueueTypeTabControl(typeTabFolder); + tab.setData(CONTROLLER, controller); + tab.setControl(controller.getControl()); + + typeTabFolder.addListener(SWT.Selection, new Listener() + { + public void handleEvent(Event evt) + { + TabItem tab = (TabItem)evt.item; + try + { + refreshTypeTabFolder(tab); + } + catch (Exception ex) + { + MBeanUtility.handleException(ex); + } + } + }); + } + + private void createNotificationsTabFolder() + { + notificationTabFolder = new TabFolder(_form.getBody(), SWT.NONE); + FormData layoutData = new FormData(); + layoutData.left = new FormAttachment(0); + layoutData.top = new FormAttachment(0); + layoutData.right = new FormAttachment(100); + layoutData.bottom = new FormAttachment(100); + notificationTabFolder.setLayoutData(layoutData); + notificationTabFolder.setVisible(false); + + VHNotificationsTabControl controller = new VHNotificationsTabControl(notificationTabFolder); + TabItem tab = new TabItem(notificationTabFolder, SWT.NONE); + tab.setText(NOTIFICATIONS); + tab.setData(CONTROLLER, controller); + tab.setControl(controller.getControl()); + } + + private void refreshNotificationPage() + { + TabItem tab = notificationTabFolder.getItem(0); + VHNotificationsTabControl controller = (VHNotificationsTabControl)tab.getData(CONTROLLER); + controller.refresh(); + notificationTabFolder.setVisible(true); + } + + /** + * Refreshes the Selected mbeantype tab. The control lists all the available mbeans + * for an mbeantype(eg Queue, Exchange etc) + * @param tab + * @throws Exception + */ + private void refreshTypeTabFolder(TabItem tab) throws Exception + { + if (tab == null) + { + return; + } + typeTabFolder.setSelection(tab); + MBeanTypeTabControl controller = (MBeanTypeTabControl)tab.getData(CONTROLLER); + controller.refresh(); + typeTabFolder.setVisible(true); + } + + private void refreshTypeTabFolder(String type) throws Exception + { + if (CONNECTION.equals(type)) + { + refreshTypeTabFolder(typeTabFolder.getItem(0)); + } + else if (EXCHANGE.equals(type)) + { + refreshTypeTabFolder(typeTabFolder.getItem(1)); + } + else if (QUEUE.equals(type)) + { + refreshTypeTabFolder(typeTabFolder.getItem(2)); + } + } + + /** + * hides other folders and makes the given one visible. + * @param tabFolder + */ + private void setVisible(TabFolder tabFolder) + { + for (TabFolder folder : tabFolderMap.values()) + { + if (folder == tabFolder) + folder.setVisible(true); + else + folder.setVisible(false); + } + } + + private void setInvisible() + { + for (TabFolder folder : tabFolderMap.values()) + { + folder.setVisible(false); + } + + if (typeTabFolder != null) + { + typeTabFolder.setVisible(false); + } + + if (notificationTabFolder != null) + { + notificationTabFolder.setVisible(false); + } + } + +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java new file mode 100644 index 0000000000..1da13a9b56 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java @@ -0,0 +1,1253 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.views; + +import static org.apache.qpid.management.ui.Constants.*; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ManagedServer; +import org.apache.qpid.management.ui.ServerRegistry; +import org.apache.qpid.management.ui.exceptions.InfoRequiredException; +import org.apache.qpid.management.ui.jmx.JMXServerRegistry; +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.eclipse.jface.preference.PreferenceStore; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.ITreeViewerListener; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeExpansionEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.part.ViewPart; + +/** + * Navigation View for navigating the managed servers and managed beans on + * those servers + * @author Bhupendra Bhardwaj + */ +public class NavigationView extends ViewPart +{ + public static final String ID = "org.apache.qpid.management.ui.navigationView"; + public static final String INI_FILENAME = System.getProperty("user.home") + File.separator + "qpidManagementConsole.ini"; + + private static final String INI_SERVERS = "Servers"; + private static final String INI_QUEUES = QUEUE + "s"; + private static final String INI_CONNECTIONS = CONNECTION + "s"; + private static final String INI_EXCHANGES = EXCHANGE + "s"; + + private TreeViewer _treeViewer = null; + private TreeObject _rootNode = null; + private TreeObject _serversRootNode = null; + + private PreferenceStore _preferences; + // Map of connected servers + private HashMap<ManagedServer, TreeObject> _managedServerMap = new HashMap<ManagedServer, TreeObject>(); + + private void createTreeViewer(Composite parent) + { + _treeViewer = new TreeViewer(parent); + _treeViewer.setContentProvider(new ContentProviderImpl()); + _treeViewer.setLabelProvider(new LabelProviderImpl()); + _treeViewer.setSorter(new ViewerSorterImpl()); + + // layout the tree viewer below the label field, to cover the area + GridData layoutData = new GridData(); + layoutData = new GridData(); + layoutData.grabExcessHorizontalSpace = true; + layoutData.grabExcessVerticalSpace = true; + layoutData.horizontalAlignment = GridData.FILL; + layoutData.verticalAlignment = GridData.FILL; + _treeViewer.getControl().setLayoutData(layoutData); + _treeViewer.setUseHashlookup(true); + + createListeners(); + } + + /** + * Creates listeners for the JFace treeviewer + */ + private void createListeners() + { + _treeViewer.addDoubleClickListener(new IDoubleClickListener() + { + public void doubleClick(DoubleClickEvent event) + { + IStructuredSelection ss = (IStructuredSelection) event.getSelection(); + if ((ss == null) || (ss.getFirstElement() == null)) + { + return; + } + + boolean state = _treeViewer.getExpandedState(ss.getFirstElement()); + _treeViewer.setExpandedState(ss.getFirstElement(), !state); + } + }); + + _treeViewer.addTreeListener(new ITreeViewerListener() + { + public void treeExpanded(TreeExpansionEvent event) + { + _treeViewer.setExpandedState(event.getElement(), true); + // Following will cause the selection event to be sent, so commented + // _treeViewer.setSelection(new StructuredSelection(event.getElement())); + _treeViewer.refresh(); + } + + public void treeCollapsed(TreeExpansionEvent event) + { + _treeViewer.setExpandedState(event.getElement(), false); + _treeViewer.refresh(); + } + }); + + // This listener is for popup menu, which pops up if a queue,exchange or connection is selected + // with right click. + _treeViewer.getTree().addListener(SWT.MenuDetect, new Listener() + { + Display display = getSite().getShell().getDisplay(); + final Shell shell = new Shell(display); + + public void handleEvent(Event event) + { + Tree widget = (Tree) event.widget; + TreeItem[] items = widget.getSelection(); + if (items == null) + { + return; + } + + // Get the selected node + final TreeObject selectedNode = (TreeObject) items[0].getData(); + final TreeObject parentNode = selectedNode.getParent(); + + // This popup is only for mbeans and only connection,exchange and queue types + if ((parentNode == null) || !MBEAN.equals(selectedNode.getType()) + || !(CONNECTION.equals(parentNode.getName()) || QUEUE.equals(parentNode.getName()) + || EXCHANGE.equals(parentNode.getName()))) + { + return; + } + + Menu menu = new Menu(shell, SWT.POP_UP); + MenuItem item = new MenuItem(menu, SWT.PUSH); + // Add the action item, which will remove the node from the tree if selected + item.setText(ACTION_REMOVE_MBEANNODE); + item.addListener(SWT.Selection, new Listener() + { + public void handleEvent(Event e) + { + removeManagedObject(parentNode, (ManagedBean) selectedNode.getManagedObject()); + _treeViewer.refresh(); + // set the selection to the parent node + _treeViewer.setSelection(new StructuredSelection(parentNode)); + } + }); + menu.setLocation(event.x, event.y); + menu.setVisible(true); + while (!menu.isDisposed() && menu.isVisible()) + { + if (!display.readAndDispatch()) + { + display.sleep(); + } + } + + menu.dispose(); + } + }); + } + + /** + * Creates Qpid Server connection using JMX RMI protocol + * @param server + * @throws Exception + */ + private void createRMIServerConnection(ManagedServer server) throws Exception + { + // Currently Qpid Management Console only supports JMX MBeanServer + ServerRegistry serverRegistry = new JMXServerRegistry(server); + ApplicationRegistry.addServer(server, serverRegistry); + } + + /** + * Adds a new server node in the navigation view if server connection is successful. + * @param transportProtocol + * @param host + * @param port + * @param domain + * @throws Exception + */ + public void addNewServer(String transportProtocol, String host, int port, String domain, String user, String pwd) + throws Exception + { + String serverAddress = host + ":" + port; + String url = null; + ManagedServer managedServer = new ManagedServer(host, port, domain, user, pwd); + + if ("RMI".equals(transportProtocol)) + { + url = managedServer.getUrl(); + List<TreeObject> list = _serversRootNode.getChildren(); + for (TreeObject node : list) + { + ManagedServer nodeServer = (ManagedServer)node.getManagedObject(); + if (url.equals(nodeServer.getUrl())) + { + // Server is already in the list of added servers, so now connect it. + // Set the server node as selected and then connect it. + _treeViewer.setSelection(new StructuredSelection(node)); + reconnect(user, pwd); + + return; + } + } + + // The server is not in the list of already added servers, so now connect and add it. + managedServer.setName(serverAddress); + createRMIServerConnection(managedServer); + } + else + { + throw new InfoRequiredException(transportProtocol + " transport is not supported"); + } + + // Server connection is successful. Now add the server in the tree + TreeObject serverNode = new TreeObject(serverAddress, NODE_TYPE_SERVER); + serverNode.setManagedObject(managedServer); + _serversRootNode.addChild(serverNode); + + // Add server in the connected server map + _managedServerMap.put(managedServer, serverNode); + + // populate the server tree + try + { + populateServer(serverNode); + } + catch (SecurityException ex) + { + disconnect(managedServer); + throw ex; + } + + // Add the Queue/Exchanges/Connections from config file into the navigation tree + addConfiguredItems(managedServer); + + _treeViewer.refresh(); + + // save server address in file + addServerInConfigFile(serverAddress); + } + + /** + * Create the config file, if it doesn't already exist. + * Exits the application if the file could not be created. + */ + private void createConfigFile() + { + File file = new File(INI_FILENAME); + try + { + if (!file.exists()) + { + file.createNewFile(); + } + } + catch (IOException ex) + { + System.out.println("Could not write to the file " + INI_FILENAME); + System.out.println(ex); + System.exit(1); + } + } + + /** + * Server addresses are stored in a file. When user launches the application again, the + * server addresses are picked up from the file and shown in the navigfation view. This method + * adds the server address in a file, when a new server is added in the navigation view. + * @param serverAddress + */ + private void addServerInConfigFile(String serverAddress) + { + // Check if the address already exists + List<String> list = getServerListFromFile(); + if ((list != null) && list.contains(serverAddress)) + { + return; + } + + // Get the existing server list and add to that + String servers = _preferences.getString(INI_SERVERS); + String value = (servers.length() != 0) ? (servers + "," + serverAddress) : serverAddress; + _preferences.putValue(INI_SERVERS, value); + try + { + _preferences.save(); + } + catch (IOException ex) + { + System.err.println("Could not add " + serverAddress + " in " + INI_SERVERS + " (" + INI_FILENAME + ")"); + System.out.println(ex); + } + } + + /** + * Adds the item (Queue/Exchange/Connection) to the config file + * @param server + * @param virtualhost + * @param type - (Queue or Exchange or Connection) + * @param name - item name + */ + private void addItemInConfigFile(TreeObject node) + { + ManagedBean mbean = (ManagedBean) node.getManagedObject(); + String server = mbean.getServer().getName(); + String virtualhost = mbean.getVirtualHostName(); + String type = node.getParent().getName() + "s"; + String name = node.getName(); + String itemKey = server + "." + virtualhost + "." + type; + + // Check if the item already exists in the config file + List<String> list = getConfiguredItemsFromFile(itemKey); + if ((list != null) && list.contains(name)) + { + return; + } + + // Add this item to the existing list of items + String items = _preferences.getString(itemKey); + String value = (items.length() != 0) ? (items + "," + name) : name; + _preferences.putValue(itemKey, value); + try + { + _preferences.save(); + } + catch (IOException ex) + { + System.err.println("Could not add " + name + " in " + itemKey + " (" + INI_FILENAME + ")"); + System.out.println(ex); + } + } + + private void removeItemFromConfigFile(TreeObject node) + { + ManagedBean mbean = (ManagedBean) node.getManagedObject(); + String server = mbean.getServer().getName(); + String vHost = mbean.getVirtualHostName(); + String type = node.getParent().getName() + "s"; + String itemKey = server + "." + vHost + "." + type; + + List<String> list = getConfiguredItemsFromFile(itemKey); + if (list.contains(node.getName())) + { + list.remove(node.getName()); + String value = ""; + for (String item : list) + { + value += item + ","; + } + + value = (value.lastIndexOf(",") != -1) ? value.substring(0, value.lastIndexOf(",")) : value; + + _preferences.putValue(itemKey, value); + try + { + _preferences.save(); + } + catch (IOException ex) + { + System.err.println("Error in updating the config file " + INI_FILENAME); + System.out.println(ex); + } + } + } + + /** + * Queries the qpid server for MBeans and populates the navigation view with all MBeans for + * the given server node. + * @param serverNode + */ + private void populateServer(TreeObject serverNode) throws Exception + { + ManagedServer server = (ManagedServer) serverNode.getManagedObject(); + String domain = server.getDomain(); + if (!domain.equals(ALL)) + { + TreeObject domainNode = new TreeObject(domain, NODE_TYPE_DOMAIN); + domainNode.setParent(serverNode); + + populateDomain(domainNode); + } + else + { + List<TreeObject> domainList = new ArrayList<TreeObject>(); + List<String> domains = MBeanUtility.getAllDomains(server); + + for (String domainName : domains) + { + TreeObject domainNode = new TreeObject(domainName, NODE_TYPE_DOMAIN); + domainNode.setParent(serverNode); + + domainList.add(domainNode); + populateDomain(domainNode); + } + } + } + + /** + * Queries the Qpid Server and populates the given domain node with all MBeans undser that domain. + * @param domain + * @throws IOException + * @throws Exception + */ + @SuppressWarnings("unchecked") + private void populateDomain(TreeObject domain) throws IOException, Exception + { + ManagedServer server = (ManagedServer) domain.getParent().getManagedObject(); + + // Now populate the mbenas under those types + List<ManagedBean> mbeans = MBeanUtility.getManagedObjectsForDomain(server, domain.getName()); + for (ManagedBean mbean : mbeans) + { + mbean.setServer(server); + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(server); + serverRegistry.addManagedObject(mbean); + + // Add all mbeans other than Connections, Exchanges and Queues. Because these will be added + // manually by selecting from MBeanView + if (!(mbean.isConnection() || mbean.isExchange() || mbean.isQueue())) + { + addManagedBean(domain, mbean); + } + } + // To make it work with the broker without virtual host implementation. + // This will add the default nodes to the domain node + for (TreeObject child : domain.getChildren()) + { + if (!child.getName().startsWith(VIRTUAL_HOST)) + { + addDefaultNodes(domain); + } + + break; + } + } + + /** + * Add these three types - Connection, Exchange, Queue + * By adding these, these will always be available, even if there are no mbeans under thse types + * This is required because, the mbeans will be added from mbeanview, by selecting from the list + * @param parent Node + */ + private void addDefaultNodes(TreeObject parent) + { + TreeObject typeChild = new TreeObject(CONNECTION, NODE_TYPE_MBEANTYPE); + typeChild.setParent(parent); + typeChild.setVirtualHost(parent.getVirtualHost()); + typeChild = new TreeObject(EXCHANGE, NODE_TYPE_MBEANTYPE); + typeChild.setParent(parent); + typeChild.setVirtualHost(parent.getVirtualHost()); + typeChild = new TreeObject(QUEUE, NODE_TYPE_MBEANTYPE); + typeChild.setParent(parent); + typeChild.setVirtualHost(parent.getVirtualHost()); + + // Add common notification node for virtual host + TreeObject notificationNode = new TreeObject(NOTIFICATIONS, NOTIFICATIONS); + notificationNode.setParent(parent); + notificationNode.setVirtualHost(parent.getVirtualHost()); + } + + /** + * Checks if a particular mbeantype is already there in the navigation view for a domain. + * This is used while populating domain with mbeans. + * @param parent + * @param typeName + * @return Node if given mbeantype already exists, otherwise null + */ + private TreeObject getMBeanTypeNode(TreeObject parent, String typeName) + { + List<TreeObject> childNodes = parent.getChildren(); + for (TreeObject child : childNodes) + { + if ((NODE_TYPE_MBEANTYPE.equals(child.getType()) || NODE_TYPE_TYPEINSTANCE.equals(child.getType())) + && typeName.equals(child.getName())) + { + return child; + } + } + + return null; + } + + private boolean doesMBeanNodeAlreadyExist(TreeObject typeNode, String mbeanName) + { + List<TreeObject> childNodes = typeNode.getChildren(); + for (TreeObject child : childNodes) + { + if (MBEAN.equals(child.getType()) && mbeanName.equals(child.getName())) + { + return true; + } + } + + return false; + } + + /** + * Adds the given MBean to the given domain node. Creates Notification node for the MBean. + * sample ObjectNames - + * org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=localhost + * org.apache.qpid:type=VirtualHost.Queue,VirtualHost=test,name=ping_1 + * @param domain + * @param mbean + * @throws Exception + */ + private void addManagedBean(TreeObject domain, ManagedBean mbean) // throws Exception + { + String name = mbean.getName(); + // Split the mbean type into array of Strings, to create hierarchy + // eg. type=VirtualHost.VirtualHostManager,VirtualHost=localhost will be: + // localhost->VirtualHostManager + // eg. type=org.apache.qpid:type=VirtualHost.Queue,VirtualHost=test,name=ping will be: + // test->Queue->ping + String[] types = mbean.getType().split("\\."); + TreeObject typeNode = null; + TreeObject parentNode = domain; + + // Run this loop till all nodes(hierarchy) for this mbean are created. This loop only creates + // all the required parent nodes for the mbean + for (int i = 0; i < types.length; i++) + { + String type = types[i]; + String valueOftype = mbean.getProperty(type); + // If value is not null, then there will be a parent node for this mbean + // eg. for type=VirtualHost the value is "test" + typeNode = getMBeanTypeNode(parentNode, type); + + // create the type node if not already created + if (typeNode == null) + { + // If the ObjectName doesn't have name property, that means there will be only one instance + // of this mbean for given "type". So there will be no type node created for this mbean. + if ((name == null) && (i == (types.length - 1))) + { + break; + } + + // create a node for "type" + typeNode = createTypeNode(parentNode, type); + if (!type.equals(VIRTUAL_HOST)) + { + typeNode.setVirtualHost(mbean.getVirtualHostName()); + } + } + + // now type node create becomes the parent node for next node in hierarchy + parentNode = typeNode; + + /* + * Now create instances node for this type if value exists. + */ + if (valueOftype == null) + { + // No instance node will be created when value is null (eg type=Queue) + break; + } + + // For different virtual hosts, the nodes with given value will be created. + // eg type=VirtualHost, value=test + typeNode = getMBeanTypeNode(parentNode, valueOftype); + if (typeNode == null) + { + typeNode = createTypeInstanceNode(parentNode, valueOftype); + typeNode.setVirtualHost(mbean.getVirtualHostName()); + + // Create default nodes for VHost instances + if (type.equals(VIRTUAL_HOST)) + { + addDefaultNodes(typeNode); + } + } + + parentNode = typeNode; + } + + if (typeNode == null) + { + typeNode = parentNode; + } + + // Check if an MBean is already added + if (doesMBeanNodeAlreadyExist(typeNode, name)) + { + return; + } + + // Add the mbean node now + TreeObject mbeanNode = new TreeObject(mbean); + mbeanNode.setParent(typeNode); + + // Add the mbean to the config file + if (mbean.isQueue() || mbean.isExchange() || mbean.isConnection()) + { + addItemInConfigFile(mbeanNode); + } + + // Add notification node + // TODO: show this only if the mbean sends any notification + //TreeObject notificationNode = new TreeObject(NOTIFICATION, NOTIFICATION); + //notificationNode.setParent(mbeanNode); + } + + private TreeObject createTypeNode(TreeObject parent, String name) + { + TreeObject typeNode = new TreeObject(name, NODE_TYPE_MBEANTYPE); + typeNode.setParent(parent); + + return typeNode; + } + + private TreeObject createTypeInstanceNode(TreeObject parent, String name) + { + TreeObject typeNode = new TreeObject(name, NODE_TYPE_TYPEINSTANCE); + typeNode.setParent(parent); + + return typeNode; + } + + /** + * Removes all the child nodes of the given parent node. Used when closing a server. + * @param parent + */ + private void removeManagedObject(TreeObject parent) + { + List<TreeObject> list = parent.getChildren(); + for (TreeObject child : list) + { + removeManagedObject(child); + } + + list.clear(); + } + + /** + * Removes the mbean from the tree + * @param parent + * @param mbean + */ + private void removeManagedObject(TreeObject parent, ManagedBean mbean) + { + List<TreeObject> list = parent.getChildren(); + TreeObject objectToRemove = null; + for (TreeObject child : list) + { + if (MBEAN.equals(child.getType())) + { + String name = (mbean.getName() != null) ? mbean.getName() : mbean.getType(); + if (child.getName().equals(name)) + { + objectToRemove = child; + + break; + } + } + else + { + removeManagedObject(child, mbean); + } + } + + if (objectToRemove != null) + { + list.remove(objectToRemove); + removeItemFromConfigFile(objectToRemove); + } + + } + + /** + * Closes the Qpid server connection + */ + public void disconnect() throws Exception + { + TreeObject selectedNode = getSelectedServerNode(); + ManagedServer managedServer = (ManagedServer) selectedNode.getManagedObject(); + disconnect(managedServer); + } + + private void disconnect(ManagedServer managedServer) throws Exception + { + if (!_managedServerMap.containsKey(managedServer)) + { + return; + } + + // Close server connection + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(managedServer); + if (serverRegistry == null) // server connection is already closed + { + return; + } + + serverRegistry.closeServerConnection(); + // Add server to the closed server list and the worker thread will remove the server from required places. + ApplicationRegistry.serverConnectionClosed(managedServer); + } + + /** + * Connects the selected server node + * @throws Exception + */ + public void reconnect(String user, String password) throws Exception + { + TreeObject selectedNode = getSelectedServerNode(); + ManagedServer managedServer = (ManagedServer) selectedNode.getManagedObject(); + if (_managedServerMap.containsKey(managedServer)) + { + throw new InfoRequiredException("Server " + managedServer.getName() + " is already connected"); + } + + managedServer.setUser(user); + managedServer.setPassword(password); + createRMIServerConnection(managedServer); + + // put the server in the managed server map + _managedServerMap.put(managedServer, selectedNode); + + try + { + // populate the server tree now + populateServer(selectedNode); + } + catch (SecurityException ex) + { + disconnect(managedServer); + throw ex; + } + + + // Add the Queue/Exchanges/Connections from config file into the navigation tree + addConfiguredItems(managedServer); + + _treeViewer.refresh(); + } + + /** + * Adds the items(queues/exchanges/connectins) from config file to the server tree + * @param server + */ + private void addConfiguredItems(ManagedServer server) + { + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(server); + List<String> list = serverRegistry.getVirtualHosts(); + for (String virtualHost : list) + { + // Add Queues + String itemKey = server.getName() + "." + virtualHost + "." + INI_QUEUES; + List<String> items = getConfiguredItemsFromFile(itemKey); + List<ManagedBean> mbeans = serverRegistry.getQueues(virtualHost); + addConfiguredItems(items, mbeans); + + // Add Exchanges + itemKey = server.getName() + "." + virtualHost + "." + INI_EXCHANGES; + items = getConfiguredItemsFromFile(itemKey); + mbeans = serverRegistry.getExchanges(virtualHost); + addConfiguredItems(items, mbeans); + + // Add Connections + itemKey = server.getName() + "." + virtualHost + "." + INI_CONNECTIONS; + items = getConfiguredItemsFromFile(itemKey); + mbeans = serverRegistry.getConnections(virtualHost); + addConfiguredItems(items, mbeans); + } + } + + /** + * Gets the mbeans corresponding to the items and adds those to the navigation tree + * @param items + * @param mbeans + */ + private void addConfiguredItems(List<String> items, List<ManagedBean> mbeans) + { + if ((items == null) || (items.isEmpty() | (mbeans == null)) || mbeans.isEmpty()) + { + return; + } + + for (String item : items) + { + for (ManagedBean mbean : mbeans) + { + if (item.equals(mbean.getName())) + { + addManagedBean(mbean); + + break; + } + } + } + } + + /** + * Closes the Qpid server connection if not already closed and removes the server node from the navigation view and + * also from the ini file stored in the system. + * @throws Exception + */ + public void removeServer() throws Exception + { + disconnect(); + + // Remove from the Tree + String serverNodeName = getSelectedServerNode().getName(); + List<TreeObject> list = _serversRootNode.getChildren(); + TreeObject objectToRemove = null; + for (TreeObject child : list) + { + if (child.getName().equals(serverNodeName)) + { + objectToRemove = child; + + break; + } + } + + if (objectToRemove != null) + { + list.remove(objectToRemove); + } + + _treeViewer.refresh(); + + // Remove from the ini file + removeServerFromConfigFile(serverNodeName); + } + + private void removeServerFromConfigFile(String serverNodeName) + { + List<String> serversList = getServerListFromFile(); + serversList.remove(serverNodeName); + + String value = ""; + for (String item : serversList) + { + value += item + ","; + } + + value = (value.lastIndexOf(",") != -1) ? value.substring(0, value.lastIndexOf(",")) : value; + + _preferences.putValue(INI_SERVERS, value); + + try + { + _preferences.save(); + } + catch (IOException ex) + { + System.err.println("Error in updating the config file " + INI_FILENAME); + System.out.println(ex); + } + } + + /** + * @return the server addresses from the ini file + * @throws Exception + */ + private List<String> getServerListFromFile() + { + return getConfiguredItemsFromFile(INI_SERVERS); + } + + /** + * Returns the list of items from the config file. + * sample ini file: + * Servers=localhost:8999,127.0.0.1:8999 + * localhost.virtualhost1.Queues=queue1,queue2 + * localhost.virtualhost1.Exchanges=exchange1,exchange2 + * localhost.virtualhost2.Connections=conn1 + * @param key + * @return + */ + private List<String> getConfiguredItemsFromFile(String key) + { + List<String> list = new ArrayList<String>(); + String items = _preferences.getString(key); + if (items.length() != 0) + { + String[] array = items.split(","); + for (String item : array) + { + list.add(item); + } + } + + return list; + } + + public TreeObject getSelectedServerNode() throws Exception + { + IStructuredSelection ss = (IStructuredSelection) _treeViewer.getSelection(); + TreeObject selectedNode = (TreeObject) ss.getFirstElement(); + if (ss.isEmpty() || (selectedNode == null) || (!selectedNode.getType().equals(NODE_TYPE_SERVER))) + { + throw new InfoRequiredException("Please select the server"); + } + + return selectedNode; + } + + /** + * This is a callback that will allow us to create the viewer and initialize + * it. + */ + public void createPartControl(Composite parent) + { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout gridLayout = new GridLayout(); + gridLayout.marginHeight = 2; + gridLayout.marginWidth = 2; + gridLayout.horizontalSpacing = 0; + gridLayout.verticalSpacing = 2; + composite.setLayout(gridLayout); + + createTreeViewer(composite); + _rootNode = new TreeObject("ROOT", "ROOT"); + _serversRootNode = new TreeObject(NAVIGATION_ROOT, "ROOT"); + _serversRootNode.setParent(_rootNode); + + _treeViewer.setInput(_rootNode); + // set viewer as selection event provider for MBeanView + getSite().setSelectionProvider(_treeViewer); + + // Start worker thread to refresh tree for added or removed objects + (new Thread(new Worker())).start(); + + createConfigFile(); + _preferences = new PreferenceStore(INI_FILENAME); + + try + { + _preferences.load(); + } + catch (IOException ex) + { + System.out.println(ex); + } + + // load the list of servers already added from file + List<String> serversList = getServerListFromFile(); + if (serversList != null) + { + for (String serverAddress : serversList) + { + String[] server = serverAddress.split(":"); + ManagedServer managedServer = new ManagedServer(server[0], Integer.parseInt(server[1]), "org.apache.qpid"); + TreeObject serverNode = new TreeObject(serverAddress, NODE_TYPE_SERVER); + serverNode.setManagedObject(managedServer); + _serversRootNode.addChild(serverNode); + } + } + + _treeViewer.refresh(); + + } + + /** + * Passing the focus request to the viewer's control. + */ + public void setFocus() + { } + + public void refresh() + { + _treeViewer.refresh(); + } + + /** + * Content provider class for the tree viewer + */ + private class ContentProviderImpl implements ITreeContentProvider + { + public Object[] getElements(Object parent) + { + return getChildren(parent); + } + + public Object[] getChildren(final Object parentElement) + { + final TreeObject node = (TreeObject) parentElement; + + return node.getChildren().toArray(new TreeObject[0]); + } + + public Object getParent(final Object element) + { + final TreeObject node = (TreeObject) element; + + return node.getParent(); + } + + public boolean hasChildren(final Object element) + { + final TreeObject node = (TreeObject) element; + + return !node.getChildren().isEmpty(); + } + + public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) + { + // Do nothing + } + + public void dispose() + { + // Do nothing + } + } + + /** + * Label provider class for the tree viewer + */ + private class LabelProviderImpl extends LabelProvider implements IFontProvider + { + public Image getImage(Object element) + { + TreeObject node = (TreeObject) element; + if (node.getType().equals(NOTIFICATIONS)) + { + return ApplicationRegistry.getImage(NOTIFICATION_IMAGE); + } + else if (!node.getType().equals(MBEAN)) + { + if (_treeViewer.getExpandedState(node)) + { + return ApplicationRegistry.getImage(OPEN_FOLDER_IMAGE); + } + else + { + return ApplicationRegistry.getImage(CLOSED_FOLDER_IMAGE); + } + + } + else + { + return ApplicationRegistry.getImage(MBEAN_IMAGE); + } + } + + public String getText(Object element) + { + TreeObject node = (TreeObject) element; + if (node.getType().equals(NODE_TYPE_MBEANTYPE)) + { + return node.getName() + "s"; + } + else + { + return node.getName(); + } + } + + public Font getFont(Object element) + { + TreeObject node = (TreeObject) element; + if (node.getType().equals(NODE_TYPE_SERVER)) + { + if (node.getChildren().isEmpty()) + { + return ApplicationRegistry.getFont(FONT_NORMAL); + } + else + { + return ApplicationRegistry.getFont(FONT_BOLD); + } + } + + return ApplicationRegistry.getFont(FONT_NORMAL); + } + } // End of LabelProviderImpl + + private class ViewerSorterImpl extends ViewerSorter + { + public int category(Object element) + { + TreeObject node = (TreeObject) element; + if (node.getType().equals(MBEAN)) + { + return 1; + } + if (node.getType().equals(NOTIFICATIONS)) + { + return 2; + } + return 3; + } + } + + /** + * Worker thread, which keeps looking for new ManagedObjects to be added and + * unregistered objects to be removed from the tree. + * @author Bhupendra Bhardwaj + */ + private class Worker implements Runnable + { + public void run() + { + while (true) + { + if (!_managedServerMap.isEmpty()) + { + refreshRemovedObjects(); + refreshClosedServerConnections(); + } + + try + { + Thread.sleep(3000); + } + catch (Exception ex) + { } + + } // end of while loop + } // end of run method. + } // end of Worker class + + /** + * Adds the mbean to the navigation tree + * @param mbean + * @throws Exception + */ + public void addManagedBean(ManagedBean mbean) // throws Exception + { + TreeObject treeServerObject = _managedServerMap.get(mbean.getServer()); + List<TreeObject> domains = treeServerObject.getChildren(); + TreeObject domain = null; + for (TreeObject child : domains) + { + if (child.getName().equals(mbean.getDomain())) + { + domain = child; + + break; + } + } + + addManagedBean(domain, mbean); + _treeViewer.refresh(); + } + + private void refreshRemovedObjects() + { + for (ManagedServer server : _managedServerMap.keySet()) + { + final ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(server); + if (serverRegistry == null) // server connection is closed + { + continue; + } + + final List<ManagedBean> removalList = serverRegistry.getObjectsToBeRemoved(); + if (removalList != null) + { + Display display = getSite().getShell().getDisplay(); + display.syncExec(new Runnable() + { + public void run() + { + for (ManagedBean mbean : removalList) + { + TreeObject treeServerObject = _managedServerMap.get(mbean.getServer()); + List<TreeObject> domains = treeServerObject.getChildren(); + TreeObject domain = null; + for (TreeObject child : domains) + { + if (child.getName().equals(mbean.getDomain())) + { + domain = child; + + break; + } + } + + removeManagedObject(domain, mbean); + // serverRegistry.removeManagedObject(mbean); + } + + _treeViewer.refresh(); + } + }); + } + } + } + + /** + * Gets the list of closed server connection from the ApplicationRegistry and then removes + * the closed server nodes from the navigation view + */ + private void refreshClosedServerConnections() + { + final List<ManagedServer> closedServers = ApplicationRegistry.getClosedServers(); + if (closedServers != null) + { + Display display = getSite().getShell().getDisplay(); + display.syncExec(new Runnable() + { + public void run() + { + for (ManagedServer server : closedServers) + { + removeManagedObject(_managedServerMap.get(server)); + _managedServerMap.remove(server); + ApplicationRegistry.removeServer(server); + } + + _treeViewer.refresh(); + } + }); + } + } + +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java new file mode 100644 index 0000000000..6894080859 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java @@ -0,0 +1,427 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.views; + +import static org.apache.qpid.management.ui.Constants.BUTTON_CLEAR; +import static org.apache.qpid.management.ui.Constants.BUTTON_REFRESH; +import static org.apache.qpid.management.ui.Constants.DESCRIPTION; +import static org.apache.qpid.management.ui.Constants.FONT_BOLD; +import static org.apache.qpid.management.ui.Constants.FONT_BUTTON; +import static org.apache.qpid.management.ui.Constants.FONT_ITALIC; +import static org.apache.qpid.management.ui.Constants.SUBSCRIBE_BUTTON; +import static org.apache.qpid.management.ui.Constants.UNSUBSCRIBE_BUTTON; + +import java.util.List; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ServerRegistry; +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.apache.qpid.management.ui.model.NotificationInfoModel; +import org.apache.qpid.management.ui.model.NotificationObject; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.TabFolder; + +/** + * Creates control composite for Notifications tab + * @author Bhupendra Bhardwaj + */ +public class NotificationsTabControl extends VHNotificationsTabControl +{ + private static final String SELECT_NOTIFICATIONNAME = "Select Notification"; + private static final String SELECT_NOTIFICATIONTYPE = "Select Type"; + private SelectionListener selectionListener; + private SelectionListener comboListener; + + private Combo notificationNameCombo = null; + private Combo typesCombo = null; + private Label descriptionLabel = null; + private Button _subscribeButton = null; + private Button _unsubscribeButton = null; + + public NotificationsTabControl(TabFolder tabFolder) + { + super(tabFolder); + } + + protected void createWidgets() + { + selectionListener = new SelectionListenerImpl(); + comboListener = new ComboSelectionListener(); + createNotificationInfoComposite(); + //addFilterComposite(); + addButtons(); + createTableViewer(); + } + + /** + * Creates composite and populates for displaying Notification Information (name, type, description) + * and creates buttons for subscribing or unsubscribing for notifications + */ + private void createNotificationInfoComposite() + { + Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + composite.setLayout(new FormLayout()); + + Label label = _toolkit.createLabel(composite, "Select the notification to subscribe or unsubscribe"); + label.setFont(ApplicationRegistry.getFont(FONT_BOLD)); + FormData formData = new FormData(); + formData.top = new FormAttachment(0, 10); + formData.left = new FormAttachment(0, 10); + label.setLayoutData(formData); + + notificationNameCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN); + formData = new FormData(); + formData.top = new FormAttachment(label, 10); + formData.left = new FormAttachment(0, 10); + formData.right = new FormAttachment(40); + notificationNameCombo.setLayoutData(formData); + notificationNameCombo.addSelectionListener(comboListener); + + typesCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN); + formData = new FormData(); + formData.top = new FormAttachment(label, 10); + formData.left = new FormAttachment(notificationNameCombo, 5); + formData.right = new FormAttachment(65); + typesCombo.setLayoutData(formData); + typesCombo.addSelectionListener(comboListener); + + _subscribeButton = new Button(composite, SWT.PUSH | SWT.CENTER); + _subscribeButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); + _subscribeButton.setText(SUBSCRIBE_BUTTON); + formData = new FormData(); + formData.top = new FormAttachment(label, 10); + formData.left = new FormAttachment(65, 10); + formData.width = 80; + _subscribeButton.setLayoutData(formData); + _subscribeButton.addSelectionListener(selectionListener); + + _unsubscribeButton = new Button(composite, SWT.PUSH | SWT.CENTER); + _unsubscribeButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); + _unsubscribeButton.setText(UNSUBSCRIBE_BUTTON); + formData = new FormData(); + formData.top = new FormAttachment(label, 10); + formData.left = new FormAttachment(_subscribeButton, 10); + formData.width = 80; + _unsubscribeButton.setLayoutData(formData); + _unsubscribeButton.addSelectionListener(selectionListener); + + Label fixedLabel = _toolkit.createLabel(composite, ""); + formData = new FormData(); + formData.top = new FormAttachment(notificationNameCombo, 5); + formData.left = new FormAttachment(0, 10); + fixedLabel.setLayoutData(formData); + fixedLabel.setText(DESCRIPTION + " : "); + fixedLabel.setFont(ApplicationRegistry.getFont(FONT_BOLD)); + + descriptionLabel = _toolkit.createLabel(composite, ""); + formData = new FormData(); + formData.top = new FormAttachment(notificationNameCombo, 5); + formData.left = new FormAttachment(fixedLabel, 10); + formData.right = new FormAttachment(100); + descriptionLabel.setLayoutData(formData); + descriptionLabel.setText(" "); + descriptionLabel.setFont(ApplicationRegistry.getFont(FONT_ITALIC)); + } + + /** + * Creates clear buttin and refresh button + */ + protected void addButtons() + { + Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + composite.setLayout(new GridLayout(2, true)); + + // Add Clear Button + _clearButton = _toolkit.createButton(composite, BUTTON_CLEAR, SWT.PUSH | SWT.CENTER); + _clearButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); + GridData gridData = new GridData(SWT.LEAD, SWT.TOP, true, false); + gridData.widthHint = 80; + _clearButton.setLayoutData(gridData); + _clearButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + if (_mbean == null) + return; + + IStructuredSelection ss = (IStructuredSelection)_tableViewer.getSelection(); + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); + serverRegistry.clearNotifications(_mbean, ss.toList()); + refresh(); + } + }); + + // Add Refresh Button + _refreshButton = _toolkit.createButton(composite, BUTTON_REFRESH, SWT.PUSH | SWT.CENTER); + _refreshButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); + gridData = new GridData(SWT.TRAIL, SWT.TOP, true, false); + gridData.widthHint = 80; + _refreshButton.setLayoutData(gridData); + _refreshButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + if (_mbean == null) + return; + + refresh(); + } + }); + } + + @Override + public void refresh(ManagedBean mbean) + { + _mbean = mbean; + _notifications = null; + _table.deselectAll(); + _tableViewer.getTable().clearAll(); + + if (_mbean == null) + { + _tableViewer.getTable().clearAll(); + _subscribeButton.setEnabled(false); + _unsubscribeButton.setEnabled(false); + return; + } + + if (!doesMBeanSendsNotification()) + { + Control[] children = _form.getBody().getChildren(); + for (int i = 0; i < children.length; i++) + { + children[i].setVisible(false); + } + + String name = (_mbean.getName() != null) ? _mbean.getName() : _mbean.getType(); + _form.setText(name + " does not send any notification"); + return; + } + + Control[] children = _form.getBody().getChildren(); + for (int i = 0; i < children.length; i++) + { + children[i].setVisible(true); + } + + populateNotificationInfo(); + workerRunning = true; + _form.layout(true); + _form.getBody().layout(true, true); + } + + public void refresh() + { + _notifications = null; + _table.deselectAll(); + _tableViewer.getTable().clearAll(); + } + + /** + * Fills the notification information widgets for selected mbean + */ + private void populateNotificationInfo() + { + notificationNameCombo.removeAll(); + NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean); + if (items.length > 1) + { + notificationNameCombo.add(SELECT_NOTIFICATIONNAME); + } + + for (int i = 0; i < items.length; i++) + { + notificationNameCombo.add(items[i].getName()); + notificationNameCombo.setData(items[i].getName(), items[i]); + } + notificationNameCombo.select(0); + + typesCombo.removeAll(); + typesCombo.add("Select Type", 0); + typesCombo.select(0); + typesCombo.setEnabled(false); + + populateNotificationType(notificationNameCombo.getItem(0)); + checkForEnablingButtons(); + } + + /** + * Checks and the enabing/disabling of buttons + */ + private void checkForEnablingButtons() + { + int nameIndex = notificationNameCombo.getSelectionIndex(); + int itemCount = notificationNameCombo.getItems().length; + if ((itemCount > 1) && (nameIndex == 0)) + { + _subscribeButton.setEnabled(false); + _unsubscribeButton.setEnabled(false); + descriptionLabel.setText(""); + return; + } + + int typeIndex = typesCombo.getSelectionIndex(); + itemCount = typesCombo.getItems().length; + if ((itemCount > 1) && (typeIndex == 0)) + { + _subscribeButton.setEnabled(false); + _unsubscribeButton.setEnabled(false); + return; + } + + String type = typesCombo.getItem(typeIndex); + String name = notificationNameCombo.getItem(nameIndex); + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); + + if (serverRegistry.hasSubscribedForNotifications(_mbean, name, type)) + { + _subscribeButton.setEnabled(false); + _unsubscribeButton.setEnabled(true); + } + else + { + _subscribeButton.setEnabled(true); + _unsubscribeButton.setEnabled(false); + } + } + + private boolean doesMBeanSendsNotification() + { + NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean); + if (items == null || items.length == 0) + return false; + else + return true; + } + + /** + * Selection listener for subscribing or unsubscribing the notifications + */ + private class SelectionListenerImpl extends SelectionAdapter + { + public void widgetSelected(SelectionEvent e) + { + if (_mbean == null) + return; + + Button source = (Button)e.getSource(); + String type = typesCombo.getItem(typesCombo.getSelectionIndex()); + String name = notificationNameCombo.getItem(notificationNameCombo.getSelectionIndex()); + if (source == _unsubscribeButton) + { + try + { + MBeanUtility.removeNotificationListener(_mbean, name, type); + } + catch(Exception ex) + { + MBeanUtility.handleException(ex); + } + } + else if (source == _subscribeButton) + { + try + { + MBeanUtility.createNotificationlistener(_mbean, name, type); + } + catch(Exception ex) + { + MBeanUtility.handleException(ex); + } + } + checkForEnablingButtons(); + } + } + + /** + * Selection listener class for the Notification Name. The notification type and description will be + * displayed accordingly + */ + private class ComboSelectionListener extends SelectionAdapter + { + public void widgetSelected(SelectionEvent e) + { + if (_mbean == null) + return; + + Combo combo = (Combo)e.getSource(); + if (combo == notificationNameCombo) + { + String selectedItem = combo.getItem(combo.getSelectionIndex()); + populateNotificationType(selectedItem); + } + checkForEnablingButtons(); + } + } + + private void populateNotificationType(String notificationName) + { + NotificationInfoModel data = (NotificationInfoModel)notificationNameCombo.getData(notificationName); + if (data == null) + { + descriptionLabel.setText(""); + typesCombo.select(0); + typesCombo.setEnabled(false); + return; + } + descriptionLabel.setText(data.getDescription()); + typesCombo.removeAll(); + typesCombo.setItems(data.getTypes()); + if (typesCombo.getItemCount() > 1) + { + typesCombo.add(SELECT_NOTIFICATIONTYPE, 0); + } + typesCombo.select(0); + typesCombo.setEnabled(true); + } + + /** + * Updates the table with new notifications received from mbean server for the selected mbean + */ + protected void updateTableViewer() + { + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); + List<NotificationObject> newList = serverRegistry.getNotifications(_mbean); + if (newList == null) + return; + + _notifications = newList; + _tableViewer.setInput(_notifications); + _tableViewer.refresh(); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NumberVerifyListener.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NumberVerifyListener.java new file mode 100644 index 0000000000..1774209dae --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NumberVerifyListener.java @@ -0,0 +1,46 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.views; + +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.events.VerifyListener; + +/** + * Implementation of VeryfyListener for numeric values + * @author Bhupendra Bhardwaj + */ +public class NumberVerifyListener implements VerifyListener +{ + public void verifyText(VerifyEvent event) + { + String string = event.text; + char [] chars = new char [string.length ()]; + string.getChars (0, chars.length, chars, 0); + for (int i=0; i<chars.length; i++) + { + if (!('0' <= chars [i] && chars [i] <= '9')) + { + event.doit = false; + return; + } + } + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java new file mode 100644 index 0000000000..36ad1b4fdc --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java @@ -0,0 +1,903 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.views; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; + +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.TabularDataSupport; + +import static org.apache.qpid.management.ui.Constants.*; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ServerRegistry; +import org.apache.qpid.management.ui.jmx.JMXServerRegistry; +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.apache.qpid.management.ui.model.OperationData; +import org.apache.qpid.management.ui.model.ParameterData; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.widgets.Form; +import org.eclipse.ui.forms.widgets.FormToolkit; + + +/** + * Control class for the MBean operations tab. It creates the required widgets + * for the selected MBean. + * @author Bhupendra Bhardwaj + * @author Robert Gemmell + */ +public class OperationTabControl extends TabControl +{ + private static final int heightForAParameter = 30; + private static final int labelWidth = 30; + private static final int valueWidth = labelWidth + 25; + + private FormToolkit _toolkit; + private Form _form; + private OperationData _opData; + + private SelectionListener operationExecutionListener = new OperationExecutionListener(); + private SelectionListener refreshListener = new RefreshListener(); + private SelectionListener parameterSelectionListener = new ParameterSelectionListener(); + private SelectionListener booleanSelectionListener = new BooleanSelectionListener(); + private VerifyListener verifyListener = new VerifyListenerImpl(); + private KeyListener keyListener = new KeyListenerImpl(); + private KeyListener headerBindingListener = new HeaderBindingKeyListener(); + + private Composite _headerComposite = null; + private Composite _paramsComposite = null; + private Composite _resultsComposite = null; + private Button _executionButton = null; + + // for customized method in header exchange + private HashMap<Text, Text> headerBindingHashMap = null; + private String _virtualHostName = null; + + public OperationTabControl(TabFolder tabFolder, OperationData opData) + { + super(tabFolder); + _toolkit = new FormToolkit(_tabFolder.getDisplay()); + _form = _toolkit.createForm(_tabFolder); + _form.getBody().setLayout(new GridLayout()); + _opData = opData; + createComposites(); + setHeader(); + } + + /** + * Form area is devided in four parts: + * Header composite - displays operaiton information + * Patameters composite - displays parameters if there + * Button - operation execution button + * Results composite - displays results for operations, which have + * no parameters but have some return value + */ + private void createComposites() + { + // + _headerComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE); + _headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + + List<ParameterData> params = _opData.getParameters(); + if (params != null && !params.isEmpty()) + { + _paramsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE); + _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + } + _executionButton = _toolkit.createButton(_form.getBody(), BUTTON_EXECUTE, SWT.PUSH | SWT.CENTER); + _executionButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); + GridData layoutData = new GridData(SWT.CENTER, SWT.TOP, true, false); + layoutData.verticalIndent = 20; + _executionButton.setLayoutData(layoutData); + + _resultsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE); + layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + layoutData.verticalIndent = 20; + _resultsComposite.setLayoutData(layoutData); + _resultsComposite.setLayout(new GridLayout()); + } + + /** + * @see TabControl#getControl() + */ + public Control getControl() + { + return _form; + } + + @Override + public void refresh(ManagedBean mbean) + { + _mbean = mbean; + _virtualHostName = _mbean.getVirtualHostName(); + + // Setting the form to be invisible. Just in case the mbean server connection + // is done and it takes time in getting the response, then the ui should be blank + // instead of having half the widgets displayed. + _form.setVisible(false); + + ViewUtility.disposeChildren(_paramsComposite); + createParameterWidgets(); + + // Set button text and add appropriate listener to button. + // If there are no parameters and it is info operation, then operation gets executed + // and result is displayed + List<ParameterData> params = _opData.getParameters(); + if (params != null && !params.isEmpty()) + { + setButton(BUTTON_EXECUTE); + } + else if (_opData.getImpact() == OPERATION_IMPACT_ACTION) + { + setButton(BUTTON_EXECUTE); + } + else if (_opData.getImpact() == OPERATION_IMPACT_INFO) + { + setButton(BUTTON_REFRESH); + executeAndShowResults(); + } + + _form.setVisible(true); + layout(); + } + + public void layout() + { + _form.layout(true); + _form.getBody().layout(true, true); + } + + /** + * populates the header composite, containing the operation name and description. + */ + private void setHeader() + { + _form.setText(ViewUtility.getDisplayText(_opData.getName())); + _headerComposite.setLayout(new GridLayout(2, false)); + //operation description + Label label = _toolkit.createLabel(_headerComposite, DESCRIPTION + " : "); + label.setFont(ApplicationRegistry.getFont(FONT_BOLD)); + label.setLayoutData(new GridData(SWT.LEAD, SWT.TOP, false, false)); + + label = _toolkit.createLabel(_headerComposite, _opData.getDescription()); + label.setFont(ApplicationRegistry.getFont(FONT_NORMAL)); + label.setLayoutData(new GridData(SWT.LEAD, SWT.TOP, true, false)); + + _headerComposite.layout(); + } + + /** + * Creates the widgets for operation parameters if there are any + */ + private void createParameterWidgets() + { + List<ParameterData> params = _opData.getParameters(); + if (params == null || params.isEmpty()) + { + return; + } + + // Customised parameter widgets + if (_mbean.isExchange() && + EXCHANGE_TYPE_VALUES[2].equals(_mbean.getProperty(EXCHANGE_TYPE)) && + _opData.getName().equalsIgnoreCase(OPERATION_CREATE_BINDING)) + { + customCreateNewBinding(); + return; + } + // end of Customised parameter widgets + + _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + _paramsComposite.setLayout(new FormLayout()); + int parameterPositionOffset = 0; + for (ParameterData param : params) + { + boolean valueInCombo = false; + Label label = _toolkit.createLabel(_paramsComposite, ViewUtility.getDisplayText(param.getName())); + FormData formData = new FormData(); + if (params.indexOf(param) == 0) + { + parameterPositionOffset = 0; + } + else + { + parameterPositionOffset += heightForAParameter; + } + formData.top = new FormAttachment(0, parameterPositionOffset + 2); + formData.right = new FormAttachment(labelWidth); + label.setLayoutData(formData); + label.setToolTipText(param.getDescription()); + + formData = new FormData(); + formData.top = new FormAttachment(0, parameterPositionOffset); + formData.left = new FormAttachment(label, 5); + formData.right = new FormAttachment(valueWidth); + // this will contain the list of items, if the list is to be made available to choose from + // e.g. the list of exchanges + String[] items = null; + if (param.getName().equals(QUEUE)) + { + List<String> qList = ApplicationRegistry.getServerRegistry(_mbean).getQueueNames(_virtualHostName); + // Customization for AMQQueueMBean method OPERATION_MOVE_MESSAGES + if (_opData.getName().equals(OPERATION_MOVE_MESSAGES)) + { + qList.remove(_mbean.getName()); + } + // End of Customization + items = qList.toArray(new String[0]); + } + else if (param.getName().equals(EXCHANGE)) + { + items = ApplicationRegistry.getServerRegistry(_mbean).getExchangeNames(_virtualHostName); + } + else if (param.getName().equals(EXCHANGE_TYPE)) + { + items = EXCHANGE_TYPE_VALUES; + } + else if (isUserListParameter(param)) + { + List<String> list = ApplicationRegistry.getServerRegistry(_mbean).getUsernames(); + if (list != null && !list.isEmpty()) + { + items = list.toArray(new String[0]); + } + } + + if (items != null) + { + org.eclipse.swt.widgets.List _list = new org.eclipse.swt.widgets.List(_paramsComposite, SWT.BORDER | SWT.V_SCROLL); + int listSize = _form.getClientArea().height * 2 / 3; + int itemsHeight = items.length * (_list.getItemHeight() + 2); + // Set a min height for the list widget (set it to min 4 items) + if (items.length < 4) + { + itemsHeight = 4 * (_list.getItemHeight() + 2); + } + + listSize = (listSize > itemsHeight) ? itemsHeight : listSize; + parameterPositionOffset = parameterPositionOffset + listSize; + formData.bottom = new FormAttachment(0, parameterPositionOffset); + _list.setLayoutData(formData); + _list.setData(param); + _list.setItems(items); + _list.addSelectionListener(parameterSelectionListener); + valueInCombo = true; + } + else if (param.isBoolean()) + { + Button booleanButton = _toolkit.createButton(_paramsComposite, "", SWT.CHECK); + booleanButton.setLayoutData(formData); + booleanButton.setData(param); + booleanButton.addSelectionListener(booleanSelectionListener); + valueInCombo = true; + } + else + { + int style = SWT.NONE; + if (PASSWORD.equalsIgnoreCase(param.getName())) + { + style = SWT.PASSWORD; + } + Text text = _toolkit.createText(_paramsComposite, "", style); + formData = new FormData(); + formData.top = new FormAttachment(0, parameterPositionOffset); + formData.left = new FormAttachment(label, 5); + formData.right = new FormAttachment(valueWidth); + text.setLayoutData(formData); + // Listener to assign value to the parameter + text.addKeyListener(keyListener); + // Listener to verify if the entered key is valid + text.addVerifyListener(verifyListener); + text.setData(param); + } + + // display the parameter data type next to the text field + if (valueInCombo) + { + label = _toolkit.createLabel(_paramsComposite, ""); + } + else if (PASSWORD.equalsIgnoreCase(param.getName())) + { + label = _toolkit.createLabel(_paramsComposite, "(String)"); + } + else + { + String str = param.getType(); + + if (param.getType().lastIndexOf(".") != -1) + str = param.getType().substring(1 + param.getType().lastIndexOf(".")); + + label = _toolkit.createLabel(_paramsComposite, "(" + str + ")"); + } + formData = new FormData(); + formData.top = new FormAttachment(0, parameterPositionOffset); + formData.left = new FormAttachment(valueWidth, 5); + label.setLayoutData(formData); + } + } + + private boolean isUserListParameter(ParameterData param) + { + if (_mbean.isAdmin() && param.getName().equals(OPERATION_PARAM_USERNAME) + && !_opData.getName().equals(OPERATION_CREATEUSER)) + { + return true; + } + + return false; + } + + /** + * Creates customized dispaly for a method "CreateNewBinding" for Headers exchange + * + */ + private void customCreateNewBinding() + { + headerBindingHashMap = new HashMap<Text, Text>(); + + _paramsComposite.setLayout(new GridLayout()); + _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true)); + final ScrolledComposite scrolledComposite = new ScrolledComposite(_paramsComposite, SWT.BORDER | SWT.V_SCROLL); + scrolledComposite.setExpandHorizontal(true); + scrolledComposite.setExpandVertical(true); + GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, true); + scrolledComposite.setLayoutData(layoutData); + scrolledComposite.setLayout(new GridLayout()); + + final Composite composite = _toolkit.createComposite(scrolledComposite, SWT.NONE); + scrolledComposite.setContent(composite); + layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + layoutData.verticalIndent = 20; + composite.setLayoutData(layoutData); + composite.setLayout(new FormLayout()); + + List<ParameterData> params = _opData.getParameters(); + ParameterData param = params.get(0); + // Queue selection widget + Label label = _toolkit.createLabel(composite, ViewUtility.getDisplayText(param.getName())); + FormData formData = new FormData(); + formData.top = new FormAttachment(0, 2); + formData.right = new FormAttachment(labelWidth); + label.setLayoutData(formData); + label.setToolTipText(param.getDescription()); + + formData = new FormData(); + formData.top = new FormAttachment(0); + formData.left = new FormAttachment(label, 5); + formData.right = new FormAttachment(valueWidth); + + Combo combo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN); + List<String> qList = ApplicationRegistry.getServerRegistry(_mbean).getQueueNames(_virtualHostName); + combo.setItems(qList.toArray(new String[0])); + combo.add("Select Queue", 0); + combo.select(0); + combo.setLayoutData(formData); + combo.setData(param); + combo.addSelectionListener(parameterSelectionListener); + + // Binding creation widgets + createARowForCreatingHeadersBinding(composite, 1); + createARowForCreatingHeadersBinding(composite, 2); + createARowForCreatingHeadersBinding(composite, 3); + createARowForCreatingHeadersBinding(composite, 4); + createARowForCreatingHeadersBinding(composite, 5); + createARowForCreatingHeadersBinding(composite, 6); + createARowForCreatingHeadersBinding(composite, 7); + createARowForCreatingHeadersBinding(composite, 8); + + final Button addMoreButton = _toolkit.createButton(composite, "Add More", SWT.PUSH); + formData = new FormData(); + formData.top = new FormAttachment(0, heightForAParameter); + formData.left = new FormAttachment(70, 5); + addMoreButton.setLayoutData(formData); + addMoreButton.setData("rowCount", 8); + addMoreButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + int count = Integer.parseInt(addMoreButton.getData("rowCount").toString()); + createARowForCreatingHeadersBinding(composite, ++count); + addMoreButton.setData("rowCount", count); + scrolledComposite.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + composite.layout(); + _form.layout(); + } + }); + + scrolledComposite.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + composite.layout(); + } + + /** + * Adds a row for adding a binding for Headers Exchange. Used by the method, which creates the customized + * layout and widgest for Header's exchange method createNewBinding. + * @param parent composite + * @param rowCount - row number + */ + private void createARowForCreatingHeadersBinding(Composite parent, int rowCount) + { + Label key = _toolkit.createLabel(parent, "Name"); + FormData formData = new FormData(); + formData.top = new FormAttachment(0, rowCount * heightForAParameter + 2); + formData.right = new FormAttachment(15); + key.setLayoutData(formData); + + Text keyText = _toolkit.createText(parent, "", SWT.NONE); + formData = new FormData(); + formData.top = new FormAttachment(0, rowCount * heightForAParameter); + formData.left = new FormAttachment(key, 5); + formData.right = new FormAttachment(40); + keyText.setLayoutData(formData); + keyText.addKeyListener(headerBindingListener); + + Label value = _toolkit.createLabel(parent, "Value"); + formData = new FormData(); + formData.top = new FormAttachment(0, rowCount * heightForAParameter + 2); + formData.right = new FormAttachment(45); + value.setLayoutData(formData); + + Text valueText = _toolkit.createText(parent, "", SWT.NONE); + formData = new FormData(); + formData.top = new FormAttachment(0, rowCount * heightForAParameter); + formData.left = new FormAttachment(value, 5); + formData.right = new FormAttachment(70); + valueText.setLayoutData(formData); + valueText.addKeyListener(headerBindingListener); + + // Add these to the map, to retrieve the values while setting the parameter value + headerBindingHashMap.put(keyText, valueText); + } + + /** + * Sets text and listener for the operation execution button + * @param text + */ + private void setButton(String text) + { + _executionButton.setText(text); + _executionButton.removeSelectionListener(refreshListener); + _executionButton.removeSelectionListener(operationExecutionListener); + + if (BUTTON_EXECUTE.equals(text)) + { + _executionButton.addSelectionListener(operationExecutionListener); + } + else + { + _executionButton.addSelectionListener(refreshListener); + } + } + + /** + * displays the operation result in a pop-up window + * @param result + */ + private void populateResults(Object result) + { + Display display = Display.getCurrent(); + int width = 600; + int height = 400; + Shell shell = ViewUtility.createPopupShell(RESULT, width, height); + shell.setImage(ApplicationRegistry.getImage(CONSOLE_IMAGE)); + ViewUtility.populateCompositeWithData(_toolkit, shell, result); + + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + shell.dispose(); + } + + /** + * Clears the parameter values of the operation + */ + private void clearParameters() + { + List<ParameterData> params = _opData.getParameters(); + if (params != null && !params.isEmpty()) + { + for (ParameterData param : params) + { + param.setDefaultValue(); + } + } + } + + /** + * Clears the values entered by the user from parameter value widgets + * @param control + */ + private void clearParameterValues(Composite control) + { + if (control == null || (control.isDisposed())) + return; + + Control[] controls = control.getChildren(); + if (controls == null || controls.length == 0) + return; + + for (int i = 0; i < controls.length; i++) + { + if (controls[i] instanceof Combo) + ((Combo)controls[i]).select(0); + if (controls[i] instanceof org.eclipse.swt.widgets.List) + ((org.eclipse.swt.widgets.List)controls[i]).deselectAll(); + else if (controls[i] instanceof Text) + ((Text)controls[i]).setText(""); + else if (controls[i] instanceof Button) + ((Button)controls[i]).setSelection(false); + else if (controls[i] instanceof Composite) + clearParameterValues((Composite)controls[i]); + } + } + + /** + * Listener class for operation execution events + */ + private class OperationExecutionListener extends SelectionAdapter + { + public void widgetSelected(SelectionEvent e) + { + List<ParameterData> params = _opData.getParameters(); + if (params != null && !params.isEmpty()) + { + for (ParameterData param : params) + { + if (param.getValue() == null || param.getValue().toString().length() == 0) + { + // Customized check, because for this parameter null is allowed + if (param.getName().equals(ATTRIBUTE_QUEUE_OWNER) && + _opData.getName().equals(OPERATION_CREATE_QUEUE)) + { + continue; + } + // End of custom code + + ViewUtility.popupInfoMessage(_form.getText(), "Please select the " + ViewUtility.getDisplayText(param.getName())); + return; + } + + // customized for passwords + if (PASSWORD.equalsIgnoreCase(param.getName())) + { + if (param.getType().equals("[C")) + { + try + { + param.setValue(ViewUtility.getHash((String)param.getValue())); + } + catch (Exception ex) + { + MBeanUtility.handleException(_mbean, ex); + return; + } + } + } + // end of customization + } + } + + if (_opData.getImpact() == OPERATION_IMPACT_ACTION) + { + String bean = _mbean.getName() == null ? _mbean.getType() : _mbean.getName(); + int response = ViewUtility.popupConfirmationMessage(bean, "Do you want to " + _form.getText()+ " ?"); + if (response == SWT.YES) + { + executeAndShowResults(); + } + } + else + { + executeAndShowResults(); + } + + if (_mbean.isAdmin() && _opData.getName().equals(OPERATION_DELETEUSER)) + { + refresh(_mbean); + } + else + { + clearParameters(); + clearParameterValues(_paramsComposite); + } + } + } + + // Listener for the "Refresh" execution button + private class RefreshListener extends SelectionAdapter + { + public void widgetSelected(SelectionEvent e) + { + executeAndShowResults(); + } + } + + /** + * Executres the operation, gets the result from server and displays to the user + */ + private void executeAndShowResults() + { + Object result = null; + try + { + result = MBeanUtility.execute(_mbean, _opData); + } + catch(Exception ex) + { + MBeanUtility.handleException(_mbean, ex); + return; + } + + // Custom code for Admin mbean operation + /* These custome codes here are to make the GUI look more user friendly. + * Here we are adding the users to a list, which will be used to list username to be selected on + * pages like "delete user", "set password" instead of typing the username + */ + if (_mbean.isAdmin()) + { + if (_opData.getName().equals(OPERATION_VIEWUSERS)) + { + ApplicationRegistry.getServerRegistry(_mbean).setUserList(extractUserList(result)); + } + else if (_opData.getName().equals(OPERATION_DELETEUSER)) + { + List<String> list = ApplicationRegistry.getServerRegistry(_mbean).getUsernames(); + Object userName = _opData.getParameterValue(OPERATION_PARAM_USERNAME); + if ((list != null) && !list.isEmpty() && (userName != null)) + { + list.remove(userName); + ApplicationRegistry.getServerRegistry(_mbean).setUserList(list); + } + } + else if (_opData.getName().equals(OPERATION_CREATEUSER)) + { + List<String> list = ApplicationRegistry.getServerRegistry(_mbean).getUsernames(); + Object userName = _opData.getParameterValue(OPERATION_PARAM_USERNAME); + if ((list != null) && !list.isEmpty() && (userName != null)) + { + list.add(userName.toString()); + ApplicationRegistry.getServerRegistry(_mbean).setUserList(list); + } + } + } + // end of custom code + + // Some mbeans have only "type" and no "name". + String title = _mbean.getType(); + if (_mbean.getName() != null && _mbean.getName().length() != 0) + { + title = _mbean.getName(); + } + + if (_opData.isReturnTypeVoid()) + { + ViewUtility.popupInfoMessage(title, OPERATION_SUCCESSFUL); + } + else if (_opData.isReturnTypeBoolean()) + { + boolean success = Boolean.parseBoolean(result.toString()); + String message = success ? OPERATION_SUCCESSFUL : OPERATION_UNSUCCESSFUL; + ViewUtility.popupInfoMessage(title, message); + } + else if (_opData.getParameters() != null && !_opData.getParameters().isEmpty()) + { + populateResults(result); + } + else + { + ViewUtility.disposeChildren(_resultsComposite); + ViewUtility.populateCompositeWithData(_toolkit, _resultsComposite, result); + _resultsComposite.layout(); + _form.layout(); + } + + } + + private List<String> extractUserList(Object result) + { + if (!(result instanceof TabularDataSupport)) + { + return null; + } + + TabularDataSupport tabularData = (TabularDataSupport)result; + Collection<Object> records = tabularData.values(); + List<String> list = new ArrayList<String>(); + for (Object o : records) + { + CompositeData data = (CompositeData) o; + if (data.containsKey(USERNAME)) + { + list.add(data.get(USERNAME).toString()); + } + } + + return list; + } + + /** + * Listener class for the operation parameters widget + */ + private class ParameterSelectionListener extends SelectionAdapter + { + public void widgetSelected(SelectionEvent e) + { + ParameterData parameter = (ParameterData)e.widget.getData(); + parameter.setValue(null); + if (e.widget instanceof Combo) + { + Combo combo = (Combo)e.widget; + if (combo.getSelectionIndex() > 0) + { + String item = combo.getItem(combo.getSelectionIndex()); + parameter.setValueFromString(item); + } + } + else if (e.widget instanceof org.eclipse.swt.widgets.List) + { + org.eclipse.swt.widgets.List list = (org.eclipse.swt.widgets.List)e.widget; + String[] selectedItems = list.getSelection(); + if (selectedItems.length > 0) + { + parameter.setValueFromString(selectedItems[0]); + } + } + } + } + + /** + * Listener class for boolean parameter widgets + */ + private class BooleanSelectionListener extends SelectionAdapter + { + public void widgetSelected(SelectionEvent e) + { + ParameterData parameter = (ParameterData)(e.widget.getData()); + if (e.widget instanceof Button) + { + Button button = (Button)e.widget; + parameter.setValue(button.getSelection()); + } + else if (e.widget instanceof Combo) + { + Combo combo = (Combo)e.widget; + String item = combo.getItem(combo.getSelectionIndex()); + parameter.setValueFromString(item); + } + } + } + + /** + * Listener class for the operation parameter value widget (Text field) + */ + private class KeyListenerImpl extends KeyAdapter + { + public void keyReleased(KeyEvent e) + { + if (!(e.widget instanceof Text)) + return; + + Text text = (Text)e.widget; + // Get the parameters widget and assign the text to the parameter + String strValue = text.getText(); + ParameterData parameter = (ParameterData)text.getData(); + try + { + parameter.setValueFromString(strValue); + } + catch(Exception ex) + { + // Exception occured in setting parameter value. + // ignore it. The value will not be assigned to the parameter + } + } + } + + /** + * Listener class for HeaderExchange's new binding widgets. Used when the new bindings are + * being created for Header's Exchange + */ + private class HeaderBindingKeyListener extends KeyAdapter + { + public void keyReleased(KeyEvent e) + { + ParameterData param = _opData.getParameters().get(1); + StringBuffer paramValue = new StringBuffer(); + for (Entry<Text, Text> entry : headerBindingHashMap.entrySet()) + { + + Text nameText = entry.getKey(); + String name = nameText.getText(); + Text valueText = entry.getValue(); + String value = valueText.getText(); + if ((name != null) && (name.length() != 0) && (value != null) && (value.length() != 0)) + { + if (paramValue.length() != 0) + { + paramValue.append(","); + } + paramValue.append(name + "=" + value); + } + } + + param.setValue(paramValue.toString()); + } + } + + /** + * Listener class for verifying the user input with parameter type + */ + private class VerifyListenerImpl implements VerifyListener + { + public void verifyText(VerifyEvent event) + { + ParameterData parameter = (ParameterData)event.widget.getData(); + String text = event.text; + char [] chars = new char [text.length ()]; + text.getChars(0, chars.length, chars, 0); + String type = parameter.getType(); + if (type.equals("int") || type.equals("java.lang.Integer") || + type.equals("long") || type.equals("java.lang.Long")) + { + for (int i=0; i<chars.length; i++) + { + if (!('0' <= chars [i] && chars [i] <= '9')) + { + event.doit = false; + return; + } + } + + } + } + } + +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java new file mode 100644 index 0000000000..31a0bc857b --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java @@ -0,0 +1,296 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.management.ui.views; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ServerRegistry; +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.apache.qpid.management.ui.model.AttributeData; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.TabFolder; + +/** + * Controller class, which takes care of displaying appropriate information and widgets for Queues. + * This allows user to select Queues and add those to the navigation view + */ +public class QueueTypeTabControl extends MBeanTypeTabControl +{ + private boolean _showTempQueues = false; + private Button _sortBySizeButton = null; + private Button _sortByConsumercountButton = null; + private Button _sortByNameButton = null; + private Button _showTempQueuesButton = null; + + private ComparatorImpl _sorterByAttribute = new ComparatorImpl(); + + // Map required for sorting queues based on attribute values + private Map<AttributeData, ManagedBean> _queueDepthMap = new LinkedHashMap<AttributeData, ManagedBean>(); + // Map used for sorting Queues based on consumer count + private Map<AttributeData, ManagedBean> _queueConsumerCountMap = new LinkedHashMap<AttributeData, ManagedBean>(); + + + public QueueTypeTabControl(TabFolder tabFolder) + { + super(tabFolder, Constants.QUEUE); + createWidgets(); + } + + protected void createWidgets() + { + createHeaderComposite(getFormComposite()); + createButtonsComposite(getFormComposite()); + createListComposite(); + } + + @Override + public void refresh() throws Exception + { + setLabelValues(); + selectDefaultSortingButton(); + populateList(); + layout(); + } + + /** + * populates the map with mbean name and the mbean object. + * @throws Exception + */ + protected void populateList() throws Exception + { + // map should be cleared before populating it with new values + getMBeansMap().clear(); + _queueDepthMap.clear(); + _queueConsumerCountMap.clear(); + + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer()); + String[] items = null; + java.util.List<ManagedBean> list = null; + + // populate the map and list with appropriate mbeans + list = serverRegistry.getQueues(MBeanView.getVirtualHost()); + items = getQueueItems(list); + // sort the refreshed list in the selected order + if (_sortBySizeButton.getSelection()) + { + sortQueuesByQueueDepth(); + } + else if (_sortByConsumercountButton.getSelection()) + { + sortQueuesByConsumerCount(); + } + else + { + getListWidget().setItems(items); + } + } + + private void selectDefaultSortingButton() + { + _sortByNameButton.setSelection(true); + _sortBySizeButton.setSelection(false); + _sortByConsumercountButton.setSelection(false); + + _showTempQueues = false; + _showTempQueuesButton.setSelection(_showTempQueues); + } + + protected void createListComposite() + { + // Composite to contain the item list + Composite composite = getToolkit().createComposite(getFormComposite()); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + composite.setLayoutData(gridData); + GridLayout layout = new GridLayout(2, true); + layout.verticalSpacing = 0; + composite.setLayout(layout); + + createListComposite(composite); + + // Composite to contain buttons like - Sort by size + Composite _sortingComposite = getToolkit().createComposite(composite); + gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + _sortingComposite.setLayoutData(gridData); + GridLayout gridLayout = new GridLayout(); + gridLayout.verticalSpacing = 20; + _sortingComposite.setLayout(gridLayout); + + Group sortingGroup = new Group(_sortingComposite, SWT.SHADOW_NONE); + sortingGroup.setBackground(_sortingComposite.getBackground()); + sortingGroup.setText(" Sort List By "); + sortingGroup.setFont(ApplicationRegistry.getFont(Constants.FONT_BOLD)); + gridData = new GridData(SWT.CENTER, SWT.TOP, true, false); + sortingGroup.setLayoutData(gridData); + sortingGroup.setLayout(new GridLayout()); + + _sortByNameButton = getToolkit().createButton(sortingGroup, Constants.QUEUE_SORT_BY_NAME, SWT.RADIO); + gridData = new GridData(SWT.LEAD, SWT.CENTER, true, false); + _sortByNameButton.setLayoutData(gridData); + _sortByNameButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e) + { + try + { + // sort the stored list of items + java.util.List<String> list = new ArrayList<String>(getMBeansMap().keySet()); + Collections.sort(list); + getListWidget().setItems(list.toArray(new String[0])); + } + catch (Exception ex) + { + MBeanUtility.handleException(ex); + } + } + }); + + _sortBySizeButton = getToolkit().createButton(sortingGroup, Constants.QUEUE_SORT_BY_DEPTH, SWT.RADIO); + gridData = new GridData(SWT.LEAD, SWT.CENTER, true, false); + _sortBySizeButton.setLayoutData(gridData); + _sortBySizeButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e) + { + try + { + // sort the stored list of items + sortQueuesByQueueDepth(); + } + catch (Exception ex) + { + MBeanUtility.handleException(ex); + } + } + }); + + _sortByConsumercountButton = getToolkit().createButton(sortingGroup, Constants.QUEUE_SORT_BY_CONSUMERCOUNT, SWT.RADIO); + gridData = new GridData(SWT.LEAD, SWT.CENTER, true, false); + _sortByConsumercountButton.setLayoutData(gridData); + _sortByConsumercountButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e) + { + try + { + sortQueuesByConsumerCount(); + } + catch (Exception ex) + { + MBeanUtility.handleException(ex); + } + } + }); + + _showTempQueuesButton = getToolkit().createButton(_sortingComposite, Constants.QUEUE_SHOW_TEMP_QUEUES, SWT.CHECK); + _showTempQueuesButton.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false)); + _showTempQueuesButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e) + { + Button button = (Button)e.widget; + _showTempQueues = button.getSelection(); + try + { + populateList(); + } + catch (Exception ex) + { + MBeanUtility.handleException(ex); + } + } + }); + } + + + private String[] getQueueItems(java.util.List<ManagedBean> list) throws Exception + { + if (list == null) + return new String[0]; + + // Sort the list. It will keep the mbeans in sorted order in the _queueMap, which is required for + // sorting the queue according to size etc + Collections.sort(list, getMBeanNameSorter()); + java.util.List<String> items = new ArrayList<String>();; + int i = 0; + for (ManagedBean mbean : list) + { + if ((!_showTempQueues && mbean.isTempQueue())) + { + continue; + } + AttributeData data = MBeanUtility.getAttributeData(mbean, Constants.ATTRIBUTE_QUEUE_DEPTH); + String value = mbean.getName() + " (" + data.getValue().toString() + " KB)"; + items.add(value); + //items[i] = mbean.getName() + " (" + value + " KB)"; + getMBeansMap().put(value, mbean); + _queueDepthMap.put(data, mbean); + data = MBeanUtility.getAttributeData(mbean, Constants.ATTRIBUTE_QUEUE_CONSUMERCOUNT); + _queueConsumerCountMap.put(data, mbean); + i++; + } + + return items.toArray(new String[0]); + } + + + private void sortQueuesByQueueDepth() + { + // Queues are already in the alphabetically sorted order in _queueMap, now sort for queueDepth + java.util.List<AttributeData> list = new ArrayList<AttributeData>(_queueDepthMap.keySet()); + Collections.sort(list, _sorterByAttribute); + + String[] items = new String[list.size()]; + int i = 0; + for (AttributeData data : list) + { + ManagedBean mbean = _queueDepthMap.get(data); + String value = data.getValue().toString(); + items[i++] = mbean.getName() + " (" + value + " KB)"; + } + getListWidget().setItems(items); + } + + private void sortQueuesByConsumerCount() + { + java.util.List<AttributeData> list = new ArrayList<AttributeData>(_queueConsumerCountMap.keySet()); + Collections.sort(list, _sorterByAttribute); + + String[] items = new String[list.size()]; + int i = 0; + for (AttributeData data : list) + { + ManagedBean mbean = _queueConsumerCountMap.get(data); + String value = data.getValue().toString(); + items[i++] = mbean.getName() + " (" + value + " )"; + } + getListWidget().setItems(items); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java new file mode 100644 index 0000000000..c13c92066c --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java @@ -0,0 +1,102 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.views; + +import java.util.ArrayList; + +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.model.OperationData; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.TabFolder; + +/** + * Abstract class for all the control classes of tabs. + * @author Bhupendra Bhardwaj + */ +public abstract class TabControl +{ + protected ManagedBean _mbean = null; + protected TabFolder _tabFolder = null; + + private static java.util.List<String> simpleTypes = new ArrayList<String>(); + + static + { + simpleTypes.add("java.math.BigDecimal"); + simpleTypes.add("java.math.BigInteger"); + simpleTypes.add("java.lang.Boolean"); + simpleTypes.add("java.lang.Byte"); + simpleTypes.add("java.lang.Character"); + simpleTypes.add("java.util.Date"); + simpleTypes.add("java.lang.Double"); + simpleTypes.add("java.lang.Float"); + simpleTypes.add("java.lang.Integer"); + simpleTypes.add("java.lang.Long"); + simpleTypes.add("javax.management.ObjectName"); + simpleTypes.add("java.lang.Short"); + simpleTypes.add("java.lang.String"); + simpleTypes.add("boolean"); + } + + public TabControl(TabFolder tabFolder) + { + _tabFolder = tabFolder; + } + + /** + * @return controller composite for the tab + */ + public Control getControl() + { + return null; + } + + public void refresh(ManagedBean mbean) + { + if (mbean == null) + { + refresh(); + } + } + + public void refresh() + { + + } + + public void refresh(ManagedBean mbean, OperationData opData) + { + + } + + /** + * Sets focus on a widget + */ + public void setFocus() + { + + } + + public boolean isSimpleType(Object data) + { + return simpleTypes.contains(data.getClass().getName()); + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java new file mode 100644 index 0000000000..9545ed9876 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java @@ -0,0 +1,126 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.views; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ManagedObject; + +public class TreeObject +{ + private String _name; + private String _type; + private String _virtualHost; + private TreeObject _parent; + private List<TreeObject> _children = new ArrayList<TreeObject>(); + private ManagedObject _object; + + public TreeObject(String name, String type) + { + this._name = name; + this._type = type; + } + + public TreeObject(ManagedObject obj) + { + _name = obj.getName(); + if (_name == null && (obj instanceof ManagedBean)) + { + String[] types = ((ManagedBean)obj).getType().split("\\."); + _name = types[types.length - 1]; + } + this._type = Constants.MBEAN; + this._object = obj; + } + + public void addChild(TreeObject child) + { + _children.add(child); + } + + public void addChildren(List<TreeObject> subList) + { + _children.addAll(subList); + } + + public List<TreeObject> getChildren() + { + return _children; + } + + public void setChildren(List<TreeObject> children) + { + this._children = children; + } + + public void setName(String value) + { + _name = value; + } + + public String getName() + { + return _name; + } + public String getType() + { + return _type; + } + + public String getVirtualHost() + { + // To make it work with the broker with no virtual host implementation + return _virtualHost == null ? Constants.DEFAULT_VH : _virtualHost; + } + + public void setVirtualHost(String vHost) + { + _virtualHost = vHost; + } + + public ManagedObject getManagedObject() + { + return _object; + } + + public void setManagedObject(ManagedObject obj) + { + this._object = obj; + } + + public TreeObject getParent() + { + return _parent; + } + + public void setParent(TreeObject parent) + { + this._parent = parent; + + if (parent != null) + { + parent.addChild(this); + } + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java new file mode 100644 index 0000000000..be25707bd3 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java @@ -0,0 +1,483 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.management.ui.views; + +import static org.apache.qpid.management.ui.Constants.BUTTON_CLEAR; +import static org.apache.qpid.management.ui.Constants.BUTTON_REFRESH; +import static org.apache.qpid.management.ui.Constants.CONSOLE_IMAGE; +import static org.apache.qpid.management.ui.Constants.FONT_BUTTON; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ServerRegistry; +import org.apache.qpid.management.ui.model.NotificationObject; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.widgets.Form; +import org.eclipse.ui.forms.widgets.FormToolkit; + +public class VHNotificationsTabControl extends TabControl +{ + protected FormToolkit _toolkit; + protected Form _form; + protected Table _table = null; + protected TableViewer _tableViewer = null; + + protected Thread worker = null; + + protected List<NotificationObject> _notifications = null; + + private static final String COLUMN_OBJ = "Object Name"; + private static final String COLUMN_SEQ = "Sequence No"; + private static final String COLUMN_TIME = "TimeStamp"; + private static final String COLUMN_TYPE = "Type"; + private static final String COLUMN_MSG = "Notification Message"; + protected static final String[] _tableTitles = new String [] { + COLUMN_OBJ, + COLUMN_SEQ, + COLUMN_TIME, + COLUMN_TYPE, + COLUMN_MSG + }; + + protected Button _clearButton = null; + protected Button _refreshButton = null; + + public VHNotificationsTabControl(TabFolder tabFolder) + { + super(tabFolder); + _toolkit = new FormToolkit(_tabFolder.getDisplay()); + _form = _toolkit.createForm(_tabFolder); + GridLayout gridLayout = new GridLayout(); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + _form.getBody().setLayout(gridLayout); + + worker = new Thread(new Worker()); + worker.start(); + } + + protected void createWidgets() + { + addButtons(); + createTableViewer(); + } + + /** + * @see TabControl#getControl() + */ + public Control getControl() + { + if (_table == null) + { + createWidgets(); + } + return _form; + } + + /** + * Creates clear buttin and refresh button + */ + protected void addButtons() + { + Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + composite.setLayout(new GridLayout(2, true)); + + // Add Clear Button + _clearButton = _toolkit.createButton(composite, BUTTON_CLEAR, SWT.PUSH | SWT.CENTER); + _clearButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); + GridData gridData = new GridData(SWT.LEAD, SWT.TOP, true, false); + gridData.widthHint = 80; + _clearButton.setLayoutData(gridData); + _clearButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + //TODO : Get selected rows and clear those + IStructuredSelection ss = (IStructuredSelection)_tableViewer.getSelection(); + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer()); + serverRegistry.clearNotifications(null, ss.toList()); + refresh(); + } + }); + + // Add Refresh Button + _refreshButton = _toolkit.createButton(composite, BUTTON_REFRESH, SWT.PUSH | SWT.CENTER); + _refreshButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); + gridData = new GridData(SWT.TRAIL, SWT.TOP, true, false); + gridData.widthHint = 80; + _refreshButton.setLayoutData(gridData); + _refreshButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + refresh(); + } + }); + } + + /** + * Creates table to display notifications + */ + private void createTable() + { + _table = _toolkit.createTable(_form.getBody(), SWT.MULTI | SWT.FULL_SELECTION); + _table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + TableColumn column = new TableColumn(_table, SWT.NONE); + column.setText(_tableTitles[0]); + column.setWidth(100); + + column = new TableColumn(_table, SWT.NONE); + column.setText(_tableTitles[1]); + column.setWidth(100); + + column = new TableColumn(_table, SWT.NONE); + column.setText(_tableTitles[2]); + column.setWidth(130); + + column = new TableColumn(_table, SWT.NONE); + column.setText(_tableTitles[3]); + column.setWidth(100); + + column = new TableColumn(_table, SWT.NONE); + column.setText(_tableTitles[4]); + column.setWidth(500); + + _table.setHeaderVisible(true); + _table.setLinesVisible(true); + } + + /** + * Creates JFace viewer for the notifications table + */ + protected void createTableViewer() + { + createTable(); + _tableViewer = new TableViewer(_table); + //_tableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + _tableViewer.setUseHashlookup(true); + _tableViewer.setContentProvider(new ContentProviderImpl()); + _tableViewer.setLabelProvider(new LabelProviderImpl()); + _tableViewer.setColumnProperties(_tableTitles); + /* + CellEditor[] cellEditors = new CellEditor[_tableTitles.length]; + TextCellEditor textEditor = new TextCellEditor(table); + cellEditors[0] = textEditor; + textEditor = new TextCellEditor(table); + cellEditors[1] = textEditor; + textEditor = new TextCellEditor(table); + cellEditors[2] = textEditor; + textEditor = new TextCellEditor(table); + cellEditors[3] = textEditor; + + // Assign the cell editors to the viewer + _tableViewer.setCellEditors(cellEditors); + _tableViewer.setCellModifier(new TableCellModifier()); + */ + + addTableListeners(); + + //_tableViewer.addSelectionChangedListener(new ); + + //_notificationDetails = new Composite(_tabControl, SWT.BORDER); + //_notificationDetails.setLayoutData(new GridData(GridData.FILL_BOTH)); + + //_tabControl.layout(); + //viewerComposite.layout(); + } + + /** + * Adds listeners to the viewer for displaying notification details + */ + protected void addTableListeners() + { + _tableViewer.addDoubleClickListener(new IDoubleClickListener() + { + Display display = null; + Shell shell = null; + public void doubleClick(DoubleClickEvent event) + { + display = Display.getCurrent(); + shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN | SWT.MAX | SWT.RESIZE); + shell.setText("Notification"); + shell.setImage(ApplicationRegistry.getImage(CONSOLE_IMAGE)); + + int x = display.getBounds().width; + int y = display.getBounds().height; + shell.setBounds(x/4, y/4, x/2, y/3); + StructuredSelection selection = (StructuredSelection)event.getSelection(); + createPopupContents((NotificationObject)selection.getFirstElement()); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + //If you create it, you dispose it. + shell.dispose(); + } + + private void createPopupContents(NotificationObject obj) + { + shell.setLayout(new GridLayout()); + + Composite parent = _toolkit.createComposite(shell, SWT.NONE); + parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout layout = new GridLayout(4, true); + parent.setLayout(layout); + + // Object name record + Label key = _toolkit.createLabel(parent, COLUMN_OBJ, SWT.TRAIL); + GridData layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false,1,1); + key.setLayoutData(layoutData); + Text value = _toolkit.createText(parent, obj.getSourceName(), SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1)); + + // Sequence no record + key = _toolkit.createLabel(parent, COLUMN_SEQ, SWT.TRAIL); + layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false,1,1); + key.setLayoutData(layoutData); + value = _toolkit.createText(parent, ""+obj.getSequenceNo(), SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1)); + + // Time row + key = _toolkit.createLabel(parent, COLUMN_TIME, SWT.TRAIL); + key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1)); + value = _toolkit.createText(parent, obj.getTimeStamp(), SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1)); + + key = _toolkit.createLabel(parent, COLUMN_TYPE, SWT.TRAIL); + key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1)); + value = _toolkit.createText(parent, obj.getType(), SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1)); + + key = _toolkit.createLabel(parent, COLUMN_MSG, SWT.TRAIL); + key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1)); + value = _toolkit.createText(parent, obj.getMessage(), SWT.MULTI | SWT.WRAP| SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1); + gridData.heightHint = 100; + value.setLayoutData(gridData); + } + }); + } + + public void refresh() + { + _notifications = null; + _table.deselectAll(); + _tableViewer.getTable().clearAll(); + + Control[] children = _form.getBody().getChildren(); + for (int i = 0; i < children.length; i++) + { + children[i].setVisible(true); + } + + workerRunning = true; + _form.layout(true); + _form.getBody().layout(true, true); + } + + /** + * Content provider class for the table viewer + */ + protected class ContentProviderImpl implements IStructuredContentProvider, INotificationViewer + { + public void inputChanged(Viewer v, Object oldInput, Object newInput) + { + + } + public void dispose() + { + + } + public Object[] getElements(Object parent) + { + return _notifications.toArray(new NotificationObject[0]); + } + public void addNotification(NotificationObject notification) + { + _tableViewer.add(notification); + } + + public void addNotification(List<NotificationObject> notificationList) + { + _tableViewer.add(notificationList.toArray(new NotificationObject[0])); + } + } + + /** + * Label provider for the table viewer + */ + protected class LabelProviderImpl implements ITableLabelProvider + { + List<ILabelProviderListener> listeners = new ArrayList<ILabelProviderListener>(); + public void addListener(ILabelProviderListener listener) + { + listeners.add(listener); + } + + public void dispose(){ + + } + + public Image getColumnImage(Object element, int columnIndex) + { + return null; + } + + public String getColumnText(Object element, int columnIndex) + { + String result = null; + NotificationObject t = (NotificationObject)element; + switch(columnIndex) + { + case 0 : + result = t.getSourceName(); + break; + case 1 : + result = String.valueOf(t.getSequenceNo()); + break; + case 2 : + result = String.valueOf(t.getTimeStamp()); + break; + case 3 : + result = t.getType(); + break; + case 4 : + result = t.getMessage(); + break; + default : + result = ""; + } + + return result; + } + + public boolean isLabelProperty(Object element, String property) + { + return false; + } + + public void removeListener(ILabelProviderListener listener) + { + listeners.remove(listener); + } + } // end of LabelProviderImpl + + protected boolean workerRunning = false; + protected void setWorkerRunning(boolean running) + { + workerRunning = running; + } + + /** + * Worker class which keeps looking if there are new notifications coming from server for the selected mbean + */ + private class Worker implements Runnable + { + public void run() + { + Display display = _tabFolder.getDisplay(); + while(true) + { + if (!workerRunning || display == null) + { + sleep(); + continue; + } + + display.syncExec(new Runnable() + { + public void run() + { + if (_form == null || _form.isDisposed()) + return; + setWorkerRunning(_form.isVisible()); + if (!workerRunning) return; + + updateTableViewer(); + } + }); + + sleep(); + } + } + + private void sleep() + { + try + { + Thread.sleep(2000); + } + catch(Exception ex) + { + + } + } + } + + /** + * Updates the table with new notifications received from mbean server for all mbeans + */ + protected void updateTableViewer() + { + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer()); + List<NotificationObject> newList = serverRegistry.getNotifications(null); + if (newList == null) + return; + + _notifications = newList; + _tableViewer.setInput(_notifications); + _tableViewer.refresh(); + } + +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java new file mode 100644 index 0000000000..5d6a03b238 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java @@ -0,0 +1,593 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.views; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.TabularDataSupport; +import javax.management.openmbean.TabularType; + +import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.widgets.FormToolkit; + +/** + * Utility Class for displaying OpenMbean data types by creating required SWT widgets + * @author Bhupendra Bhardwaj + */ +public class ViewUtility +{ + public static final String OP_NAME = "operation_name"; + public static final String OP_PARAMS = "parameters"; + public static final String PARAMS_TEXT = "text"; + + public static final String FIRST = "First"; + public static final String LAST = "Last"; + public static final String NEXT = "Next"; + public static final String PREV = "Previous"; + public static final String INDEX = "Index"; + + private static final Comparator tabularDataComparator = new TabularDataComparator(); + + private static List<String> SUPPORTED_ARRAY_DATATYPES = new ArrayList<String>(); + static + { + SUPPORTED_ARRAY_DATATYPES.add("java.lang.String"); + SUPPORTED_ARRAY_DATATYPES.add("java.lang.Boolean"); + SUPPORTED_ARRAY_DATATYPES.add("java.lang.Character"); + SUPPORTED_ARRAY_DATATYPES.add("java.lang.Integer"); + SUPPORTED_ARRAY_DATATYPES.add("java.lang.Long"); + SUPPORTED_ARRAY_DATATYPES.add("java.lang.Double"); + SUPPORTED_ARRAY_DATATYPES.add("java.util.Date"); + } + + /** + * Populates the composite with given openmbean data type (TabularType or CompositeType) + * @param toolkit + * @param parent composite + * @param data open mbean data type(either composite type or tabular data type) + */ + public static void populateCompositeWithData(FormToolkit toolkit, Composite parent, Object data) + { + if (data instanceof TabularDataSupport) + { + ViewUtility.createTabularDataHolder(toolkit, parent, (TabularDataSupport)data); + } + else if (data instanceof CompositeDataSupport) + { + ViewUtility.populateCompositeWithCompositeData(toolkit, parent, (CompositeDataSupport)data); + } + } + + @SuppressWarnings("unchecked") + private static void createTabularDataHolder(FormToolkit toolkit, Composite parent, TabularDataSupport tabularData) + { + Composite composite = toolkit.createComposite(parent, SWT.BORDER); + GridLayout layout = new GridLayout(4, true); + layout.horizontalSpacing = 0; + layout.marginWidth = 0; + layout.marginHeight = 10; + layout.verticalSpacing = 10; + composite.setLayout(layout); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + Set entrySet = tabularData.entrySet(); + ArrayList<Map.Entry> list = new ArrayList<Map.Entry>(entrySet); + if (list.size() == 0) + { + Text text = toolkit.createText(composite, " No records ", SWT.CENTER | SWT.SINGLE | SWT.READ_ONLY); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1); + text.setLayoutData(layoutData); + return; + } + + Collections.sort(list, tabularDataComparator); + + // Attach the tabular record to be retrieved and shown later when record is traversed + // using first/next/previous/last buttons + composite.setData(list); + + // Create button and the composite for CompositeData + Composite compositeDataHolder = createCompositeDataHolder(toolkit, composite, + tabularData.getTabularType().getRowType()); + + // display the first record + CompositeData data = (CompositeData)(list.get(0)).getValue(); + composite.setData(INDEX, 0); + populateCompositeWithCompositeData(toolkit, compositeDataHolder, data); + enableOrDisableTraversalButtons(composite); + } + + private static void enableOrDisableTraversalButtons(Composite composite) + { + int index = (Integer)composite.getData(INDEX); + int size = ((List)composite.getData()).size(); + + ((Button)composite.getData(FIRST)).setEnabled(true); + ((Button)composite.getData(PREV)).setEnabled(true); + ((Button)composite.getData(NEXT)).setEnabled(true); + ((Button)composite.getData(LAST)).setEnabled(true); + + if (index == 0) + { + ((Button)composite.getData(FIRST)).setEnabled(false); + ((Button)composite.getData(PREV)).setEnabled(false); + } + if (index == size -1) + { + ((Button)composite.getData(NEXT)).setEnabled(false); + ((Button)composite.getData(LAST)).setEnabled(false); + } + } + + /** + * Sets up the given composite for holding a CompositeData. Create traversal buttons, label etc and + * creates a child Composite, which should be populated with the CompositeData + * @param toolkit + * @param dataHolder + * @param compositeType + * @return + */ + private static Composite createCompositeDataHolder(final FormToolkit toolkit, final Composite dataHolder, CompositeType compositeType) + { + String desc = compositeType.getDescription(); + Label description = toolkit.createLabel(dataHolder, desc, SWT.CENTER); + description.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false, 4, 1)); + // TODO nameLabel.setFont(font); + description.setText(desc); + + // Add traversal buttons + final Button firstRecordButton = toolkit.createButton(dataHolder, FIRST, SWT.PUSH); + GridData layoutData = new GridData (GridData.HORIZONTAL_ALIGN_END); + layoutData.widthHint = 80; + firstRecordButton.setLayoutData(layoutData); + + final Button nextRecordButton = toolkit.createButton(dataHolder, NEXT, SWT.PUSH); + layoutData = new GridData (GridData.HORIZONTAL_ALIGN_END); + layoutData.widthHint = 80; + nextRecordButton.setLayoutData(layoutData); + + final Button previousRecordButton = toolkit.createButton(dataHolder, PREV, SWT.PUSH); + layoutData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING); + layoutData.widthHint = 80; + previousRecordButton.setLayoutData(layoutData); + + final Button lastRecordButton = toolkit.createButton(dataHolder, LAST, SWT.PUSH); + layoutData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING); + layoutData.widthHint = 80; + lastRecordButton.setLayoutData(layoutData); + + // Now create the composite, which will hold the CompositeData + final Composite composite = toolkit.createComposite(dataHolder, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.horizontalSpacing = layout.verticalSpacing = 0; + layout.marginHeight = layout.marginWidth = 0; + composite.setLayout(layout); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1)); + + // Add button references. These references will be used when buttons + // are to enabled or disabled based of record index. e.g. for first record + // First and Previous buttons will be disabled. + dataHolder.setData(FIRST, firstRecordButton); + dataHolder.setData(NEXT, nextRecordButton); + dataHolder.setData(PREV, previousRecordButton); + dataHolder.setData(LAST, lastRecordButton); + + // Listener for the traversal buttons. When a button is clicked the respective + // CompositeData will be populated in the composite + SelectionListener listener = new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + if (!(e.widget instanceof Button)) + return; + + Button traverseButton =(Button)e.widget; + // Get the CompositeData respective to the button selected + CompositeData data = getCompositeData(dataHolder, traverseButton.getText()); + populateCompositeWithCompositeData(toolkit, composite, data); + enableOrDisableTraversalButtons(dataHolder); + } + }; + + firstRecordButton.addSelectionListener(listener); + nextRecordButton.addSelectionListener(listener); + previousRecordButton.addSelectionListener(listener); + lastRecordButton.addSelectionListener(listener); + + return composite; + } + + /** + * The CompositeData is set as data with the Composite and using the index, this method will + * return the corresponding CompositeData + * @param compositeHolder + * @param dataIndex + * @return the CompositeData respective to the index + */ + private static CompositeData getCompositeData(Composite compositeHolder, String dataIndex) + { + List objectData = (List)compositeHolder.getData(); + if (objectData == null || objectData.isEmpty()) + { + // TODO + } + + // Get the index of record to be shown. + int index = 0; + if (compositeHolder.getData(INDEX) != null) + { + index = (Integer)compositeHolder.getData(INDEX); + } + + if (FIRST.equals(dataIndex)) + { + index = 0; + } + else if (NEXT.equals(dataIndex)) + { + index = index + 1; + } + else if (PREV.equals(dataIndex)) + { + index = (index != 0) ? (index = index - 1) : index; + } + else if (LAST.equals(dataIndex)) + { + index = objectData.size() -1; + } + + // Set the index being shown. + compositeHolder.setData(INDEX, index); + + return (CompositeData)((Map.Entry)objectData.get(index)).getValue(); + } + + /** + * Populates the given composite with the CompositeData. Creates required widgets to hold the data types + * @param toolkit + * @param parent + * @param data CompositeData + */ + @SuppressWarnings("unchecked") + private static void populateCompositeWithCompositeData(FormToolkit toolkit, Composite parent, CompositeData data) + { + Control[] oldControls = parent.getChildren(); + for (int i = 0; i < oldControls.length; i++) + { + oldControls[i].dispose(); + } + + Composite compositeHolder = toolkit.createComposite(parent, SWT.NONE); + GridLayout layout = new GridLayout(4, false); + layout.horizontalSpacing = 10; + compositeHolder.setLayout(layout); + compositeHolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + + // ItemNames in composite data + List<String> itemNames = new ArrayList<String>(data.getCompositeType().keySet()); + + for (String itemName : itemNames) + { + OpenType itemType = data.getCompositeType().getType(itemName); + Label keyLabel = toolkit.createLabel(compositeHolder, itemName, SWT.TRAIL); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1); + layoutData.minimumWidth = 70; + keyLabel.setLayoutData(layoutData); + + if (itemType.isArray()) + { + OpenType type = ((ArrayType)itemType).getElementOpenType(); + // If Byte array and mimetype is text, convert to text string + if (type.getClassName().equals(Byte.class.getName())) + { + String mimeType = null; + String encoding = null; + if (data.containsKey("MimeType")) + { + mimeType = (String)data.get("MimeType"); + } + if (data.containsKey("Encoding")) + { + encoding = (String)data.get("Encoding"); + } + + if (encoding == null || encoding.length() == 0) + { + encoding = Charset.defaultCharset().name(); + } + + if ("text/plain".equals(mimeType)) + { + convertByteArray(toolkit, compositeHolder, data, itemName, encoding); + } + else + { + setNotSupportedDataType(toolkit, compositeHolder); + } + } + // If array of any other supported type, show as a list of String array + else if (SUPPORTED_ARRAY_DATATYPES.contains(type.getClassName())) + { + convertArrayItemForDisplay(compositeHolder, data, itemName); + } + else + { + setNotSupportedDataType(toolkit, compositeHolder); + } + } + else if (itemType instanceof TabularType) + { + Composite composite = toolkit.createComposite(compositeHolder, SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1)); + layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + composite.setLayout(layout); + createTabularDataHolder(toolkit, composite, (TabularDataSupport)data.get(itemName)); + } + else + { + Text valueText = toolkit.createText(compositeHolder, String.valueOf(data.get(itemName)), SWT.READ_ONLY | SWT.BORDER); + valueText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1)); + } + } + + // layout the composite after creating new widgets. + parent.layout(); + } //end of method + + + private static void convertByteArray(FormToolkit toolkit, Composite compositeHolder, CompositeData data, String itemName, String encoding) + { + Byte[] arrayItems = (Byte[])data.get(itemName); + byte[] byteArray = new byte[arrayItems.length]; + + for (int i = 0; i < arrayItems.length; i++) + { + byteArray[i] = arrayItems[i]; + } + try + { + String textMessage = new String(byteArray, encoding); + + Text valueText = toolkit.createText(compositeHolder, textMessage, SWT.READ_ONLY | SWT.BORDER | + SWT.MULTI | SWT.WRAP | SWT.V_SCROLL); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1); + gridData.heightHint = 300; + valueText.setLayoutData(gridData); + } + catch(Exception ex) + { + ex.printStackTrace(); + } + } + + private static Shell getShell() + { + Shell shell = Display.getCurrent().getActiveShell(); + + // Under linux GTK getActiveShell returns null so we need to make a new shell for display. + // Under windows this is fine. + if (shell == null) + { + // This occurs under linux gtk + shell = new Shell(Display.getCurrent(), SWT.BORDER | SWT.CLOSE | SWT.MIN | SWT.MAX); + } + + return shell; + } + + private static int showBox(String title, String message, int icon) + { + MessageBox messageBox = new MessageBox(getShell(), icon); + messageBox.setMessage(message); + messageBox.setText(title); + + return messageBox.open(); + } + + public static int popupInfoMessage(String title, String message) + { + return showBox(title, message, SWT.ICON_INFORMATION | SWT.OK); + } + + public static int popupErrorMessage(String title, String message) + { + return showBox(title, message, SWT.ICON_ERROR | SWT.OK); + } + + public static int popupConfirmationMessage(String title, String message) + { + return showBox(title, message,SWT.ICON_QUESTION | SWT.YES | SWT.NO | SWT.CANCEL); + } + + + public static Shell createPopupShell(String title, int width, int height) + { + Display display = Display.getCurrent(); + Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN |SWT.MAX); + shell.setText(title); + shell.setLayout(new GridLayout()); + int x = display.getBounds().width; + int y = display.getBounds().height; + shell.setBounds(x/4, y/4, width, height); + + return shell; + } + + /** + * Creates a List widget for displaying array of strings + * @param compositeHolder + * @param data - containing the array item value + * @param itemName - item name + */ + private static void convertArrayItemForDisplay(Composite compositeHolder, CompositeData data, String itemName) + { + Object[] arrayItems = (Object[])data.get(itemName); + String[] items = new String[arrayItems.length]; + for (int i = 0; i < arrayItems.length; i++) + { + items[i] = String.valueOf(arrayItems[i]); + } + org.eclipse.swt.widgets.List list = new org.eclipse.swt.widgets.List(compositeHolder, + SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY); + list.setItems(items); + //list.setBackground(compositeHolder.getBackground()); + list.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); + } + + private static void setNotSupportedDataType(FormToolkit toolkit, Composite compositeHolder) + { + Text valueText = toolkit.createText(compositeHolder, "--- Content can not be displayed ---", SWT.READ_ONLY); + valueText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1)); + } + + /** + * Converts the input string to displayable format by converting some character case or inserting space + * @param input + * @return formatted string + */ + public static String getDisplayText(String input) + { + StringBuffer result = new StringBuffer(input); + if (Character.isLowerCase(result.charAt(0))) + { + result.setCharAt(0, Character.toUpperCase(result.charAt(0))); + } + for (int i = 1; i < input.length(); i++) + { + if (Character.isUpperCase(result.charAt(i)) && !Character.isWhitespace(result.charAt(i - 1)) + && Character.isLowerCase(result.charAt(i - 1))) + { + result.insert(i, " "); + i++; + } + else if (Character.isLowerCase(result.charAt(i)) && Character.isWhitespace(result.charAt(i - 1))) + { + result.setCharAt(i, Character.toUpperCase(result.charAt(i))); + } + + } + + return result.toString(); + } + + /** + * Disposes the children of given Composite if not null and not already disposed + * @param parent composite + */ + public static void disposeChildren(Composite parent) + { + if (parent == null || parent.isDisposed()) + return; + + Control[] oldControls = parent.getChildren(); + for (int i = 0; i < oldControls.length; i++) + { + oldControls[i].dispose(); + } + } + + public static char[] getHash(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException + { + byte[] data = text.getBytes("utf-8"); + + MessageDigest md = MessageDigest.getInstance("MD5"); + + for (byte b : data) + { + md.update(b); + } + + byte[] digest = md.digest(); + + char[] hash = new char[digest.length ]; + + int index = 0; + for (byte b : digest) + { + hash[index++] = (char) b; + } + + return hash; + } + + private static class TabularDataComparator implements java.util.Comparator<Map.Entry> + { + public int compare(Map.Entry data1, Map.Entry data2) + { + if (data1.getKey() instanceof List) + { + Object obj1 = ((List)data1.getKey()).get(0); + Object obj2 = ((List)data2.getKey()).get(0); + String str1 = obj1.toString(); + String str2 = obj2.toString(); + if (obj1 instanceof String) + { + return str1.compareTo(str2); + } + + try + { + return Long.valueOf(str1).compareTo(Long.valueOf(str2)); + } + catch (Exception ex) + { + return -1; + } + } + + return -1; + } + } +} diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/resources/.eclipseproduct b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/.eclipseproduct new file mode 100644 index 0000000000..28ee27ca17 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/.eclipseproduct @@ -0,0 +1,23 @@ +#Eclipse Product File
+#Fri Nov 03 14:47:54 GMT 2006
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+version=1.0-incubating-M2-SNAPSHOT
+name=Qpid Management Console
+id=org.apache.qpid.manager.gui.product
diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/resources/eclipse.exe b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/eclipse.exe Binary files differnew file mode 100644 index 0000000000..7826d1ed80 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/eclipse.exe diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/resources/eclipse.ini b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/eclipse.ini new file mode 100644 index 0000000000..f56524580d --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/eclipse.ini @@ -0,0 +1,23 @@ +############################################################################### +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +############################################################################### + +-vmargs
+-Xms40m
+-Xmx256m
+-Declipse.consoleLog=true
diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/resources/icons/Console.icns b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/icons/Console.icns Binary files differnew file mode 100644 index 0000000000..610976efab --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/icons/Console.icns diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/resources/license.eclipse.txt b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/license.eclipse.txt new file mode 100644 index 0000000000..da433e89f9 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/license.eclipse.txt @@ -0,0 +1,88 @@ +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and +b) in the case of each subsequent Contributor: + +i) changes to the Program, and + +ii) additions to the Program; + +where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. + +b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. + +c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. + +d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and + +b) its license agreement: + +i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; + +ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; + +iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and + +iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and + +b) a copy of this Agreement must be included with each copy of the Program. + +Contributors may not remove or alter any copyright notices contained within the Program. + +Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. + + diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini new file mode 100644 index 0000000000..fe1a9fe2c2 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini @@ -0,0 +1,30 @@ +############################################################################### +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +############################################################################### + +#Product Runtime Configuration File + +org.eclipse.update.reconcile=false +osgi.splashPath=platform\:/base/plugins/org.eclipse.platform +eclipse.product=org.apache.qpid.management.ui.product +eclipse.application=org.apache.qpid.management.ui.application + +osgi.bundles=org.eclipse.equinox.common@2:start,org.eclipse.core.runtime@start,com.ibm.icu,org.apache.qpid.management.ui,org.eclipse.core.commands,org.eclipse.core.contenttype,org.eclipse.core.expressions,org.eclipse.core.jobs,org.eclipse.core.runtime.compatibility.auth,org.eclipse.core.runtime.compatibility.registry,org.eclipse.equinox.preferences,org.eclipse.equinox.registry,org.eclipse.help,org.eclipse.jface,org.eclipse.swt,org.eclipse.swt.carbon.macosx,org.eclipse.ui,org.eclipse.ui.forms,org.eclipse.ui.workbench,org.eclipse.equinox.app,org.eclipse.core.databinding,org.eclipse.jface.databinding,jmxremote.sasl + +osgi.bundles.defaultStartLevel=4 +eof=eof diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Info.plist b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Info.plist new file mode 100644 index 0000000000..77f79a2944 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Info.plist @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleExecutable</key> + <string>eclipse</string> + <key>CFBundleGetInfoString</key> + <string>Apache Qpid Management Console for Mac OS X</string> + <key>CFBundleIconFile</key> + <string>Console.icns</string> + <key>CFBundleIdentifier</key> + <string>org.apache.qpid.management.ui</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>Qpid Management Console</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>3.4</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>3.4</string> + <key>Qpid Management Console</key> + <array> + <string>-consoleLog</string> + <string>-showlocation</string> + </array> +</dict> +</plist> diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/resources/macosx/eclipse b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/macosx/eclipse Binary files differnew file mode 100755 index 0000000000..36247a08e4 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/macosx/eclipse diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/resources/macosx/eclipse.ini b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/macosx/eclipse.ini new file mode 100644 index 0000000000..d3c2505730 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/macosx/eclipse.ini @@ -0,0 +1,14 @@ +-showsplash +org.eclipse.platform +-startup +../../plugins/org.eclipse.equinox.launcher_1.0.101.R34x_v20080819.jar +--launcher.library +../../plugins/org.eclipse.equinox.launcher.carbon.macosx_1.0.101.R34x_v20080731 +-vmargs +#-Xdock:icon=../Resources/Eclipse.icns +-XstartOnFirstThread +-Xms40m +-Xmx512m +-XX:MaxPermSize=256m +-Dosgi.requiredJavaVersion=1.5 +-Dorg.eclipse.swt.internal.carbon.smallFonts diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/resources/sasl/MANIFEST.MF b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/sasl/MANIFEST.MF new file mode 100644 index 0000000000..fa11bac2ea --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/sasl/MANIFEST.MF @@ -0,0 +1,19 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: jmx sasl Plug-in +Bundle-SymbolicName: jmxremote.sasl +Bundle-Version: 1.0.1 +Bundle-ClassPath: jmxremote_optional.jar +Export-Package: com.sun.jmx.remote.generic, + com.sun.jmx.remote.opt.internal, + com.sun.jmx.remote.opt.security, + com.sun.jmx.remote.opt.util, + com.sun.jmx.remote.profile.sasl, + com.sun.jmx.remote.profile.tls, + com.sun.jmx.remote.protocol.jmxmp, + com.sun.jmx.remote.socket, + javax.management.remote.generic, + javax.management.remote.jmxmp, + javax.management.remote.message +Bundle-Vendor: +Bundle-Localization: plugin diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/resources/startup.jar b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/startup.jar Binary files differnew file mode 100644 index 0000000000..2f26eceece --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/startup.jar diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/resources/unix/configuration/config.ini b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/unix/configuration/config.ini new file mode 100644 index 0000000000..5bbf344c17 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/unix/configuration/config.ini @@ -0,0 +1,27 @@ +###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+###############################################################################
+
+#Product Runtime Configuration File
+
+osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui
+eclipse.product=org.apache.qpid.management.ui.product
+eclipse.application=org.apache.qpid.management.ui.application
+osgi.bundles=org.eclipse.equinox.common@2:start,org.eclipse.core.runtime@start,com.ibm.icu,org.apache.qpid.management.ui,org.eclipse.core.commands,org.eclipse.core.contenttype,org.eclipse.core.expressions,org.eclipse.core.jobs,org.eclipse.core.runtime.compatibility.auth,org.eclipse.core.runtime.compatibility.registry,org.eclipse.equinox.preferences,org.eclipse.equinox.registry,org.eclipse.help,org.eclipse.jface,org.eclipse.swt,org.eclipse.swt.gtk.linux.x86,org.eclipse.ui,org.eclipse.ui.forms,org.eclipse.ui.workbench,jmxremote.sasl
+osgi.bundles.defaultStartLevel=4
+eof=eof
diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/resources/unix/eclipse.ini b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/unix/eclipse.ini new file mode 100644 index 0000000000..33884bd8f1 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/unix/eclipse.ini @@ -0,0 +1,11 @@ +-startup +plugins/org.eclipse.equinox.launcher_1.0.101.R34x_v20080819.jar +--launcher.library +plugins/org.eclipse.equinox.launcher.gtk.linux.x86_1.0.101.R34x_v20080805 +#-showsplash +#org.eclipse.platform +--launcher.XXMaxPermSize +256m +-vmargs +-Xms40m +-Xmx256m diff --git a/RC9/qpid/java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini new file mode 100644 index 0000000000..e83321e650 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini @@ -0,0 +1,26 @@ +###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+###############################################################################
+
+#Product Runtime Configuration File
+
+osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui
+eclipse.product=org.apache.qpid.management.ui.product
+eclipse.application=org.apache.qpid.management.ui.application
+osgi.bundles=org.eclipse.equinox.common@2:start,org.eclipse.core.runtime@start,com.ibm.icu,org.apache.qpid.management.ui,org.eclipse.core.commands,org.eclipse.core.contenttype,org.eclipse.core.expressions,org.eclipse.core.jobs,org.eclipse.core.runtime.compatibility.auth,org.eclipse.core.runtime.compatibility.registry,org.eclipse.equinox.preferences,org.eclipse.equinox.registry,org.eclipse.help,org.eclipse.jface,org.eclipse.swt,org.eclipse.swt.win32.win32.x86,org.eclipse.ui,org.eclipse.ui.forms,jmxremote.sasl,org.eclipse.ui.workbench
+osgi.bundles.defaultStartLevel=4
diff --git a/RC9/qpid/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ManagementConsoleTest.java b/RC9/qpid/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ManagementConsoleTest.java new file mode 100644 index 0000000000..11ab6af064 --- /dev/null +++ b/RC9/qpid/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ManagementConsoleTest.java @@ -0,0 +1,126 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +import junit.framework.TestCase; +import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.exchange.DirectExchange; +import org.apache.qpid.server.management.AMQManagedObject; +import org.apache.qpid.server.queue.AMQQueueMBean; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.queue.AMQQueueFactory; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.registry.IApplicationRegistry; +import org.apache.qpid.server.virtualhost.VirtualHost; + +import javax.management.MBeanFeatureInfo; +import javax.management.MBeanInfo; +import java.util.ArrayList; +import java.util.List; + + +/** + * Test class to test if any change in the broker JMX code is affesting the management console + * There are some hardcoding of management feature names and parameter names to create a customized + * look in the console. + */ +public class ManagementConsoleTest extends TestCase +{ + private VirtualHost _virtualHost; + + @Override + protected void setUp() throws Exception + { + super.setUp(); + IApplicationRegistry applicationRegistry = ApplicationRegistry.getInstance(); + _virtualHost = applicationRegistry.getVirtualHostRegistry().getVirtualHost("test"); + } + + @Override + protected void tearDown() throws Exception + { + ApplicationRegistry.removeAll(); + } + + /** + * Test for AMQQueueMBean attribute and operation names, which are used in the management console + * @throws Exception + */ + public void testAMQQueueMBeanInfo() throws Exception + { + // If this test fails due to changes in the broker code, + // then the constants in the Constants.java shoule be updated accordingly + AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testQueueForManagement"), false, null, false, _virtualHost, + null); + AMQManagedObject mbean = new AMQQueueMBean(queue); + MBeanInfo mbeanInfo = mbean.getMBeanInfo(); + + List<String> operationNames = getNamesList(mbeanInfo.getOperations()); + assertTrue(operationNames.contains(Constants.OPERATION_MOVE_MESSAGES)); + + List<String> attributesList = getNamesList(mbeanInfo.getAttributes()); + assertTrue(attributesList.contains(Constants.ATTRIBUTE_QUEUE_CONSUMERCOUNT)); + assertTrue(attributesList.contains(Constants.ATTRIBUTE_QUEUE_DEPTH)); + } + + /** + * Test for Exchange MBean attribute and operation names, which are used in the management console + * @throws Exception + */ + public void testExchangeMBeanInfo() throws Exception + { + // If this test fails due to changes in the broker code, + // then the constants in the Constants.java shoule be updated accordingly + DirectExchange exchange = new DirectExchange(); + exchange.initialise(_virtualHost, ExchangeDefaults.DIRECT_EXCHANGE_NAME, false, 0, true); + AMQManagedObject mbean = (AMQManagedObject)exchange.getManagedObject(); + MBeanInfo mbeanInfo = mbean.getMBeanInfo(); + + // Check for the Exchange Type property in the ObjectName + assertNotNull(mbean.getObjectName().getKeyProperty(Constants.EXCHANGE_TYPE)); + + // Check for operation names + List<String> operationNames = getNamesList(mbeanInfo.getOperations()); + assertTrue(operationNames.contains(Constants.OPERATION_CREATE_BINDING)); + } + + /** + * Test for VirtualHostManagerMBean features used in Management console for customizing the GUI + * @throws Exception + */ + public void testVirtualHostManagerMBeanInfo() throws Exception + { + AMQManagedObject mbean = (AMQManagedObject)_virtualHost.getManagedObject(); + assertTrue(mbean.getType().equals(Constants.VIRTUAL_HOST)); + } + + private List<String> getNamesList(MBeanFeatureInfo[] features) + { + List<String> names = new ArrayList<String>(); + for (MBeanFeatureInfo feature : features) + { + names.add(feature.getName()); + } + + return names; + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/Guide.txt b/RC9/qpid/java/management/tools/qpid-cli/Guide.txt new file mode 100644 index 0000000000..db841ebaa1 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/Guide.txt @@ -0,0 +1,143 @@ + + * How to connect with the Broker * + --------------------------------- + +Before you come in to this state you have to build the source or you +can get the binary and extract then set the QPID_CLI environment +variable to the main directory of the source or binary,then only you +are in a position to start working with management console. First +check whether the broker is up and running. In order to simply connect +with the broker you can run the qpid-cli script which required +arguments. + +${QPID_CLI}/bin/qpid-cli -h [HostName of IP of the broker ] -p [Port +of the broker] + +Default values for arguments -h [localhost] -p [8999] + + * One Shot mode * + ----------------- + +With one shot mode you can run interactive mode commands for one time +and disconnect with the broker.This feature is useful when you want to +run particular command in the management console using a script which +is running in the normal console.What you have to do is you have to +give the command you want to run with the qpid-cli script running +command. + +Ex 1: $QPID_CLI/bin/qpid-cli queue list -- This will list the queue +objects and disconnect. + +Ex 2: $QPID_CLI/bin/qpid-cli queue view -n ping - This will display +information about all the message in the queue with the name of ping + +Likewise you can run any command in one shot mode and get the output +for one time. + + * Report Generation Mode * + ------------------------- + +If you want to generate reports you can do it by defining your +required information using a property file. There's a sample property +file in the parent directory and you can have a look and get an idea +about that.You can generate reports by giving a time interval in the +property file. In order to start the daemon mode you have to run the +qpid-cli script with the option : -r by giving the path for your +property file. + +Ex: $QPID_CLI/bin/qpid-cli -r ../report.property + +You should specify a property file in order to run the daemon mode and +get information repeatedly. + + * Interactive mode with number of command * + ------------------------------------------- + +This is the mode you get when you run the qpid-cli script without the +one shot mode and without the daemon mode with [-r] option.Once you +connect with the broker it display you a prompt [qpid-admin-$], then +you can run several commands to can perform following tasks. + +For all the commands object type is command and most important command +so you can use this option value without giving the option letter by +giving that option value at the beginning of the command. + +Ex: [list -o queue ] can use this command like this dropping -o option +[queue list] +Ex: [list -o queue -n ping] = [queue list -n ping] + + * Data displaying commands * + ---------------------------- + +This is the set of commands which display the information about +broker. + +list : +------ +list information about the given object type with limited +number of attributes and you can use number of command options to get +different useful behaviors with the list command.You can get the +complete description about the command by running the command like +this.[list -h]. + +info : +------ +list all the attributes of a given object type. This command +works very similar way to list command. You can use -h option for help +and get complete description of the info command. + +view : +------ +view information about the content of the message in the queue +object. In order to run this command you have to specify the object +type at the beginning.You can give how many message informations you +want to view from the top of the queue by using -t option. + +Ex : queue view -n message_queue -t 5 +[list the message info for top 5 messages in queue message_queue] + +viewcontent : +------------- +view the content of the a given message in the +queue. You have to give the messageId as a parameter with -id option +letters. + +Ex: queue viewcontent -n message_queue -id 12 +[list the content encoding and Mimetype of the message with the +messageId for the give message which is in the queue message_queue] + + * Data modification commands * + ------------------------------ + +This is a set of commands which allow users to deal with messages in +queues.Users can delete messages from a give queue and user's can move +one message from one queue to another queue. + +delete : +-------- +Using this command user can delete a give message from a given +queue you can specify how many messages you want to delete from the +queue from the top of the queue by using -t option.If user does not +give how many messages to delete from the top of the queue program is +going to delete all the messages from the queue after giving a prompt +to confirm the deletion. + +Ex: queue delete -n message_queue -t 3 +[Delete top three messages in the queue message_queue ] + +move : +------ +This command allow user to move number of messages from one +queue to another queue. First you have to specify from which queue you +want to move messages by using -n1 and -v1 option letters(-n1 queue +name/ -v1 virtual host).Then you have to use -n2 option to give the +target queue name and then you have to give From messageId and To +messageId using -fmid and -tmid option letters to specify the messages +range you want to do the move operation. + +Ex: queue move -n1 message_queue -n2 ping -fmid 13 -tmid 15 +[This will move messages with the messageId range of 13-15 from queue +message_queue to queue ping. + + + diff --git a/RC9/qpid/java/management/tools/qpid-cli/LICENSE b/RC9/qpid/java/management/tools/qpid-cli/LICENSE new file mode 100644 index 0000000000..c6432e459f --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/LICENSE @@ -0,0 +1,225 @@ +========================================================================= +== Apache License == +========================================================================= + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +============================================================================= +== JLine (BSD) License +============================================================================= +Copyright (c) 2008, Apache Software Foundation +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + + + + diff --git a/RC9/qpid/java/management/tools/qpid-cli/NOTICE b/RC9/qpid/java/management/tools/qpid-cli/NOTICE new file mode 100644 index 0000000000..f1d9e54095 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/NOTICE @@ -0,0 +1,12 @@ +Apache Qpid +Copyright 2006-2008 Apache Software Foundation +This product includes software developed at +Apache Software Foundation (http://www.apache.org/) + +Handling console input is provided bye the Jline library package, +JLine is a Java library for handling console input. It is similar +in functionality to BSD editline and GNU readline.Original software is +available from + +http://jline.sourceforge.net/index.html + diff --git a/RC9/qpid/java/management/tools/qpid-cli/README b/RC9/qpid/java/management/tools/qpid-cli/README new file mode 100644 index 0000000000..6db439aad0 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/README @@ -0,0 +1,64 @@ +README +n====== + +INSTALL +======= + source + ====== + 1.Set the environment variable QPID_HOME to the root directory of the repository or the release. + + 2.Run these command to build the source + + ant compile OR run the ant build in the parent directory(main ant script) + + 3.To launch the CLI run the script in bin folder with appropriate parameters. + + ex: + + Linux $QPID_HOME/bin/qpid-cli -h 10.8.100.122 -p 8334 + Windows %QPID_HOME%/bin/qpid-cli.bat -h 10.8.100.122 -p 8334 + + -h hostname (default localhost) + -p broker port (default 8999) + + binary + ====== + 1.Set the environment variable QPID_HOME to the root directory of the repository or the release. + + 2.To launch the CLI run the script in bin folder with appropriate parameters. + + ex: + + Linux $QPID_HOME/bin/qpid-cli -h 10.8.100.122 -p 8334 + Windows %QPID_HOME%/bin/qpid-cli.bat -h 10.8.100.122 -p 8334 + + -h hostname (default localhost) + -p broker port (default 8999) + + 3. No test cases are included in the binary version. + +TESTING +======= + +1.Test source is located in the test directory.If you want to run the tests please start the +Qpid java broker and run following ant targets. + + ant compile-tests This compile all the test sources + ant test This runs all the test cases +2.If you want to test with a remote broker please use the source release and change the constants in ConnectionConstants.java +class.(Default values are BROKER_HOSTNAME="localhost" BROKER_PORT="8999") + +For more informations please visit the project home page. + + + + + + + + + + + + + diff --git a/RC9/qpid/java/management/tools/qpid-cli/bin/qpid-cli b/RC9/qpid/java/management/tools/qpid-cli/bin/qpid-cli new file mode 100755 index 0000000000..0efb49dddd --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/bin/qpid-cli @@ -0,0 +1,35 @@ +#!/bin/bash +# +# License to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +if [ -z "$QPID_HOME" ]; then + export QPID_HOME=$(dirname $(dirname $(readlink -f $0))) + export PATH=${PATH}:${QPID_HOME}/bin +fi + +# Set classpath to include Qpid jar with all required jars in manifest +QPID_LIBS=$QPID_HOME/lib/qpid-all.jar + +# Set other variables used by the qpid-run script before calling +export JAVA=java \ + JAVA_VM=-server \ + JAVA_MEM=-Xmx1024m \ + QPID_CLASSPATH=$QPID_LIBS + +. qpid-run org.apache.qpid.CommandLineInterpreter "$@" diff --git a/RC9/qpid/java/management/tools/qpid-cli/bin/qpid-cli.bat b/RC9/qpid/java/management/tools/qpid-cli/bin/qpid-cli.bat new file mode 100755 index 0000000000..e282114d75 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/bin/qpid-cli.bat @@ -0,0 +1,27 @@ +@REM +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM +set CLASSPATH=%CLASSPATH%;%QPID_HOME%/lib/jline-0.9.94.jar +set CLASSPATH=%CLASSPATH%;%QPID_HOME%/lib/junit-4.4.jar +set CLASSPATH=%CLASSPATH%;%QPID_HOME%/lib/qpid-cli-1.0.jar +set CLASSPATH=%CLASSPATH%;%QPID_HOME%/management/tools/qpid-cli/main/classes/ +java -classpath %CLASSPATH% org.apache.qpid.CommandLineInterpreter %1 + + + + diff --git a/RC9/qpid/java/management/tools/qpid-cli/build.xml b/RC9/qpid/java/management/tools/qpid-cli/build.xml new file mode 100644 index 0000000000..1c3c87cac6 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/build.xml @@ -0,0 +1,31 @@ +<!-- + - + - Licensed to the Apache Software Foundation (ASF) under one + - or more contributor license agreements. See the NOTICE file + - distributed with this work for additional information + - regarding copyright ownership. The ASF licenses this file + - to you under the Apache License, Version 2.0 (the + - "License"); you may not use this file except in compliance + - with the License. You may obtain a copy of the License at + - + - http://www.apache.org/licenses/LICENSE-2.0 + - + - Unless required by applicable law or agreed to in writing, + - software distributed under the License is distributed on an + - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + - KIND, either express or implied. See the License for the + - specific language governing permissions and limitations + - under the License. + - + --> +<project name="qpid-cli"> + + <property name="module.depends" value="common" /> + <property name="module.test.depends" value="common client" /> + <property name="module.src" value="src" /> + <!-- Disable tests as per QPID-1342 --> + <!--property name="module.test.src" value="test" /--> + + <import file="../../../module.xml"/> + +</project> diff --git a/RC9/qpid/java/management/tools/qpid-cli/report.property b/RC9/qpid/java/management/tools/qpid-cli/report.property new file mode 100644 index 0000000000..46734d52a8 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/report.property @@ -0,0 +1,26 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +object=queue +column=Name,MessageCount,ActiveConsumerCount,Durable +filter.name=ping +filter.virtualhost=test +output=csv +seperator=| +interval=1 diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Command.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Command.java new file mode 100644 index 0000000000..6845361192 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Command.java @@ -0,0 +1,62 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid; + +import org.apache.qpid.utils.CommandLineOption; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: May 29, 2008 + * Time: 9:21:46 PM + * To change this template use File | Settings | File Templates. + */ +public interface + Command { + + public static String commandname = null; + public static CommandLineOption options = null; + + void execute(); + + void printusage(); + + void optionchecker(); + + void optionvaluechecker(); +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandConstants.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandConstants.java new file mode 100644 index 0000000000..9285501693 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandConstants.java @@ -0,0 +1,50 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid; + +public interface CommandConstants { + + String LIST_COMMAND = "list"; + String INFO_COMMAND = "info"; + String HELP_COMMAND = "help"; + String DELETE_COMMAND = "delete"; + String MOVE_COMMAND = "move"; + String VIEW_COMMAND = "view"; + String VIEWCONTENT_COMMAND = "viewcontent"; + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandExecusionEngine.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandExecusionEngine.java new file mode 100644 index 0000000000..ed54883759 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandExecusionEngine.java @@ -0,0 +1,88 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid; + +import org.apache.qpid.utils.CommandLineOptionParser; +import org.apache.qpid.utils.JMXinfo; +import org.apache.qpid.commands.*; +import org.apache.qpid.commands.Command; + + +public class CommandExecusionEngine { + private Command currentcommand = null; + private String commandname = null; + private JMXinfo info = null; + + public CommandExecusionEngine(JMXinfo info) { + this.info = info; + this.commandname = info.getCommandLineOptionParser().getcommandname(); + } + + public boolean CommandSelector() { + + if (CommandConstants.INFO_COMMAND.equalsIgnoreCase(this.commandname)) + currentcommand = new Commandinfo(info, this.commandname); + else if (CommandConstants.LIST_COMMAND.equalsIgnoreCase(this.commandname)) + currentcommand = new Commandlist(info, this.commandname); + else if (CommandConstants.HELP_COMMAND.equalsIgnoreCase(this.commandname)) + currentcommand = new Commandhelp(info, this.commandname); + else if (CommandConstants.DELETE_COMMAND.equalsIgnoreCase(this.commandname)) + currentcommand = new Commanddelete(info, this.commandname); + else if (CommandConstants.MOVE_COMMAND.equalsIgnoreCase(this.commandname)) + currentcommand = new Commandmove(info, this.commandname); + else if (CommandConstants.VIEW_COMMAND.equalsIgnoreCase(this.commandname)) + currentcommand = new Commandview(info, this.commandname); + else if (CommandConstants.VIEWCONTENT_COMMAND.equalsIgnoreCase(this.commandname)) + currentcommand = new Commandviewcontent(info, this.commandname); + else { + usage(); + return false; + } + return true; + + + } + + public void runcommand() { + currentcommand.execute(); + } + + public void usage() { + System.out.println(commandname + ":Command not found"); + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandLineInterpreter.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandLineInterpreter.java new file mode 100644 index 0000000000..e9073c79ce --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandLineInterpreter.java @@ -0,0 +1,194 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.qpid; + +import org.apache.qpid.utils.CommandLineOptionParser; +import org.apache.qpid.utils.JMXConfiguration; +import org.apache.qpid.utils.JMXinfo; + +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.naming.ServiceUnavailableException; +import java.io.PrintWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.io.FileInputStream; +import java.util.LinkedList; +import java.util.List; +import java.util.StringTokenizer; +import java.util.Properties; +import java.rmi.ConnectException; + +import jline.ConsoleReader; +import jline.ArgumentCompletor; +import jline.SimpleCompletor; + + +public class CommandLineInterpreter { + public static void main(String[] args) { + Connector conn = null; + try { + // Create an RMI connector client and + // connect it to the RMI connector server + + /*checking the commandline options and + parse them in to config method */ + JMXConnector jmxc = null; + MBeanServerConnection mbsc = null; + ConsoleReader reader = new ConsoleReader(); + reader.setBellEnabled(false); + CommandLineOptionParser commandlineoptionparser = null; + + if ((args == null) || (args.length) == 0) { + Usage(); + } + /* here special constructor is calling, when parsing options,in here first option value is starting from minus sign + so this is handle by a special constructor */ + else { + if (args[0].startsWith("-")) { + commandlineoptionparser = new CommandLineOptionParser(args, args[0]); // if user specify any argument with the qpid-cli script + } + } + + /* Connecting with the broker */ +// commandlineoptionparser = new CommandLineOptionParser(args); +// JMXConfiguration config = new JMXConfiguration(commandlineoptionparser.getAlloptions()); + try { + if (commandlineoptionparser == null) + commandlineoptionparser = new CommandLineOptionParser(args); + + JMXConfiguration config = new JMXConfiguration(commandlineoptionparser.getAlloptions()); + conn = ConnectorFactory.getConnector(config.gethostname(), config.getport()); + jmxc = conn.getConnector(); + mbsc = conn.getMBeanServerConnection(); + if (config.checkoptionsetting("r", commandlineoptionparser.getAlloptions())) { + JMXinfo info = new JMXinfo(jmxc, commandlineoptionparser, mbsc); + ReportGenerator reportgen = new ReportGenerator(config.optionchecker("r", commandlineoptionparser.getAlloptions()), info); + reportgen.loadproperties(); + reportgen.run(); + } + /* This implementation is for the people who are using the interactive + mode for one shot this run the user given command and exit */ + for (int i = 0; i < args.length; i++) { + if (args[i].compareTo("list") == 0 || args[i].compareTo("info") == 0 || args[i].compareTo("view") == 0 || args[i].compareTo("viewcontent") == 0 + || args[i].compareTo("delete") == 0 || args[i].compareTo("move") == 0) { + oneshotmode(args,commandlineoptionparser,jmxc,mbsc); + + return; + } + } + } catch (Exception ex) { + connectionrefuse(); + return; + } + /* In this point connection has been established */ + String line; + String[] command; + + /* prividing GNU readline features using Jline library */ + //String list = "list"; + PrintWriter out = new PrintWriter(System.out); + reader.addCompletor(new ArgumentCompletor( + new SimpleCompletor(new String[]{"list", "info", "exit", "quit", "delete", "move", "view", "viewcontent", "queue", "exchange", "connection", "usermanagement", "virtualhost"}))); + while ((line = reader.readLine("qpid-admin-$ ")) != null) { + out.flush(); + if (removeSpaces(line).equalsIgnoreCase("quit") || removeSpaces(line).equalsIgnoreCase("exit")) + break; + else if (line.length() == 0) + continue; + else { + command = line.split("\\s+"); + commandlineoptionparser = new CommandLineOptionParser(command); + JMXinfo info = new JMXinfo(jmxc, commandlineoptionparser, mbsc); + CommandExecusionEngine engine = new CommandExecusionEngine(info); + if (engine.CommandSelector()) + engine.runcommand(); + } + } + conn.getConnector().close(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + + private static void Usage() { + System.out.println("Connecting to localhost Qpid java broker..."); + } + + private static String removeSpaces(String s) { + StringTokenizer st = new StringTokenizer(s, " ", false); + String t = ""; + while (st.hasMoreElements()) t += st.nextElement(); + return t; + } + + private static void connectionrefuse() { + System.out.println("Cannot connect with the broker in given host with given port"); + System.out.println("Please check the host name and the port given"); + } + + private static void commandlineerror() { + System.out.println("Please run the script again and try to connect to broker again"); + } + public static String[] oneshotmode(String[] args,CommandLineOptionParser commandlineoptionparser,JMXConnector jmxc,MBeanServerConnection mbsc) + { + int check = 0; + String [] temp; + for (int i = 0; i < args.length; i++) { + + if (args[i].compareTo("-h") == 0) + check++; + else if (args[i].compareTo("-p") == 0) + check++; + } + for (int i = 0; i < (args.length - 2 * check); i++) { // mulitply by 2 because have to remove the option letter with the option value// + args[i] = args[i + check * 2]; + } + + commandlineoptionparser = new CommandLineOptionParser(args); //change the args string array which works as interactive mode// + JMXinfo info = new JMXinfo(jmxc, commandlineoptionparser, mbsc); + CommandExecusionEngine engine = new CommandExecusionEngine(info); + if (engine.CommandSelector()) + engine.runcommand(); + return args; + + } +} + diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Connector.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Connector.java new file mode 100644 index 0000000000..d3357e31b7 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Connector.java @@ -0,0 +1,76 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid; + +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXServiceURL; +import javax.management.remote.JMXConnectorFactory; +import java.io.IOException; + + +public class Connector { + private JMXServiceURL url = null; + private JMXConnector jmxc = null; + private MBeanServerConnection mbsc = null; + + + public Connector(JMXServiceURL url, JMXConnector jmxc, MBeanServerConnection mbsc) { + + + this.url = url; + this.jmxc = jmxc; + this.mbsc = mbsc; + + + } + + public JMXServiceURL getURL() { + return url; + } + + public JMXConnector getConnector() { + return jmxc; + } + + public MBeanServerConnection getMBeanServerConnection() { + return mbsc; + } + + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ConnectorFactory.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ConnectorFactory.java new file mode 100644 index 0000000000..a94003dc45 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ConnectorFactory.java @@ -0,0 +1,71 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + /* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid; + +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; +import javax.management.remote.JMXConnector; +import javax.management.MBeanServerConnection; +import java.io.IOException; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jul 3, 2008 + * Time: 10:51:28 AM + * To change this template use File | Settings | File Templates. + */ +public class ConnectorFactory { + + public static Connector getConnector(String host, String port) { + + String url_string = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi"; + JMXServiceURL url; + JMXConnector jmxc; + MBeanServerConnection mbsc; + try { + url = new JMXServiceURL(url_string); + jmxc = JMXConnectorFactory.connect(url, null); + mbsc = jmxc.getMBeanServerConnection(); + + } catch (IOException e) { + throw new RuntimeException(e); + } + return new Connector(url, jmxc, mbsc); + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ReportGenerator.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ReportGenerator.java new file mode 100644 index 0000000000..0a63d73a98 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ReportGenerator.java @@ -0,0 +1,180 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid; + +import org.apache.qpid.commands.objects.*; +import org.apache.qpid.utils.JMXinfo; + +import javax.management.MBeanServerConnection; +import java.util.*; +import java.io.FileInputStream; +import java.io.IOException; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Aug 12, 2008 + * Time: 4:03:21 PM + * To change this template use File | Settings | File Templates. + */ +public class ReportGenerator implements Runnable { + + String[] propertyname = {"object", "column", "filter.name", "filter.virtualhost", "output", "seperator", "interval"}; + String[] propertyvalue = null; + String propertyfilepath = null; + String[] columnvalue = null; + List<String> columns = null; + Properties props = null; + JMXinfo info = null; + int interval = 10; + + public void run() { + for (; ;) // creating infinite loop + { + generatereport(); + try { + Thread.sleep(this.interval * 60000); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + public ReportGenerator(String propfile, JMXinfo info) { + this.propertyfilepath = propfile; + props = new Properties(); + propertyvalue = new String[propertyname.length]; + this.info = info; + columns = new ArrayList<String>(); + } + + public void loadproperties() // get all the property file values and set the columen values// + { + try { + + props.load(new FileInputStream(this.propertyfilepath)); + for (int i = 0; i < propertyname.length; i++) { + propertyvalue[i] = props.getProperty(propertyname[i]); + } + this.setcolumnvalues(); + this.setinterval(); + } + + //catch exception in case properties file does not exist + + catch (IOException e) { + System.out.println("Oooops Give property file is not exist"); + } + } + + public void generatereport() { + this.listobjects(propertyvalue[0]); + } + + private void setcolumnvalues() { + columnvalue = propertyvalue[1].split(","); + for (int i = 0; i < columnvalue.length; i++) { + columns.add(columnvalue[i]); + } + } + + private void setinterval() { + this.interval = (new Integer(propertyvalue[6])).intValue(); + } + + private void listobjects(String option_value) { + /*pring usage if use is not give the correct option letter or no options */ + if (option_value == null) { +// System.out.println("testing"); + return; + } + MBeanServerConnection mbsc = info.getmbserverconnector(); + Set set = null; + ObjectNames objname = null; + + try { + if (option_value.compareToIgnoreCase("queue") == 0 || option_value.compareToIgnoreCase("queues") == 0) { + objname = new QueueObject(mbsc); + + } else + if (option_value.compareToIgnoreCase("Virtualhosts") == 0 || option_value.compareToIgnoreCase("Virtualhost") == 0) { + objname = new VirtualHostObject(mbsc); +// this.name = option_value; + } else + if (option_value.compareToIgnoreCase("Exchange") == 0 || option_value.compareToIgnoreCase("Exchanges") == 0) { + objname = new ExchangeObject(mbsc); +// this.name = option_value; + } else + if (option_value.compareToIgnoreCase("Connection") == 0 || option_value.compareToIgnoreCase("Connections") == 0) { + objname = new ConnectionObject(mbsc); +// this.name = option_value; + } else if (option_value.compareToIgnoreCase("all") == 0) { + objname = new AllObjects(mbsc); +// this.name = option_value; + } else + if (option_value.compareToIgnoreCase("Usermanagement") == 0 || option_value.compareToIgnoreCase("Usermanagmenets") == 0) { + objname = new UserManagementObject(mbsc); +// this.name = option_value; + } else { + printusage(); + echo("Wrong objectName"); + return; + } + objname.setQueryString(this.propertyvalue[0], this.propertyvalue[2], this.propertyvalue[3]); + objname.returnObjects(); + if (objname.getSet().size() != 0) { + objname.reportgenerator(this.propertyvalue[4], this.propertyvalue[5], columns); + } else { + printusage(); + } + } + catch (Exception ex) { + ex.printStackTrace(); + } + + + } + + public void echo(String str) { + System.out.println(str); + } + + public void printusage() { + System.out.println("Wrong option or wrong option value"); + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Command.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Command.java new file mode 100644 index 0000000000..02c50e37e4 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Command.java @@ -0,0 +1,113 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.qpid.commands; + + +import org.apache.qpid.utils.CommandLineOptionParser; +import org.apache.qpid.utils.JMXinfo; +import org.apache.qpid.utils.CommandLineOption; + +import javax.management.remote.JMXConnector; +import javax.management.MBeanServerConnection; +import java.util.Map; + + +public class Command { + public JMXinfo info = null; + public String commandname = null; + + + public Command(JMXinfo info, String name) { + this.info = info; + this.commandname = name; + } + + public Command() { + + } + + public void execute() { + + + } + + public void printusage() { + } + + + public String optionchecker(String option_letter) { + Map map = info.getCommandLineOptionParser().getAlloptions(); + if (map == null) + return null; + CommandLineOption option = (CommandLineOption) map.get(option_letter); + if (option == null) + return null; + String value = option.getOptionValue(); + return value; + } + + public boolean checkoptionsetting(String option_letter) { + Map map = info.getCommandLineOptionParser().getAlloptions(); + if (map == null) + return false; + CommandLineOption option = (CommandLineOption) map.get(option_letter); + if (option == null) + return false; + String value = option.getOptionType(); + + if (value != null) + return true; + else + return false; + } + + public void optionvaluechecker() { + + } + + public void echo(String str) { + System.out.println(str); + } + + public void unrecognizeoption() { + echo("list: Unrecognized option"); + echo("Try `" + this.commandname + " --help` for more information"); + } + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commanddelete.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commanddelete.java new file mode 100644 index 0000000000..eb24012405 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commanddelete.java @@ -0,0 +1,228 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +package org.apache.qpid.commands; + +import org.apache.qpid.utils.JMXinfo; +import org.apache.qpid.commands.objects.*; + +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanInfo; +import java.util.Set; +import java.util.Iterator; +import java.util.StringTokenizer; +import java.io.BufferedReader; +import java.io.InputStreamReader; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Aug 6, 2008 + * Time: 5:34:51 PM + * To change this template use File | Settings | File Templates. + */ +public class Commanddelete extends Command { + private String object; + private String name; + private String vhost; + private int number = 0; + private QueueObject objname; + private MBeanServerConnection mbsc; + private String method1, method2; + private ObjectName queue; + + public Commanddelete(JMXinfo info, String name) { + super(info, name); + this.mbsc = info.getmbserverconnector(); + this.objname = new QueueObject(mbsc); + this.method1 = "deleteMessageFromTop"; + this.method2 = "clearQueue"; + + } + + public void deletemessages() { + Set set = null; + objname.setQueryString(this.object, this.name, this.vhost); + set = objname.returnObjects(); + + if (objname.getSet().size() != 0) { + Iterator it = set.iterator(); + this.queue = (ObjectName) it.next(); + try { + if (this.number == 0) { + echo(""); + System.out.print("Do you want to delete all the messages from the Queue [Y/N] :"); + InputStreamReader isr = new InputStreamReader(System.in); + BufferedReader br = new BufferedReader(isr); + String s = br.readLine(); + echo(s); + if (s.compareToIgnoreCase("y") == 0) + this.mbsc.invoke(queue, this.method2, null, null); + else + return; + } else if (objname.getmessagecount(this.queue) < this.number) { + echo("Given number is Greater than the Queue Depth"); + return; + } else { + for (int i = 0; i < this.number; i++) { + this.mbsc.invoke(queue, this.method1, null, null); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + + } else { + if (isname()) { + + echo("The Queue you have specified is not in the current broker"); + echo(""); + } else { + printusage(); + } + } + } + + public void execute() { + /* In here you it's easy to handle any number of otpions which are going to add with the list command which works + with main option object or o + */ + + if (checkoptionsetting("object") || checkoptionsetting("o")) { + String object = optionchecker("object"); + if (object == null) { + object = optionchecker("o"); + } + if (object.compareToIgnoreCase("queue") == 0) + setobject(object); + else { + unrecognizeoption(); + echo("This command is only applicable for delete command so please start with queue"); + } + if (checkoptionsetting("name") || checkoptionsetting("n")) { + String name = optionchecker("name"); + if (name == null) + name = optionchecker("n"); + + setname(name); + } + if (checkoptionsetting("virtualhost") || checkoptionsetting("v")) { + String vhost = optionchecker("virtualhost"); + if (vhost == null) + vhost = optionchecker("v"); + setvhost(vhost); + } + if (checkoptionsetting("top") || checkoptionsetting("t")) { + String number = optionchecker("top"); + if (number == null) + number = optionchecker("t"); + + setnumber(removeSpaces(number)); + } + this.deletemessages(); + } else if (checkoptionsetting("h") || checkoptionsetting("help")) + printusage(); + else + unrecognizeoption(); + } + + public void printusage() { + echo(""); + echo("Usage:delete [OPTION] ... [OBJECT TYPE]...\n"); + echo("Delete the top most messages from the given queue object\n"); + echo("To specify the desired queue you have to give the virtualhost name and the queue name with following commands\n"); + echo("Where possible options include:\n"); + echo(" -v --virtualhost Give the virtuallhost name of the desired queue"); + echo(" -n --name Give the queue name of the desired queue you want to do the delete operation"); + echo(" -t --top Give how many number of messages you want to delete from the top (Default = all the messages will be deleted"); + echo(" -h --help Display the help and back to the qpid-cli prompt\n"); + + } + + private void setobject(String object) { + this.object = object; + } + + public String getobject() { + return this.object; + } + + private void setname(String name) { + this.name = name; + } + + private boolean isname() { + if (this.name == null) + return false; + + else + return true; + } + + private void setvhost(String vhost) { + this.vhost = vhost; + } + + public String getvhost() { + return this.vhost; + } + + public String getname() { + return this.name; + } + + private void setnumber(String number) { + Integer i = new Integer(number); + this.number = i.intValue(); + } + + public int getnumber() { + return this.number; + } + + private static String removeSpaces(String s) { + StringTokenizer st = new StringTokenizer(s, " ", false); + String t = ""; + while (st.hasMoreElements()) t += st.nextElement(); + return t; + } + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandhelp.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandhelp.java new file mode 100644 index 0000000000..962b606c12 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandhelp.java @@ -0,0 +1,73 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.qpid.commands; + +import org.apache.qpid.utils.JMXinfo; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jul 6, 2008 + * Time: 5:55:28 PM + * To change this template use File | Settings | File Templates. + */ +public class Commandhelp extends Command { + public Commandhelp(JMXinfo info, String name) { + super(info, name); + } + + public void execute() { + displayhelp(); + } + + private void displayhelp() { + echo(""); + echo("Current version of qpid CLI is supporting following commands"); + echo(""); + echo("[list] This command is listing limited information about a given type of object"); + echo(" For more information about list command run `list --help`"); + echo("[info] This command is listing All the information about a given type of object"); + echo(" For more information about list command run `info --help`"); + + echo(""); + echo("[exit] This command is disconnect the connection with the Qpid Java broker and go back to normal propmt"); + echo("[quit] This command is disconnect the connection with the Qpid Java broker and go back to normal propmt"); + echo(""); + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandinfo.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandinfo.java new file mode 100644 index 0000000000..51cbb2b929 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandinfo.java @@ -0,0 +1,259 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.qpid.commands; + + +import org.apache.qpid.utils.CommandLineOptionParser; +import org.apache.qpid.utils.JMXinfo; +import org.apache.qpid.commands.objects.*; + +import javax.management.MBeanServerConnection; +import java.util.Set; + + +public class Commandinfo extends Command { + private String object = null; + private String name = null; + private String virtualhost = null; + private String outputformat = null; + private String seperator = ","; + + public Commandinfo(JMXinfo info, String name) { + + super(info, name); + + } + + private void listobjects(String option_value) { + /*pring usage if use is not give the correct option letter or no options */ + if (option_value == null) { +// System.out.println("testing"); + printusage(); + return; + } + MBeanServerConnection mbsc = info.getmbserverconnector(); + Set set = null; + ObjectNames objname = null; + + try { + if (option_value.compareToIgnoreCase("queue") == 0 || option_value.compareToIgnoreCase("queues") == 0) { + objname = new QueueObject(mbsc); + + } else + if (option_value.compareToIgnoreCase("Virtualhosts") == 0 || option_value.compareToIgnoreCase("Virtualhost") == 0) { + objname = new VirtualHostObject(mbsc); +// this.name = option_value; + } else + if (option_value.compareToIgnoreCase("Exchange") == 0 || option_value.compareToIgnoreCase("Exchanges") == 0) { + objname = new ExchangeObject(mbsc); +// this.name = option_value; + } else + if (option_value.compareToIgnoreCase("Connection") == 0 || option_value.compareToIgnoreCase("Connections") == 0) { + objname = new ConnectionObject(mbsc); +// this.name = option_value; + } else if (option_value.compareToIgnoreCase("all") == 0) { + objname = new AllObjects(mbsc); +// this.name = option_value; + } else + if (option_value.compareToIgnoreCase("Usermanagement") == 0 || option_value.compareToIgnoreCase("Usermanagmenets") == 0) { + objname = new UserManagementObject(mbsc); +// this.name = option_value; + } else { + printusage(); + echo("Wrong objectName"); + return; + } + objname.setQueryString(this.object, this.name, this.virtualhost); + objname.returnObjects(); + if (objname.getSet().size() != 0) { + objname.displayinfo(this.outputformat, this.seperator); + + } else { + if (isname()) { + + echo("You might quering wrong " + this.object + " name with --name or -n option "); + echo(""); + echo(this.object + "Type Objects might not in the broker currently"); + echo(""); + } else { + printusage(); + } + } + + + } catch (Exception ex) { + ex.printStackTrace(); + } + + + } + + public void execute() { + /* In here you it's easy to handle any number of otpions which are going to add with the list command which works + with main option object or o + */ + if (checkoptionsetting("output")) { + setoutputformat(optionchecker("output")); + if (checkoptionsetting("separator")) + setseperator(optionchecker("separator")); + } + if (checkoptionsetting("object") || checkoptionsetting("o")) { + String object = optionchecker("object"); + if (object == null) { + object = optionchecker("o"); + } + setobject(object); + if (checkoptionsetting("name") || checkoptionsetting("n")) { + String name = optionchecker("name"); + if (name == null) + name = optionchecker("n"); + + setname(name); + } + if (checkoptionsetting("virtualhost") || checkoptionsetting("v")) { + String vhost = optionchecker("virtualhost"); + if (vhost == null) + vhost = optionchecker("v"); + setvirtualhost(vhost); + } + listobjects(this.object); + } else if (checkoptionsetting("h") || checkoptionsetting("help")) + printusage(); + else + unrecognizeoption(); + } + + public void printusage() { + echo(""); + echo("Usage:info [OPTION] ... [OBJECT TYPE]...\n"); + echo("Give ALL the information about the given object\n"); + echo("Where possible options include:\n"); + echo(" -o --object type of objects which you want to list\n"); + echo(" ex: < list -o queue > : lists all the queues created in the java broker\n"); + echo(" For now list command is supporting following object typse \n"); + echo(" Queue Connection VirtualHost UserMangement Exchange"); + echo(" Or You can specify object type by giving it at the beginning rather giving "); + echo(" it as a argument"); + echo(" Ex:< queue info > this command is equal to <info -o queue> command \n"); + echo(" -v --virtualhost After specifying the object type you can filter output with this option"); + echo(" list objects with the given virtualhost which will help to find identical"); + echo(" queue objects with -n option"); + echo(" ex: queue info -v developement"); + echo(" -output Specify which output format you want to get the ouput"); + echo(" Although the option is there current version supports only for CSV output format"); + echo(" -separator This option use with output option to specify which separator you want to get the CSV output (default seperator is comma"); + echo(" -h --help Display the help and back to the qpid-cli prompt\n"); + echo(" -n --name After specifying what type of objects you want to monitor you can filter"); + echo(" the output using -n option by specifying the name of the object you want"); + echo(" to monitor exactly"); + echo(" ex: <queue info -n ping> : Give all the information about queue objects "); + echo(" having queue name of ping\n"); + } + + private void setobject(String object) { + this.object = object; + } + + private void setname(String name) { + this.name = name; + } + + private boolean isname() { + if (this.name == null) + return false; + + else + return true; + } + + private void setvirtualhost(String vhost) { + this.virtualhost = vhost; + } + + public String getvirtualhost() { + return this.virtualhost; + } + + private void setoutputformat(String outputformat) { + this.outputformat = outputformat; + } + + private void setseperator(String seperator) { + this.seperator = seperator; + } + + private boolean isseperator() { + if (this.seperator == null) + return false; + + else + return true; + } + + private boolean isoutputformat() { + if (this.outputformat == null) + return false; + + else + return true; + } + + public String getname() { + return this.name; + } + + public String getobject() { + return this.object; + } + + /* + public String optionchecker(String option_letter) { + Map map = info.getCommandLineOptionParser().getAlloptions(); + if(map == null) + return null; + CommandLineOption option = (CommandLineOption) map.get(option_letter); + if(option == null) + return null; + String value = option.getOptionValue(); + return value; + + + } + */ +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandlist.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandlist.java new file mode 100644 index 0000000000..856dfcf0f2 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandlist.java @@ -0,0 +1,296 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.qpid.commands; + +import org.apache.qpid.utils.JMXinfo; +import org.apache.qpid.utils.CommandLineOptionParser; +import org.apache.qpid.utils.CommandLineOptionConstants; +import org.apache.qpid.utils.CommandLineOption; +import org.apache.qpid.commands.objects.*; + +import javax.management.ObjectName; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanServerConnection; +import java.util.Set; +import java.util.Iterator; +import java.util.Map; + + +public class Commandlist extends Command { + + private String object; + private String name; + private String vhost; + private String outputformat = null; + private String seperator = ","; //this variable is assigning if -n option is used otherwise this is null + + public Commandlist(JMXinfo info, String name) { + super(info, name); + + } + + private void listobjects(String option_value) { + /*pring usage if use is not give the correct option letter or no options */ + if (option_value == null) { +// System.out.println("testing"); + printusage(); + return; + } + MBeanServerConnection mbsc = info.getmbserverconnector(); + Set set = null; + ObjectNames objname = null; + + try { + if (option_value.compareToIgnoreCase("queue") == 0 || option_value.compareToIgnoreCase("queues") == 0) { + objname = new QueueObject(mbsc); + + } else + if (option_value.compareToIgnoreCase("Virtualhosts") == 0 || option_value.compareToIgnoreCase("Virtualhost") == 0) { + objname = new VirtualHostObject(mbsc); +// this.name = option_value; + } else + if (option_value.compareToIgnoreCase("Exchange") == 0 || option_value.compareToIgnoreCase("Exchanges") == 0) { + objname = new ExchangeObject(mbsc); +// this.name = option_value; + } else + if (option_value.compareToIgnoreCase("Connection") == 0 || option_value.compareToIgnoreCase("Connections") == 0) { + objname = new ConnectionObject(mbsc); +// this.name = option_value; + } else if (option_value.compareToIgnoreCase("all") == 0) { + objname = new AllObjects(mbsc); +// this.name = option_value; + } else + if (option_value.compareToIgnoreCase("Usermanagement") == 0 || option_value.compareToIgnoreCase("Usermanagmenets") == 0) { + objname = new UserManagementObject(mbsc); +// this.name = option_value; + } else { + printusage(); + echo("Wrong objectName"); + return; + } + objname.setQueryString(this.object, this.name, this.vhost); + objname.returnObjects(); + if (objname.getSet().size() != 0) { + if (this.object.compareToIgnoreCase("queue") == 0 || this.object.compareToIgnoreCase("queues") == 0) + objname.displayqueues(this.outputformat, this.seperator); + else + objname.displayobjects(this.outputformat, this.seperator); + } else { + if (isname()) { + + echo("You might quering wrong " + this.object + " name with --name or -n option "); + echo(""); + echo(this.object + "Type Objects might not in the broker currently"); + echo(""); + } else { + printusage(); + } + } + + + } catch (Exception ex) { + ex.printStackTrace(); + } + + + } + + public void listdomains() { + MBeanServerConnection mbsc = info.getmbserverconnector(); + try { + String[] domains = mbsc.getDomains(); + echo("DOMAINS"); + for (int i = 0; i < domains.length; i++) + echo("\tDomain[" + i + "] = " + domains[i]); + + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void execute() { + /* In here you it's easy to handle any number of otpions which are going to add with the list command which works + with main option object or o + */ + if (checkoptionsetting("output")) { + setoutputformat(optionchecker("output")); + if (checkoptionsetting("separator")) + setseperator(optionchecker("separator")); + } + if (checkoptionsetting("object") || checkoptionsetting("o")) { + String object = optionchecker("object"); + if (object == null) { + object = optionchecker("o"); + } + setobject(object); + if (checkoptionsetting("name") || checkoptionsetting("n")) { + String name = optionchecker("name"); + if (name == null) + name = optionchecker("n"); + + setname(name); + } + if (checkoptionsetting("virtualhost") || checkoptionsetting("v")) { + String vhost = optionchecker("virtualhost"); + if (vhost == null) + vhost = optionchecker("v"); + setvhost(vhost); + } + listobjects(this.object); + } else if (checkoptionsetting("domain") || checkoptionsetting("d")) + listdomains(); + else if (checkoptionsetting("h") || checkoptionsetting("help")) + printusage(); + else + unrecognizeoption(); + } + + public void printusage() { + echo(""); + echo("Usage:list [OPTION] ... [OBJECT TYPE]...\n"); + echo("List the information about the given object\n"); + echo("Where possible options include:\n"); + echo(" -o --object type of objects which you want to list\n"); + echo(" ex: < list -o queue > : lists all the queues created in the java broker\n"); + echo(" For now list command is supporting following object typse \n"); + echo(" Queue Connection VirtualHost UserMangement Exchange"); + echo(" Or You can specify object type by giving it at the beginning"); + echo(" rather giving it as a argument"); + echo(" Ex:< queue list > this command is equal to list -o queue \n"); + echo(" -d --domain list all the domains of objects available for remote monitoring\n"); + echo(" -v --virtualhost After specifying the object type you can filter output with this option"); + echo(" list objects with the given virtualhost which will help to find "); + echo(" identical queue objects with -n option"); + echo(" ex: queue list -v develop ment"); + echo(" -output Specify which output format you want to get the ouput"); + echo(" Although the option is there current version supports only for CSV output format"); + echo(" -separator This option use with output option to specify which separator you want to get the CSV output (default seperator is comma"); + echo(" -h --help Display the help and back to the qpid-cli prompt\n"); + echo(" -n --name After specifying what type of objects you want to monitor you can filter"); + echo(" the output using -n option by specifying the name of the object you want "); + echo(" to monitor exactly"); + echo(" ex: <list -o queue -n ping> : list all the queue objects having queue name"); + echo(" of ping"); + echo(" ex: <queue list -n ping -v development> list all the queue objects with name "); + echo(" of ping and virtualhost of developement \n"); + + + } + + private void setobject(String object) { + this.object = object; + } + + private void setname(String name) { + this.name = name; + } + + private boolean isname() { + if (this.name == null) + return false; + + else + return true; + } + + private void setvhost(String vhost) { + this.vhost = vhost; + } + + public String getvhost() { + return this.vhost; + } + + public String getname() { + return this.name; + } + + public String getobject() { + return this.object; + } + + private void setoutputformat(String outputformat) { + this.outputformat = outputformat; + } + + private void setseperator(String seperator) { + this.seperator = seperator; + } + + private boolean isseperator() { + if (this.seperator == null) + return false; + + else + return true; + } + + private boolean isoutputformat() { + if (this.outputformat == null) + return false; + + else + return true; + } + + + /* + public String optionchecker(String option_letter) { + Map map = info.getCommandLineOptionParser().getAlloptions(); + if(map == null) + return null; + CommandLineOption option = (CommandLineOption) map.get(option_letter); + if(option == null) + return null; + String value = option.getOptionValue(); + return value; + + + } + */ + public void optionvaluechecker() { + + } +} + + + + + diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandmove.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandmove.java new file mode 100644 index 0000000000..a4deb19315 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandmove.java @@ -0,0 +1,294 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +package org.apache.qpid.commands; + + +import org.apache.qpid.commands.objects.QueueObject; +import org.apache.qpid.commands.objects.ObjectNames; +import org.apache.qpid.utils.JMXinfo; + +import javax.management.ObjectName; +import javax.management.MBeanInfo; +import javax.management.MBeanServerConnection; +import javax.management.MBeanAttributeInfo; +import java.util.StringTokenizer; +import java.util.Set; +import java.util.Iterator; +import java.util.List; +import java.io.InputStreamReader; +import java.io.BufferedReader; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Aug 6, 2008 + * Time: 5:35:05 PM + * To change this template use File | Settings | File Templates. + */ +public class Commandmove extends Command { + private String object; + private String name1 = null, name2 = null, vhost1 = null, vhost2 = null, method1 = null, method2 = null; //target and starting queue specifications happen with these options + private int number = 0; + private QueueObject queue1, queue2; + private MBeanServerConnection mbsc; + private ObjectName queue; + private int fmid = 0, tmid = 0; + + public Commandmove(JMXinfo info, String name) { + super(info, name); + this.mbsc = info.getmbserverconnector(); + this.queue1 = new QueueObject(mbsc); +// this.queue2 = new QueueObject(mbsc); + this.method1 = "moveMessages"; + this.method2 = "getMessagesOnTheQueue"; + + } + + public void movemessages() { + Set set = null; + queue1.setQueryString(this.object, this.name1, this.vhost1); +// queue2.setQueryString(this.object, this.name2, this.vhost2); + set = queue1.returnObjects(); + List messageidlist = null; + Long frommessageid = null, tomessageid, middle; + int temp = 0; + if (queue1.getSet().size() != 0) { // find the queue + Iterator it = set.iterator(); + this.queue = (ObjectName) it.next(); + } else { + if (isname1() || isname2()) { // if the specified queue is not there in the broker + + echo("The Queue you have specified is not in the current broker"); + echo(""); + } else { + printusage(); + } + } +// if(this.tmid == 0 || this.fmid == 0) +// { +// this.number = queue1.getmessagecount(this.queue); +// echo(""); +// System.out.print("Do you want to delete all the messages from the Queue[Y/N] :"); +// InputStreamReader isr = new InputStreamReader(System.in); +// BufferedReader br = new BufferedReader(isr); +// try{ +// String s = br.readLine(); +// echo(s); +// if(s.compareToIgnoreCase("y") != 0) +// return; +// }catch(Exception ex) +// { +// ex.printStackTrace(); +// } +// +// } +// if(this.number > queue1.getmessagecount(this.queue)) +// { +// System.out.println("Given number is Greater than the Queue Depth"); +// return; +// }//if user doesn't specify -t option all the messages will be moved +// Object[] params = {new Integer(this.number)}; +// String[] signature = {new String("java.lang.Integer")}; +// try{ +// messageidlist = (List)this.mbsc.invoke(queue,this.method2,params,signature); +// Iterator it1 = messageidlist.iterator(); +// temp++; +// do +// { +// middle = (Long)it1.next(); +// if(temp == 1) +// frommessageid = middle; // get the messageid of first message +// +// }while(it1.hasNext()); +// tomessageid = middle; // get the messageid of the last message + try { + Object[] params1 = {getfmid(), gettmid(), this.name2}; + String[] signature1 = {new String("long"), new String("long"), new String("java.lang.String")}; + this.mbsc.invoke(this.queue, this.method1, params1, signature1); + + } catch (Exception ex) { + ex.printStackTrace(); + echo("Given messageId's might be wrong please run the view command and check messageId's you have given\n"); + echo("From MessageId should be greater than 0 and should less than To messageId"); + } + + + } + + public void execute() { + /* In here you it's easy to handle any number of otpions which are going to add with the list command which works + with main option object or o + */ + + if (checkoptionsetting("object") || checkoptionsetting("o")) { + String object = optionchecker("object"); + if (object == null) { + object = optionchecker("o"); + } + if (object.compareToIgnoreCase("queue") == 0) + setobject(object); + else { + unrecognizeoption(); + echo("This command is only applicable for queue command so please start with queue"); + } + if (checkoptionsetting("n2") && checkoptionsetting("n1")) { + setname1(optionchecker("n1")); + setname2(optionchecker("n2")); + } else { + echo("You have to specify both n1 and n2 option value to move a message"); /* when user forget to specify target or starting queue name */ + return; + } + + if (checkoptionsetting("v1")) { + + setvhost1(optionchecker("v1")); + } + if (checkoptionsetting("tmid") && checkoptionsetting("fmid")) { + String tmid = optionchecker("tmid"); + String fmid = optionchecker("fmid"); + + + settomessageIdandfrommessageId(removeSpaces(tmid), removeSpaces(fmid)); + } else { + echo("You have to set from MessageId and to MessageId in order to move messages between queues"); + echo("To view MessageId's use <view> command with -n and -v options"); + return; + } + this.movemessages(); + + } else if (checkoptionsetting("h") || checkoptionsetting("help")) + printusage(); + else + unrecognizeoption(); + } + + public void printusage() { + echo(""); + echo("Usage:move [OPTION] ... [OBJECT TYPE]...\n"); + echo("Move the top most messages from the given queue object to the given destination object\n"); + echo("To specify the desired queues you have to give the virtualhost name and the queue name with following commands\n"); + echo("Where possible options include:\n"); + echo(" -v1 Give the virtuallhost name from which queue you want to move messages"); + echo(" -n1 Give the queue name which you want to move messages from"); + echo(" -n2 Give the queue name of the destination queue"); + echo(" -tmid Give From MessageId you want to move from the Queue"); + echo(" -fmid Give To MessageId you want to move from the Queue"); + echo(" -h --help Display the help and back to the qpid-cli prompt\n"); + + } + + private void setobject(String object) { + this.object = object; + } + + private void setname1(String name) { + this.name1 = name; + } + + private void setname2(String name) { + this.name2 = name; + } + + private boolean isname1() { + if (this.name1 == null) + return false; + + else + return true; + } + + private boolean isname2() { + if (this.name2 == null) + return false; + + else + return true; + } + + private void setvhost1(String vhost) { + this.vhost1 = vhost; + } +// private void setvhost2(String vhost) { +// this.vhost2 = vhost; +// } + + private void setnumber(String number) { + Integer i = new Integer(number); + this.number = i.intValue(); + } + + private static String removeSpaces(String s) { + StringTokenizer st = new StringTokenizer(s, " ", false); + String t = ""; + while (st.hasMoreElements()) t += st.nextElement(); + return t; + } + + private void settomessageIdandfrommessageId(String tmid, String fmid) { + Integer i = new Integer(tmid); + Integer j = new Integer(fmid); + this.tmid = i.intValue(); + this.fmid = j.intValue(); + } + + public int gettmid() { + return this.tmid; + } + + public int getfmid() { + return this.fmid; + } + + public String getname1() { + return this.name1; + } + + public String getname2() { + return this.name2; + } + + public String getvhost() { + return this.vhost1; + } + + public String getobject() { + return this.object; + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandview.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandview.java new file mode 100644 index 0000000000..a4c6394589 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandview.java @@ -0,0 +1,276 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + /* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.qpid.commands; + +import org.apache.qpid.commands.objects.ObjectNames; +import org.apache.qpid.commands.objects.QueueObject; +import org.apache.qpid.utils.JMXinfo; + +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanInfo; +import javax.management.openmbean.*; +import java.util.*; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.awt.font.OpenType; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Aug 8, 2008 + * Time: 11:33:05 PM + * To change this template use File | Settings | File Templates. + */ +public class Commandview extends Command { + private String object; + private String name; + private String vhost; + private int number = 0; + private QueueObject objname; + private MBeanServerConnection mbsc; + private String method1, method2; + private ObjectName queue; + + public Commandview(JMXinfo info, String name) { + super(info, name); + this.mbsc = info.getmbserverconnector(); + this.objname = new QueueObject(mbsc); + this.method1 = "viewMessages"; + this.method2 = "viewMessaegContent"; + + } + + public void viewmessages() { + Set set = null; + Object temp[] = {null}; + objname.setQueryString(this.object, this.name, this.vhost); + set = objname.returnObjects(); + String header = "", temp_header = "", message_data = "", outline = ""; + + + if (objname.getSet().size() != 0) { + Iterator it = set.iterator(); + this.queue = (ObjectName) it.next(); + try { + if (objname.getmessagecount(this.queue) == 0) { + echo("Selected Queue doesn't contain any messages"); + return; + } + if (this.number == 0) + this.number = objname.getmessagecount(this.queue); + + + if (objname.getmessagecount(this.queue) < this.number) { + echo("Given number is Greater than the Queue Depth"); + return; + } else { + Object[] params = {1, this.number}; + String[] signature = {new String("int"), new String("int")}; + TabularDataSupport data = (TabularDataSupport) this.mbsc.invoke(queue, this.method1, params, signature); + + Set entrySet = data.entrySet(); + ArrayList<Map.Entry> list = new ArrayList<Map.Entry>(entrySet); + if (list.size() != 0) {// no data} + for (int i = 0; i < list.size(); i++) { + CompositeData compositedata = + (CompositeData) (list.get(i)).getValue(); + List<String> itemNames = new + ArrayList<String>(compositedata.getCompositeType().keySet()); + if (i == 0) // display the table headers + { + for (int j = 0; j < itemNames.size(); j++) { + temp_header = ""; + if (j != 1) //skipping header information + { + temp_header = itemNames.get(j); + while (temp_header.length() < 15) + temp_header = " " + temp_header; + + header = header + temp_header + "|"; + } else + continue; + } + echo(header); + while (outline.length() < header.length()) + outline = outline + "-"; + echo(outline); + } + + for (int j = 0; j < itemNames.size(); j++) { + temp_header = ""; + if (j != 1) { + temp_header = String.valueOf(compositedata.get(itemNames.get(j))); + while (temp_header.length() < 15) + temp_header = " " + temp_header; + message_data = message_data + temp_header + "|"; + } else // header information is not displaying unless user specify header information is needed + continue; + + + } + echo(message_data); + header = ""; + message_data = ""; + } + } else { + System.out.println("No Data to Display"); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + + } else { + if (isname()) { + + echo("The Queue you have specified is not in the current broker"); + echo(""); + } else { + printusage(); + } + } + } + + public void execute() { + /* In here you it's easy to handle any number of otpions which are going to add with the list command which works + with main option object or o + */ + + if (checkoptionsetting("object") || checkoptionsetting("o")) { + String object = optionchecker("object"); + if (object == null) { + object = optionchecker("o"); + } + if (object.compareToIgnoreCase("queue") == 0) + setobject(object); + else { + unrecognizeoption(); + echo("This command is only applicable for delete command so please start with queue"); + } + if (checkoptionsetting("name") || checkoptionsetting("n")) { + String name = optionchecker("name"); + if (name == null) + name = optionchecker("n"); + + setname(name); + } + if (checkoptionsetting("virtualhost") || checkoptionsetting("v")) { + String vhost = optionchecker("virtualhost"); + if (vhost == null) + vhost = optionchecker("v"); + setvhost(vhost); + } + if (checkoptionsetting("top") || checkoptionsetting("t")) { + String number = optionchecker("top"); + if (number == null) + number = optionchecker("t"); + + setnumber(removeSpaces(number)); + } + this.viewmessages(); + } else if (checkoptionsetting("h") || checkoptionsetting("help")) + printusage(); + else + unrecognizeoption(); + } + + public void printusage() { + echo(""); + echo("Usage:view [OPTION] ... [OBJECT TYPE]...\n"); + echo("view the information about given number of messages from the given queue object\n"); + echo("To specify the desired queue you have to give the virtualhost name and the queue name with following commands\n"); + echo("Where possible options include:\n"); + echo(" -v --virtualhost Give the virtuallhost name of the desired queue"); + echo(" -n --name Give the queue name of the desired queue you want to view messages"); + echo(" -t --top Give how many number of messages you want to delete from the top (Default = all the messages will be deleted"); + echo(" -h --help Display the help and back to the qpid-cli prompt\n"); + + } + + private void setobject(String object) { + this.object = object; + } + + private void setname(String name) { + this.name = name; + } + + private boolean isname() { + if (this.name == null) + return false; + + else + return true; + } + + private void setvhost(String vhost) { + this.vhost = vhost; + } + + public String getvhost() { + return this.vhost; + } + + private void setnumber(String number) { + Integer i = new Integer(number); + this.number = i.intValue(); + } + + private static String removeSpaces(String s) { + StringTokenizer st = new StringTokenizer(s, " ", false); + String t = ""; + while (st.hasMoreElements()) t += st.nextElement(); + return t; + } + + public String getname() { + return this.name; + } + + public String getobject() { + return this.object; + } + + public int getnumber() { + return this.number; + } + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandviewcontent.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandviewcontent.java new file mode 100644 index 0000000000..f24fd08a99 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandviewcontent.java @@ -0,0 +1,284 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.qpid.commands; + +import org.apache.qpid.commands.objects.QueueObject; +import org.apache.qpid.utils.JMXinfo; + +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.CompositeData; +import java.util.*; +import java.nio.charset.Charset; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Aug 10, 2008 + * Time: 12:19:16 PM + * To change this template use File | Settings | File Templates. + */ +public class Commandviewcontent extends Command { + private String object; + private String name; + private String vhost; + private int number = 0; + private QueueObject objname; + private MBeanServerConnection mbsc; + private String method1; + private ObjectName queue; + + public Commandviewcontent(JMXinfo info, String name) { + super(info, name); + this.mbsc = info.getmbserverconnector(); + this.objname = new QueueObject(mbsc); + this.method1 = "viewMessageContent"; + + } + + public void viewcontent() { + Set set = null; + Object temp[] = {null}; + objname.setQueryString(this.object, this.name, this.vhost); + set = objname.returnObjects(); + String temp_header = "", header = "", message_data = "", encoding = null; + + if (objname.getSet().size() != 0) { + Iterator it = set.iterator(); + this.queue = (ObjectName) it.next(); + try { + if (objname.getmessagecount(this.queue) == 0) { + echo("Selected Queue doesn't contain any messages"); + return; + } + if (this.number == 0) { + echo("You haven't selected a MessageId Please use -id and give a message id"); + echo("Or run view command with same arguemnts to view messageId list for the queue"); + } + +// if(objname.getmessagecount(this.queue) < this.number) +// { +// echo("Given number is Greater than the Queue Depth"); +// return; +// } + else { + Object[] params = {this.number}; + String[] signature = {new String("long")}; + CompositeData data = (CompositeData) this.mbsc.invoke(queue, this.method1, params, signature); + List<String> itemNames = new + ArrayList<String>(data.getCompositeType().keySet()); + for (int j = 0; j < itemNames.size(); j++) { + temp_header = ""; + temp_header = itemNames.get(j); + while (temp_header.length() < 15) + temp_header = " " + temp_header; + + header = header + temp_header + "|"; + } + echo(header); + encoding = String.valueOf(data.get(itemNames.get(2))); // set the encoding at the beginning because encoding comes later in the loop + if (encoding == null || encoding.length() == 0) { + encoding = Charset.defaultCharset().name(); + + } + for (int j = 0; j < itemNames.size(); j++) { + temp_header = ""; + if (j != 1) { + temp_header = String.valueOf(data.get(itemNames.get(j))); + while (temp_header.length() < 15) + temp_header = " " + temp_header; + } else { + Byte[] arrayItems = (Byte[]) data.get(itemNames.get(j)); + byte[] byteArray = new byte[arrayItems.length]; + for (int i = 0; i < arrayItems.length; i++) { + byteArray[i] = arrayItems[i]; + temp_header = new String(byteArray, encoding); + while (temp_header.length() < 15) + temp_header = " " + temp_header; + } + } + message_data = message_data + temp_header + "|"; + + + } + echo(message_data); +// Object keys[] = data.keySet().toArray(); +// CompositeData comdata = data.get(keys); +// for(int i=0;i < keys.length;i++) +// { +// System.out.println(keys[i].toString()); +// CompositeData cdata = data.get(temp); +// System.out.println(cdata.toString()); +// temp[0] = null; +// } +// TabularType tabular = data.getTabularType(); +//// System.out.println(tabular.toString()); +// List info = tabular.getIndexNames(); +// Iterator it1 = info.iterator(); +// +// do{ +// String temp1 = (String)it1.next(); +// System.out.println(temp1); +// }while(it1.hasNext()); + + } + } catch (Exception ex) { + echo("Given MessageId is invalid, There's no message with the given messageId"); + ex.printStackTrace(); + return; + } + + } else { + if (isname()) { + + echo("The Queue you have specified is not in the current broker"); + echo(""); + } else { + printusage(); + } + } + } + + public void execute() { + /* In here you it's easy to handle any number of otpions which are going to add with the list command which works + with main option object or o + */ + + if (checkoptionsetting("object") || checkoptionsetting("o")) { + String object = optionchecker("object"); + if (object == null) { + object = optionchecker("o"); + } + if (object.compareToIgnoreCase("queue") == 0) + setobject(object); + else { + unrecognizeoption(); + echo("This command is only applicable for delete command so please start with queue"); + } + if (checkoptionsetting("name") || checkoptionsetting("n")) { + String name = optionchecker("name"); + if (name == null) + name = optionchecker("n"); + + setname(name); + } + if (checkoptionsetting("virtualhost") || checkoptionsetting("v")) { + String vhost = optionchecker("virtualhost"); + if (vhost == null) + vhost = optionchecker("v"); + setvhost(vhost); + } + if (checkoptionsetting("messageid") || checkoptionsetting("id")) { + String number = optionchecker("id"); + if (number == null) + number = optionchecker("id"); + + setnumber(removeSpaces(number)); + } + this.viewcontent(); + } else if (checkoptionsetting("h") || checkoptionsetting("help")) + printusage(); + else + unrecognizeoption(); + } + + public void printusage() { + echo(""); + echo("Usage:viewcontent [OPTION] ... [OBJECT TYPE]...\n"); + echo("view the information about given number of messages from the given queue object\n"); + echo("To specify the desired queue you have to give the virtualhost name and the queue name with following commands\n"); + echo("Where possible options include:\n"); + echo(" -v --virtualhost Give the virtuallhost name of the desired queue"); + echo(" -n --name Give the queue name of the desired queue you want to view messages"); + echo(" -id Give the messageId of the required message you want to view the content"); + echo(" -h --help Display the help and back to the qpid-cli prompt\n"); + + } + + private void setobject(String object) { + this.object = object; + } + + private void setname(String name) { + this.name = name; + } + + private boolean isname() { + if (this.name == null) + return false; + + else + return true; + } + + public void setvhost(String vhost) { + this.vhost = vhost; + } + + public String getvhost() { + return this.vhost; + } + + private void setnumber(String number) { + Integer i = new Integer(number); + this.number = i.intValue(); + } + + private static String removeSpaces(String s) { + StringTokenizer st = new StringTokenizer(s, " ", false); + String t = ""; + while (st.hasMoreElements()) t += st.nextElement(); + return t; + } + + public String getname() { + return this.name; + } + + public String getobject() { + return this.object; + } + + public int getnumber() { + return this.number; + } + + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/AllObjects.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/AllObjects.java new file mode 100644 index 0000000000..7f16109f0c --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/AllObjects.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.commands.objects; + +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 20, 2008 + * Time: 9:04:22 AM + * To change this template use File | Settings | File Templates. + */ +public class AllObjects extends ObjectNames { + + public AllObjects(MBeanServerConnection mbsc) { + ObjectNames(mbsc); +// querystring = "org.apache.qpid:*"; +// set = returnObjects(); + } + + public void setQueryString(String object, String name) { + querystring = "org.apache.qpid:*"; + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ConnectionObject.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ConnectionObject.java new file mode 100644 index 0000000000..6c427660c0 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ConnectionObject.java @@ -0,0 +1,54 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.commands.objects; + +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 26, 2008 + * Time: 9:58:02 PM + * To change this template use File | Settings | File Templates. + */ +public class ConnectionObject extends ObjectNames { + public ConnectionObject(MBeanServerConnection mbsc) { + /*calling parent classes constructor */ + ObjectNames(mbsc); +// querystring = "org.apache.qpid:type=VirtualHost.Connection,*"; +// set = returnObjects(); + + } + + public void setQueryString(String object, String name, String vhost) { + if (name != null && vhost == null) + querystring = "org.apache.qpid:type=Connection,name=" + name + ",*"; + else if (name != null && vhost != null) + querystring = "org.apache.qpid:type=Connection,VirtualHost=" + vhost + ",name=" + name + ",*"; + else if (name == null && vhost != null) + querystring = "org.apache.qpid:type=Connection,VirtualHost=" + vhost + ",*"; + else + querystring = "org.apache.qpid:type=Connection,*"; + + } +} + diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ExchangeObject.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ExchangeObject.java new file mode 100644 index 0000000000..22439e9d61 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ExchangeObject.java @@ -0,0 +1,53 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.commands.objects; + +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 24, 2008 + * Time: 12:15:19 AM + * To change this template use File | Settings | File Templates. + */ +public class ExchangeObject extends ObjectNames { + public ExchangeObject(MBeanServerConnection mbsc) { + ObjectNames(mbsc); +// querystring = "org.apache.qpid:type=VirtualHost.Exchange,*"; +// set = returnObjects(); + + } + + public void setQueryString(String object, String name, String vhost) { + if (name != null && vhost == null) + querystring = "org.apache.qpid:type=VirtualHost.Exchange,name=" + name + ",*"; + else if (name != null && vhost != null) + querystring = "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=" + vhost + ",name=" + name + ",*"; + else if (name == null && vhost != null) + querystring = "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=" + vhost + ",*"; + else + querystring = "org.apache.qpid:type=VirtualHost.Exchange,*"; + + } +} + diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ObjectNames.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ObjectNames.java new file mode 100644 index 0000000000..127c9f0a67 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ObjectNames.java @@ -0,0 +1,477 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.commands.objects; + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.management.MBeanInfo; +import java.util.Iterator; +import java.util.Set; +import java.util.List; +import java.util.ArrayList; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 20, 2008 + * Time: 8:39:01 AM + * To change this template use File | Settings | File Templates. + */ +public class ObjectNames { + public String querystring = null; + public MBeanServerConnection mbsc; + public Set set = null; + public String attributes = ""; + public String attributevalues = "";// = null; + + /* method return the Set objects according to the Object type */ + public void ObjectNames(MBeanServerConnection mbsc) { + this.mbsc = mbsc; + } + + public Set returnObjects() { + try { + set = mbsc.queryNames(new ObjectName(querystring), null); + } catch (Exception ex) { + ex.printStackTrace(); + } + return set; + } + + public void echo(String str) { + System.out.println(str); + } + /* display appropriate objects according to the ojbect type */ + + public void displayobjects(String output, String seperator) { + Iterator it = set.iterator(); + String line = ""; + String temp2 = ""; + int iterator = 0; + try { + do { + ObjectName temp_object = null; + if (it.hasNext()) { + temp_object = (ObjectName) it.next(); + if (temp_object == null) + System.out.println("null test"); + } + // echo(temp_object.getCanonicalKeyPropertyListString()); + MBeanInfo bean_info = mbsc.getMBeanInfo(temp_object); + MBeanAttributeInfo[] attr_info = bean_info.getAttributes(); + if (attr_info == null) { + echo(temp_object.toString()); + String temp = ""; + while (temp_object.toString().length() > temp.length()) + temp = "=" + temp; + if (output == null) + echo(temp); + + } else { + for (MBeanAttributeInfo attr : attr_info) { + Object toWrite = null; + + try { + String temp1 = attr.getName(); + if (output == null) { + while (temp1.length() < 15) + temp1 = " " + temp1; + attributes = attributes + temp1 + "|"; + } else if (output.compareToIgnoreCase("csv") == 0) + attributes = attributes + temp1 + seperator; + else { + echo("Wrong output format current version is supporting only for CSV"); + return; + } + } catch (Exception x) { + x.printStackTrace(); + } + } + if (attributes.equalsIgnoreCase("")) { + echo(temp_object.toString()); + String temp = ""; + while (temp_object.toString().length() > temp.length()) + temp = "=" + temp; + echo(temp); + echo("There are no attributes for this object Type"); + return; + } + for (MBeanAttributeInfo attr : attr_info) { + Object toWrite = null; + temp2 = null; + try { + toWrite = mbsc.getAttribute(temp_object, attr.getName()); + } catch (Exception x) { + temp2 = "-"; + } + if (toWrite != null) + temp2 = toWrite.toString(); + else + temp2 = "-"; + if (output == null) { + + while (temp2.length() < 15) + temp2 = " " + temp2; + + attributevalues = attributevalues + temp2 + "|"; + } else if (output.compareToIgnoreCase("csv") == 0) + attributevalues = attributevalues + temp2 + seperator; + + //echo(temp1 + " " + temp2 + " " + temp3); + + + } + } + iterator++; + if (iterator == 1) { + echo(attributes); + for (int i = 0; i < attributes.length(); i++) + line = line + "-"; + if (output == null) + echo(line); + } + echo(attributevalues); + line = ""; + attributes = ""; + attributevalues = ""; + } while (it.hasNext()); + } catch (Exception ex) { + ex.printStackTrace(); + } + + } + + public void reportgenerator(String output, String seperator, List<String> column) { + Iterator it = set.iterator(); + String line = ""; + String temp2 = ""; + int iterator = 0; + try { + do { + ObjectName temp_object = null; + if (it.hasNext()) { + temp_object = (ObjectName) it.next(); + if (temp_object == null) + System.out.println("null test"); + } + // echo(temp_object.getCanonicalKeyPropertyListString()); + MBeanInfo bean_info = mbsc.getMBeanInfo(temp_object); + MBeanAttributeInfo[] attr_info = bean_info.getAttributes(); + if (attr_info == null) { + echo(temp_object.toString()); + String temp = ""; + while (temp_object.toString().length() > temp.length()) + temp = "=" + temp; + if (output == null) + echo(temp); + + } else { + for (MBeanAttributeInfo attr : attr_info) { + Object toWrite = null; + + try { + String temp1 = attr.getName(); + if (column.contains(temp1)) { + if (output == null) { + while (temp1.length() < 15) + temp1 = " " + temp1; + attributes = attributes + temp1 + "|"; + } else if (output.compareToIgnoreCase("csv") == 0) + attributes = attributes + temp1 + seperator; + else { + echo("Wrong output format current version is supporting only for CSV"); + return; + } + } + } catch (Exception x) { + x.printStackTrace(); + } + } + if (attributes.equalsIgnoreCase("")) { + echo(temp_object.toString()); + String temp = ""; + while (temp_object.toString().length() > temp.length()) + temp = "=" + temp; + echo(temp); + echo("There are no attributes for this object Type"); + return; + } + for (MBeanAttributeInfo attr : attr_info) { + Object toWrite = null; + temp2 = null; + if (column.contains(attr.getName())) { + try { + toWrite = mbsc.getAttribute(temp_object, attr.getName()); + } catch (Exception x) { + temp2 = "-"; + } + if (toWrite != null) + temp2 = toWrite.toString(); + else + temp2 = "-"; + if (output == null) { + + while (temp2.length() < 15) + temp2 = " " + temp2; + + attributevalues = attributevalues + temp2 + "|"; + } else if (output.compareToIgnoreCase("csv") == 0) + attributevalues = attributevalues + temp2 + seperator; + + //echo(temp1 + " " + temp2 + " " + temp3); + + } + + + } + } + iterator++; + if (iterator == 1) { + echo(attributes); + for (int i = 0; i < attributes.length(); i++) + line = line + "-"; + if (output == null) + echo(line); + } + echo(attributevalues); + line = ""; + attributes = ""; + attributevalues = ""; + } while (it.hasNext()); + } catch (Exception ex) { + ex.printStackTrace(); + } + + } + + public void displayqueues(String output, String seperator) { + Iterator it = set.iterator(); + String line = ""; + int iterator = 0; + int attr_count = 0; + String temp1 = ""; + String temp2 = ""; + try { + do { + attr_count = 0; + ObjectName temp_object = null; + if (it.hasNext()) { + temp_object = (ObjectName) it.next(); + } + // echo(temp_object.getCanonicalKeyPropertyListString()); + MBeanInfo bean_info = mbsc.getMBeanInfo(temp_object); + MBeanAttributeInfo[] attr_info = bean_info.getAttributes(); + if (attr_info == null) { + echo(temp_object.toString()); + String temp = ""; + while (temp_object.toString().length() > temp.length()) + temp = "=" + temp; + if (output == null) + echo(temp); + + } else { + for (MBeanAttributeInfo attr : attr_info) { + Object toWrite = null; + attr_count++; + try { + toWrite = mbsc.getAttribute(temp_object, attr.getName()); + if (output == null) { + switch (attr_count) { + case 1: + case 3: + temp1 = attr.getName(); + while (temp1.length() < 10) + temp1 = " " + temp1; + attributes = attributes + temp1 + "|"; + temp2 = toWrite.toString(); + while (temp2.length() < 10) + temp2 = " " + temp2; + attributevalues = attributevalues + temp2 + "|"; + break; + case 6: + temp1 = attr.getName(); + while (temp1.length() < 20) + temp1 = " " + temp1; + attributes = attributes + temp1 + "|"; + temp2 = toWrite.toString(); + while (temp2.length() < 20) + temp2 = " " + temp2; + attributevalues = attributevalues + temp2 + "|"; + break; + case 7: + temp1 = attr.getName(); + while (temp1.length() < 13) + temp1 = " " + temp1; + attributes = attributes + temp1 + "|"; + temp2 = toWrite.toString(); + while (temp2.length() < 13) + temp2 = " " + temp2; + attributevalues = attributevalues + temp2 + "|"; + break; + case 9: + temp1 = attr.getName(); + while (temp1.length() < 20) + temp1 = " " + temp1; + attributes = attributes + temp1 + "|"; + temp2 = toWrite.toString(); + while (temp2.length() < 20) + temp2 = " " + temp2; + attributevalues = attributevalues + temp2 + "|"; + break; + } + } else if (output.compareToIgnoreCase("csv") == 0) { + switch (attr_count) { + case 1: + case 3: + case 6: + temp1 = attr.getName(); + attributes = attributes + temp1 + seperator; + temp2 = toWrite.toString(); + attributevalues = attributevalues + temp2 + seperator; + break; + case 7: + temp1 = attr.getName(); + attributes = attributes + temp1 + seperator; + temp2 = toWrite.toString(); + attributevalues = attributevalues + temp2 + seperator; + break; + case 9: + temp1 = attr.getName(); + attributes = attributes + temp1 + seperator; + temp2 = toWrite.toString(); + attributevalues = attributevalues + temp2 + seperator; + break; + } + } else { + echo("Wrong output format specified currently CLI supports only csv output format"); + return; + } + + + } catch (Exception x) { + x.printStackTrace(); + } + + } + } + iterator++; + if (iterator == 1) { + for (int i = 0; i < attributes.length(); i++) + line = line + "-"; + if (output == null) + echo(line); + echo(attributes); + if (output == null) + echo(line); + } + echo(attributevalues); + line = ""; + attributes = ""; + attributevalues = ""; + } while (it.hasNext()); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void displayinfo(String output, String seperator) { + Iterator it = set.iterator(); + String temp1, temp2 = ""; + try { + do { + + ObjectName temp_object = null; + if (it.hasNext()) { + temp_object = (ObjectName) it.next(); + } + // echo(temp_object.getCanonicalKeyPropertyListString()); + MBeanInfo bean_info = mbsc.getMBeanInfo(temp_object); + MBeanAttributeInfo[] attr_info = bean_info.getAttributes(); + if (attr_info == null) { + echo(temp_object.toString()); + String temp = ""; + while (temp_object.toString().length() > temp.length()) + temp = "=" + temp; + echo(temp); + + } else { + echo(temp_object.toString()); + String temp = ""; + while (temp_object.toString().length() > temp.length()) + temp = "=" + temp; + echo(temp); + + for (MBeanAttributeInfo attr : attr_info) { + Object toWrite = null; + + try { + toWrite = mbsc.getAttribute(temp_object, attr.getName()); + } catch (Exception x) { + temp2 = "-"; + } + temp1 = attr.getName(); + if (toWrite != null) + temp2 = toWrite.toString(); + + if (output == null) { + while (temp1.length() < 35) + temp1 = " " + temp1; + + while (temp2.length() < 35) + temp2 = " " + temp2; + echo(temp1 + " " + temp2); + } else if (output.compareToIgnoreCase("csv") == 0) + echo(temp1 + seperator + temp2); + else { + echo("Wrong output format specified currently CLI supports only csv output format"); + return; + } + } + echo(""); + echo(""); + + } + } while (it.hasNext()); + } catch (Exception ex) { + ex.printStackTrace(); + } + + } + + public void setQueryString(String object, String name, String vhost) { + + } + + public void setQueryStringforinfo(String object, String name, String virtualhost) { + + } + + public String getQueryString() { + return querystring; + } + + public Set getSet() { + return set; + } + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/QueueObject.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/QueueObject.java new file mode 100644 index 0000000000..7bbcbf5840 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/QueueObject.java @@ -0,0 +1,86 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.commands.objects; + +import javax.management.MBeanServerConnection; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanInfo; +import javax.management.ObjectName; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 20, 2008 + * Time: 8:49:56 AM + * To change this template use File | Settings | File Templates. + */ +public class QueueObject extends ObjectNames { + public QueueObject(MBeanServerConnection mbsc) { + ObjectNames(mbsc); + } + + public void setQueryString(String object, String name, String vhost) { + if (name != null && vhost == null) + querystring = "org.apache.qpid:type=VirtualHost.Queue,name=" + name + ",*"; + else if (name != null && vhost != null) + querystring = "org.apache.qpid:type=VirtualHost.Queue,VirtualHost=" + vhost + ",name=" + name + ",*"; + else if (name == null && vhost != null) + querystring = "org.apache.qpid:type=VirtualHost.Queue,VirtualHost=" + vhost + ",*"; + else + querystring = "org.apache.qpid:type=VirtualHost.Queue,*"; + } + + public int getmessagecount(ObjectName queue) { + int attr_count = 0; + String value; + Integer depth = null; + + try { + MBeanInfo bean_info; + bean_info = mbsc.getMBeanInfo(queue); + MBeanAttributeInfo[] attr_info = bean_info.getAttributes(); + if (attr_info == null) + return 0; + else { + for (MBeanAttributeInfo attr : attr_info) { + Object toWrite = null; + attr_count++; + toWrite = mbsc.getAttribute(queue, attr.getName()); + if (attr_count == 7) { + value = toWrite.toString(); + depth = new Integer(value); + } + } + + } + + } catch (Exception ex) { + ex.printStackTrace(); + } + if (depth != null) + return depth.intValue(); + else + return -1; + } + + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/UserManagementObject.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/UserManagementObject.java new file mode 100644 index 0000000000..a5f84ea39e --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/UserManagementObject.java @@ -0,0 +1,45 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.commands.objects; + +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 24, 2008 + * Time: 12:11:52 AM + * To change this template use File | Settings | File Templates. + */ +public class UserManagementObject extends ObjectNames { + public UserManagementObject(MBeanServerConnection mbsc) { + ObjectNames(mbsc); +// querystring = "org.apache.qpid:type=UserManagement,*"; +// set = returnObjects(); + + } + + public void setQueryString(String object, String name, String vhost) { + querystring = "org.apache.qpid:type=UserManagement,*"; + } + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/VirtualHostObject.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/VirtualHostObject.java new file mode 100644 index 0000000000..16bb159990 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/VirtualHostObject.java @@ -0,0 +1,53 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.commands.objects; + +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 20, 2008 + * Time: 9:02:04 AM + * To change this template use File | Settings | File Templates. + */ +public class VirtualHostObject extends ObjectNames { + + public VirtualHostObject(MBeanServerConnection mbsc) { + ObjectNames(mbsc); +// querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,*"; +// set = returnObjects(); + } + + public void setQueryString(String object, String name, String vhost) { + if (name != null && vhost == null) + querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,name=" + name + ",*"; + else if (name != null && vhost != null) + querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=" + vhost + ",name=" + name + ",*"; + else if (name == null && vhost != null) + querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=" + vhost + ",*"; + else + querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,*"; + + + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOption.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOption.java new file mode 100644 index 0000000000..fb6afa6344 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOption.java @@ -0,0 +1,112 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +package org.apache.qpid.utils; + +import java.util.ArrayList; + +public class CommandLineOption implements CommandLineOptionConstants { + private String type; + private ArrayList optionValues; + + public CommandLineOption(String type, String[] values) { + setOptionType(type); + ArrayList arrayList = new ArrayList(values.length); + for (int i = 0; i < values.length; i++) { + arrayList.add(values[i]); + } + this.optionValues = arrayList; + } + + private void setOptionType(String type) { + //cater for the long options first + if (type.startsWith("--")) { + type = type.replaceFirst("--", ""); + } + if (type.startsWith("-")) { + type = type.replaceFirst("-", ""); + } + + //we do not change the case of the option! + + this.type = type; + } + + /** + * @param type + */ + public CommandLineOption(String type, ArrayList values) { + setOptionType(type); + + if (null != values) { + this.optionValues = values; + } + } + + + /** + * @return Returns the type. + * @see CommandLineOptionConstants + */ + public String getOptionType() { + return type; + } + + + /** + * @return Returns the optionValues. + */ + public String getOptionValue() { + if ((optionValues != null) && (optionValues.size() > 0)) { + return (String) optionValues.get(0); + } else { + return null; + } + } + + + /** + * @return Returns the optionValues. + */ + public ArrayList getOptionValues() { + return optionValues; + } + + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionConstants.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionConstants.java new file mode 100644 index 0000000000..fe84e2ebd2 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionConstants.java @@ -0,0 +1,53 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +package org.apache.qpid.utils; + + +public interface CommandLineOptionConstants { + static interface JMXCommandLineOptionConstants { + String HOST_OPTION = "h"; + String PORT_OPTION = "p"; + String INTERVAL_OPTION = "i"; + String REPORT_OPTION = "r"; + + } + + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionParser.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionParser.java new file mode 100644 index 0000000000..33a117cad5 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionParser.java @@ -0,0 +1,218 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.qpid.utils; + +import java.util.Map; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.StringTokenizer; + + +public class CommandLineOptionParser { + private static int STARTED = 0; + private static int NEW_OPTION = 1; + private static int SUB_PARAM_OF_OPTION = 2; + + private Map commandlineoption; + private String commandname; + + public CommandLineOptionParser(Map commandlineoptions) { + this.commandlineoption = commandlineoptions; + } + + public CommandLineOptionParser(String[] args) { + /* check whether user just type the enter key */ + this.commandlineoption = this.parse(args); + + } + + public CommandLineOptionParser(String[] args, String first) { + this.commandname = first; + this.commandlineoption = this.parsefirst(args); + } + + public Map parse(String[] args) { + Map commandLineOptions = new HashMap(); + + if (0 == args.length) { + return commandLineOptions; + } else if (1 == args.length) { + commandname = args[0]; + return commandLineOptions; + } + /* when user is not giving the command line option with a "=" */ +// if (!args[2].startsWith("-")) +// return commandLineOptions; + + //State 0 means started + //State 1 means earlier one was a new -option + //State 2 means earlier one was a sub param of a -option + + int state = STARTED; + ArrayList optionBundle = null; + String optionType = null; + CommandLineOption commandLineOption; + String newcommand = ""; + String[] newargs; + int j; + if (args[1].compareTo("list") == 0 || args[1].compareTo("info") == 0 || args[1].compareTo("delete") == 0 || + args[1].compareTo("move") == 0 || args[1].compareTo("view") == 0 || args[1].compareTo("viewcontent") == 0) { + String object = args[0]; + for (j = 0; j < (args.length - 1); j++) { + newcommand = newcommand + args[j + 1] + " "; + } + newcommand = newcommand + "-o " + object; + newargs = newcommand.split(" "); + args = newargs; + } else + if (!args[1].startsWith("-")) //if user give command like list queue or something without minus argument + return commandLineOptions; //for the second wordxi + + commandname = args[0]; + for (int i = 0; i < args.length; i++) { + if (args[i].startsWith("-")) { + if (STARTED == state) { + // fresh one + state = NEW_OPTION; + optionType = args[i]; + } else if (SUB_PARAM_OF_OPTION == state || NEW_OPTION == state) { + // new one but old one should be saved + commandLineOption = + new CommandLineOption(optionType, optionBundle); + commandLineOptions.put(commandLineOption.getOptionType(), + commandLineOption); + state = NEW_OPTION; + optionType = args[i]; + optionBundle = null; + + } + } else { + if (NEW_OPTION == state) { + optionBundle = new ArrayList(); + optionBundle.add(args[i]); + state = SUB_PARAM_OF_OPTION; + + } else if (SUB_PARAM_OF_OPTION == state) { + optionBundle.add(args[i]); + } + + + } + } + commandLineOption = new CommandLineOption(optionType, optionBundle); + commandLineOptions.put(commandLineOption.getOptionType(), commandLineOption); + return commandLineOptions; + + } + + public Map parsefirst(String[] args) { + Map commandLineOptions = new HashMap(); + if (0 == args.length) { + return commandLineOptions; + } else if (1 == args.length) { + return commandLineOptions; + } + /* when user is not giving the command line option with a "=" */ +// if (!args[2].startsWith("-")) +// return commandLineOptions; + + //State 0 means started + //State 1 means earlier one was a new -option + //State 2 means earlier one was a sub param of a -option + + int state = STARTED; + ArrayList optionBundle = null; + String optionType = null; + CommandLineOption commandLineOption; + String newcommand = ""; + String[] newargs; + int j; + + for (int i = 0; i < args.length; i++) { + if (args[i].startsWith("-")) { + if (STARTED == state) { + // fresh one + state = NEW_OPTION; + optionType = args[i]; + } else if (SUB_PARAM_OF_OPTION == state || NEW_OPTION == state) { + // new one but old one should be saved + commandLineOption = + new CommandLineOption(optionType, optionBundle); + commandLineOptions.put(commandLineOption.getOptionType(), + commandLineOption); + state = NEW_OPTION; + optionType = args[i]; + optionBundle = null; + + } + } else { + if (NEW_OPTION == state) { + optionBundle = new ArrayList(); + optionBundle.add(args[i]); + state = SUB_PARAM_OF_OPTION; + + } else if (SUB_PARAM_OF_OPTION == state) { + optionBundle.add(args[i]); + } + + + } + } + commandLineOption = new CommandLineOption(optionType, optionBundle); + commandLineOptions.put(commandLineOption.getOptionType(), commandLineOption); + return commandLineOptions; + + } + + public Map getAlloptions() { + return this.commandlineoption; + } + + public String getcommandname() { + return this.commandname; + } + + private static String removeSpaces(String s) { + StringTokenizer st = new StringTokenizer(s, " ", false); + String t = ""; + while (st.hasMoreElements()) t += st.nextElement(); + return t; + } + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfigProperty.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfigProperty.java new file mode 100644 index 0000000000..27e4527619 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfigProperty.java @@ -0,0 +1,47 @@ +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.qpid.utils; + + +public class JMXConfigProperty { + + private static final String DEFAULT_HOST_NAME = "localhost"; + private static final String DEFAULT_PORT = "8999"; + private static final String DEFAULT_INTERVAL = "4000"; +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfiguration.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfiguration.java new file mode 100644 index 0000000000..622f9d78bd --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfiguration.java @@ -0,0 +1,148 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.qpid.utils; + +import org.apache.qpid.Command; + +import java.util.Map; + +public class JMXConfiguration { + private String hostname = "localhost"; + private String port = "8999"; + private String interval = "40000"; + private String outputpath = "."; + private String report_file = "report.output"; + private boolean isreport_mode = false; + + public JMXConfiguration(Map map) { + if (checkoptionsetting(CommandLineOptionConstants.JMXCommandLineOptionConstants.HOST_OPTION, map)) { + this.hostname = optionchecker(CommandLineOptionConstants.JMXCommandLineOptionConstants.HOST_OPTION, map); + } + if (checkoptionsetting(CommandLineOptionConstants.JMXCommandLineOptionConstants.PORT_OPTION, map)) { + this.port = optionchecker(CommandLineOptionConstants.JMXCommandLineOptionConstants.PORT_OPTION, map); + } + if (checkoptionsetting(CommandLineOptionConstants.JMXCommandLineOptionConstants.REPORT_OPTION, map)) { + + this.report_file = optionchecker(CommandLineOptionConstants.JMXCommandLineOptionConstants.REPORT_OPTION, map); + } + + } + + public void sethostname(String hostname) { + this.hostname = hostname; + } + + public void setport(String port) { + this.port = port; + } + + public void setinterval(String interval) { + this.interval = interval; + } + + public void setoutputpath(String output) { + this.outputpath = output; + } + + public String gethostname() { + return this.hostname; + } + + public String getport() { + return this.port; + } + + public String getinterval() { + return this.interval; + } + + public String getoutputpath() { + return this.outputpath; + } + + public CommandLineOption loadoption(String option, Map options) { + CommandLineOption op = null; + if (option != null) { + op = (CommandLineOption) options.get(option); + + } + return op; + + } + + public void setreportfile(String reportfile) { + this.report_file = reportfile; + this.isreport_mode = true; + + } + + public boolean isreportmode() { + return this.isreport_mode; + } + + public String getreportfile() { + return this.report_file; + } + + public String optionchecker(String option_letter, Map map) { + + if (map == null) + return null; + CommandLineOption option = (CommandLineOption) map.get(option_letter); + if (option == null) + return null; + String value = option.getOptionValue(); + return value; + } + + public boolean checkoptionsetting(String option_letter, Map map) { + if (map == null) + return false; + CommandLineOption option = (CommandLineOption) map.get(option_letter); + if (option == null) + return false; + String value = option.getOptionType(); + + if (value != null) + return true; + else + return false; + } + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXinfo.java b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXinfo.java new file mode 100644 index 0000000000..af3e5c7be0 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXinfo.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. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.utils; + +import javax.management.remote.JMXConnector; +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 3, 2008 + * Time: 9:21:08 PM + * To change this template use File | Settings | File Templates. + */ +public class JMXinfo { + private JMXConnector jmxconnector; + private CommandLineOptionParser input; + private MBeanServerConnection mbserverconnector; + + public JMXinfo(JMXConnector jmxc, CommandLineOptionParser input, MBeanServerConnection mbsc) { + this.jmxconnector = jmxc; + this.input = input; + this.mbserverconnector = mbsc; + } + + public JMXConnector getjmxconnectot() { + return jmxconnector; + } + + public CommandLineOptionParser getCommandLineOptionParser() { + return input; + } + + public MBeanServerConnection getmbserverconnector() { + return mbserverconnector; + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/AllTest.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/AllTest.java new file mode 100644 index 0000000000..bdae5340b5 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/AllTest.java @@ -0,0 +1,80 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.apache.qpid.commands.*; +import org.apache.qpid.commands.objects.*; +import org.apache.qpid.utils.TestCommandLineOption; +import org.apache.qpid.utils.TestCommandLineOptionParser; +import org.apache.qpid.utils.TestJMXConfiguration; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jul 7, 2008 + * Time: 1:09:50 PM + * To change this template use File | Settings | File Templates. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TestCommand.class, + TestCommandExecusionEngine.class, + TestCommandLineOption.class, + TestCommandLineOptionParser.class, + TestConnector.class, + TestJMXConfiguration.class, + TestAllObject.class, + TestConnectionObject.class, + TestExchangeObject.class, + TestQueueObject.class, + TestVirtualHostObject.class, + TestUserManagementObject.class, + TestCommanddelete.class, + TestCommandlist.class, + TestCommandinfo.class, + TestCommandmove.class, + TestCommandview.class, + TestCommandviewcontent.class, + TestCommandLineInterpreter.class + + + }) +public class AllTest { +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/ConnectionConstants.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/ConnectionConstants.java new file mode 100644 index 0000000000..58953e1693 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/ConnectionConstants.java @@ -0,0 +1,51 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.qpid; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Aug 16, 2008 + * Time: 4:55:21 PM + * To change this template use File | Settings | File Templates. + */ +public interface ConnectionConstants { + String BROKER_HOSTNAME="localhost"; + String BROKER_PORT="8999"; +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandExecusionEngine.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandExecusionEngine.java new file mode 100644 index 0000000000..bb5fa914d0 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandExecusionEngine.java @@ -0,0 +1,90 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid; + +import junit.framework.TestCase; +import org.apache.qpid.utils.JMXinfo; +import org.apache.qpid.utils.CommandLineOptionParser; +import org.junit.Before; +import org.junit.Test; +import org.junit.Assert; +import org.junit.After; + +import java.io.IOException; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:06:25 PM + * To change this template use File | Settings | File Templates. + */ +public class TestCommandExecusionEngine { + String line; + String [] command; + CommandLineOptionParser commandlineoptionparser; + JMXinfo info; + CommandExecusionEngine engine; + Connector connector; + @Before + public void setup(){ + + connector = ConnectorFactory.getConnector("localhost","8999"); + + + } + @Test + public void TestCommandSelector() + { + line = "list -o queue"; + command = line.split(" "); + commandlineoptionparser = new CommandLineOptionParser(command); + info = new JMXinfo(connector.getConnector(), commandlineoptionparser,connector.getMBeanServerConnection()); + engine = new CommandExecusionEngine(info); + Assert.assertEquals(engine.CommandSelector(),true); + } + @After + public void cleanup() + { + try { + connector.getConnector().close(); + } catch (IOException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandLineInterpreter.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandLineInterpreter.java new file mode 100644 index 0000000000..36a2d29dfd --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandLineInterpreter.java @@ -0,0 +1,101 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid; + +import junit.framework.TestCase; +import org.apache.qpid.utils.JMXinfo; +import org.apache.qpid.utils.CommandLineOptionParser; +import org.apache.qpid.commands.Commandinfo; +import org.junit.Before; +import org.junit.Test; +import org.junit.Assert; +import org.junit.After; + +import javax.management.remote.JMXConnector; +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:08:52 PM + * To change this template use File | Settings | File Templates. + */ +public class TestCommandLineInterpreter { + +// CommandLineInterpreter test = new CommandLineInterpreter(); + /* In this class there are only methodes which are displaying data on console so no test can be written*/ + String command = "-h " + ConnectionConstants.BROKER_HOSTNAME + " -p " + ConnectionConstants.BROKER_PORT + " info -o queue -n ping -v test"; + Connector conn= null; + JMXConnector jmxc=null; + MBeanServerConnection mbsc=null; + CommandLineOptionParser parser=null; + + + String [] args = null; + @Before + public void startup() + { + args = command.split(" "); +// System.out.println(args[0]); + conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT); + jmxc = conn.getConnector(); + mbsc = conn.getMBeanServerConnection(); + parser = new CommandLineOptionParser(args,args[0]); + + } + @Test + public void TestSetQueryString() + { + CommandLineInterpreter.oneshotmode(args,parser,jmxc,mbsc); + Assert.assertEquals(args[0],"info"); + Assert.assertEquals(args[1],"-o"); + Assert.assertEquals(args[2],"queue"); + Assert.assertEquals(args[3],"-n"); + Assert.assertEquals(args[4],"ping"); + Assert.assertEquals(args[5],"-v"); + Assert.assertEquals(args[6],"test"); + } + + @After + public void cleanup() + { + + } +} + diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestConnector.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestConnector.java new file mode 100644 index 0000000000..e6b80aae66 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestConnector.java @@ -0,0 +1,106 @@ +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid; + +import junit.framework.TestCase; + +import javax.management.remote.JMXServiceURL; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnector; +import javax.management.MBeanServerConnection; +import java.net.MalformedURLException; +import java.io.IOException; + +import org.junit.Test; +import org.junit.Before; +import org.junit.After; +import org.junit.Assert; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:11:50 PM + * To change this template use File | Settings | File Templates. + */ +public class TestConnector { + Connector test; + JMXServiceURL svc_url; + JMXConnector connector; + MBeanServerConnection mbsc; + + @Before + public void setup() + { + test = ConnectorFactory.getConnector("localhost","8999"); + String url = "service:jmx:rmi:///jndi/rmi://localhost:8999/jmxrmi"; + + } + @Test + public void testGetURL() + { + + +// Assert.assertNotNull(test); + Assert.assertEquals(test.getURL(),test.getURL()); + } + @Test + public void testGetConnector() + { + Assert.assertEquals(test.getConnector(),test.getConnector()); + } + @Test + public void testGetMBeanServerConnection() + { + Assert.assertEquals(test.getMBeanServerConnection(),test.getMBeanServerConnection()); + } + @After + public void cleanup() + { + try { + + test.getConnector().close(); + test = null; + } catch (IOException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + test = null; + } + + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestReportGenerator.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestReportGenerator.java new file mode 100644 index 0000000000..a2ed94d948 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestReportGenerator.java @@ -0,0 +1,50 @@ +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Aug 13, 2008 + * Time: 7:16:17 PM + * To change this template use File | Settings | File Templates. + */ +public class TestReportGenerator { + + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommand.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommand.java new file mode 100644 index 0000000000..2c92b8d66d --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommand.java @@ -0,0 +1,99 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.commands; + +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.framework.JUnit4TestAdapter; +import org.junit.Before; +import org.junit.Test; +import org.junit.After; +import org.junit.Assert; +import org.apache.qpid.Connector; +import org.apache.qpid.ConnectorFactory; +import org.apache.qpid.ConnectionConstants; +import org.apache.qpid.utils.JMXinfo; +import org.apache.qpid.utils.CommandLineOptionParser; + +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:21:32 PM + * To change this template use File | Settings | File Templates. + */ +public class TestCommand{ + String command = "list -o queue"; + String [] list; + Connector test; + MBeanServerConnection mbsc; + JMXinfo info; + CommandLineOptionParser parser; + Command cmd; + @Before + public void setup() + { + list = command.split(" "); + parser = new CommandLineOptionParser(list); + test = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME,ConnectionConstants.BROKER_PORT); + info = new JMXinfo(test.getConnector(),parser,test.getMBeanServerConnection()); + cmd = new Command(info,"list"); + + } + @Test + public void TestOptionChecker() + { + Assert.assertEquals(cmd.optionchecker("o"),"queue"); + } + @Test + public void TestCheckOptionSetting() + { + Assert.assertEquals(cmd.checkoptionsetting("o"),true); + Assert.assertEquals(cmd.checkoptionsetting("p"),false); + } + @After + public void cleanup() + { + parser = null; + test = null; + info = null; + cmd = null; + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommanddelete.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommanddelete.java new file mode 100644 index 0000000000..5bdca118d5 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommanddelete.java @@ -0,0 +1,99 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.commands; + +import org.junit.After; +import org.junit.Test; +import org.junit.Before; +import org.junit.Assert; +import org.apache.qpid.ConnectorFactory; +import org.apache.qpid.Connector; +import org.apache.qpid.ConnectionConstants; +import org.apache.qpid.utils.JMXinfo; +import org.apache.qpid.utils.CommandLineOptionParser; + +import javax.management.remote.JMXConnector; +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Aug 11, 2008 + * Time: 10:13:45 PM + * To change this template use File | Settings | File Templates. + */ +public class TestCommanddelete { + JMXinfo info=null; + String command = "delete -o queue -n ping -v test -t 1"; + Commanddelete delete = null; + Connector conn; + @Before + public void startup() + { + conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT); + JMXConnector jmxc = conn.getConnector(); + MBeanServerConnection mbsc = conn.getMBeanServerConnection(); + CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" ")); + info = new JMXinfo(jmxc,parser,mbsc); + delete = new Commanddelete(info,"delete"); + + + + } + @Test + public void TestSetQueryString() + { + delete.execute(); + Assert.assertEquals(delete.getobject(),"queue"); + Assert.assertEquals(delete.getvhost(),"test"); + Assert.assertEquals(delete.getname(),"ping"); + Assert.assertEquals(delete.getnumber(),1); + + } + + @After + public void cleanup() + { + try{ + conn.getConnector().close(); + }catch(Exception ex) + { + ex.printStackTrace(); + } + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandinfo.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandinfo.java new file mode 100644 index 0000000000..f4bb403e18 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandinfo.java @@ -0,0 +1,95 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.commands; + +import org.apache.qpid.utils.JMXinfo; +import org.apache.qpid.utils.CommandLineOptionParser; +import org.apache.qpid.Connector; +import org.apache.qpid.ConnectorFactory; +import org.apache.qpid.ConnectionConstants; +import org.junit.Before; +import org.junit.Test; +import org.junit.Assert; +import org.junit.After; + +import javax.management.remote.JMXConnector; +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Aug 16, 2008 + * Time: 6:30:24 PM + * To change this template use File | Settings | File Templates. + */ +public class TestCommandinfo { + JMXinfo info=null; + String command = "info -o queue -n ping -v test"; + Commandinfo infocommand = null; + Connector conn = null; + @Before + public void startup() + { + conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT); + JMXConnector jmxc = conn.getConnector(); + MBeanServerConnection mbsc = conn.getMBeanServerConnection(); + CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" ")); + info = new JMXinfo(jmxc,parser,mbsc); + infocommand = new Commandinfo(info,"list"); + + } + @Test + public void TestSetQueryString() + { + infocommand.execute(); + Assert.assertEquals(infocommand.getobject(),"queue"); + Assert.assertEquals(infocommand.getvirtualhost(),"test"); + Assert.assertEquals(infocommand.getname(),"ping"); + } + + @After + public void cleanup() + { + try{ + conn.getConnector().close(); + }catch(Exception ex) + { + ex.printStackTrace(); + } + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandlist.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandlist.java new file mode 100644 index 0000000000..c8e044d6fe --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandlist.java @@ -0,0 +1,100 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + /* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.commands; + +import junit.framework.TestCase; +import org.apache.qpid.ConnectionConstants; +import org.apache.qpid.Connector; +import org.apache.qpid.ConnectorFactory; +import org.apache.qpid.utils.CommandLineOptionParser; +import org.apache.qpid.utils.JMXinfo; +import org.junit.Test; +import org.junit.Before; +import org.junit.After; +import org.junit.Assert; + +import javax.management.remote.JMXConnector; +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:18:28 PM + * To change this template use File | Settings | File Templates. + */ +public class TestCommandlist { + /* All the methods in Commandlist doesn't have any arguments + and no return type. + */ + JMXinfo info=null; + String command = "list -o queue -n ping -v test"; + Commandlist list = null; + Connector conn = null; + @Before + public void startup() + { + conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT); + JMXConnector jmxc = conn.getConnector(); + MBeanServerConnection mbsc = conn.getMBeanServerConnection(); + CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" ")); + info = new JMXinfo(jmxc,parser,mbsc); + list = new Commandlist(info,"list"); + + } + @Test + public void TestSetQueryString() + { + list.execute(); + Assert.assertEquals(list.getobject(),"queue"); + Assert.assertEquals(list.getvhost(),"test"); + Assert.assertEquals(list.getname(),"ping"); + } + + @After + public void cleanup() + { + try{ + conn.getConnector().close(); + }catch(Exception ex) + { + ex.printStackTrace(); + } + } + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandmove.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandmove.java new file mode 100644 index 0000000000..278fa72365 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandmove.java @@ -0,0 +1,100 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.commands; + +import org.apache.qpid.ConnectionConstants; +import org.apache.qpid.Connector; +import org.apache.qpid.ConnectorFactory; +import org.apache.qpid.utils.CommandLineOptionParser; +import org.apache.qpid.utils.JMXinfo; +import org.junit.Before; +import org.junit.Test; +import org.junit.After; +import org.junit.Assert; + +import javax.management.remote.JMXConnector; +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Aug 11, 2008 + * Time: 10:14:34 PM + * To change this template use File | Settings | File Templates. + */ +public class TestCommandmove { + JMXinfo info=null; + String command = "move -o queue -n1 ping -v1 test -n2 message_queue -fmid 10 -tmid 12"; + Commandmove move = null; + Connector conn=null; + @Before + public void startup() + { + conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT); + JMXConnector jmxc = conn.getConnector(); + MBeanServerConnection mbsc = conn.getMBeanServerConnection(); + CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" ")); + info = new JMXinfo(jmxc,parser,mbsc); + move = new Commandmove(info,"move"); + + + + } + @Test + public void TestSetQueryString() + { + move.execute(); + Assert.assertEquals(move.getobject(),"queue"); + Assert.assertEquals(move.getvhost(),"test"); + Assert.assertEquals(move.getname1(),"ping"); + Assert.assertEquals(move.getname2(),"message_queue"); + Assert.assertEquals(move.getfmid(),10); + Assert.assertEquals(move.gettmid(),12); + } + + @After + public void cleanup() + { + try{ + conn.getConnector().close(); + }catch(Exception ex) + { + ex.printStackTrace(); + } + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandview.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandview.java new file mode 100644 index 0000000000..385d197475 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandview.java @@ -0,0 +1,96 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.commands; + +import org.apache.qpid.ConnectionConstants; +import org.apache.qpid.ConnectorFactory; +import org.apache.qpid.Connector; +import org.apache.qpid.utils.CommandLineOptionParser; +import org.apache.qpid.utils.JMXinfo; +import org.junit.Test; +import org.junit.Before; +import org.junit.After; +import org.junit.Assert; + +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Aug 11, 2008 + * Time: 10:14:58 PM + * To change this template use File | Settings | File Templates. + */ +public class TestCommandview { + JMXinfo info=null; + String command = "view -o queue -n ping -v test -t 10"; + Commandview view =null; + Connector conn=null; + @Before + public void startup() + { + conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT); + JMXConnector jmxc = conn.getConnector(); + MBeanServerConnection mbsc = conn.getMBeanServerConnection(); + CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" ")); + info = new JMXinfo(jmxc,parser,mbsc); + view = new Commandview(info,"view"); + } + @Test + public void TestSetQueryString() + { + view.execute(); + Assert.assertEquals(view.getobject(),"queue"); + Assert.assertEquals(view.getvhost(),"test"); + Assert.assertEquals(view.getname(),"ping"); + Assert.assertEquals(view.getnumber(),10); + + } + + @After + public void cleanup() + { + try{ + conn.getConnector().close(); + }catch(Exception ex) + { + ex.printStackTrace(); + } + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandviewcontent.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandviewcontent.java new file mode 100644 index 0000000000..2b8f0e3ffd --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandviewcontent.java @@ -0,0 +1,99 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.commands; + +import org.apache.qpid.utils.JMXinfo; +import org.apache.qpid.utils.CommandLineOptionParser; +import org.apache.qpid.Connector; +import org.apache.qpid.ConnectorFactory; +import org.apache.qpid.ConnectionConstants; +import org.junit.Before; +import org.junit.Test; +import org.junit.After; +import org.junit.Assert; + +import javax.management.remote.JMXConnector; +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Aug 11, 2008 + * Time: 10:15:17 PM + * To change this template use File | Settings | File Templates. + */ +public class TestCommandviewcontent { + JMXinfo info=null; + String command = "viewcontent -o queue -n ping -v test -id 10"; + Commandviewcontent viewcontent =null; + Connector conn = null; + @Before + public void startup() + { + conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT); + JMXConnector jmxc = conn.getConnector(); + MBeanServerConnection mbsc = conn.getMBeanServerConnection(); + CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" ")); + info = new JMXinfo(jmxc,parser,mbsc); + viewcontent = new Commandviewcontent(info,"viewcontent"); + + + + } + @Test + public void TestSetQueryString() + { + viewcontent.execute(); + Assert.assertEquals(viewcontent.getobject(),"queue"); + Assert.assertEquals(viewcontent.getnumber(),10); + Assert.assertEquals(viewcontent.getname(),"ping"); + Assert.assertEquals(viewcontent.getvhost(),"test"); + + } + + @After + public void cleanup() + { + try{ + conn.getConnector().close(); + }catch(Exception ex) + { + ex.printStackTrace(); + } + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestAllObject.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestAllObject.java new file mode 100644 index 0000000000..25069e6dbb --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestAllObject.java @@ -0,0 +1,93 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.commands.objects; + +import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.After; +import org.junit.Assert; +import org.apache.qpid.ConnectorFactory; +import org.apache.qpid.Connector; + +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:23:25 PM + * To change this template use File | Settings | File Templates. + */ +public class TestAllObject { + Connector conn; + MBeanServerConnection mbsc; + AllObjects test; + String test1,test2; + + @Before + public void startup() + { + conn = ConnectorFactory.getConnector("localhost", "8999"); + mbsc = conn.getMBeanServerConnection(); + test = new AllObjects(mbsc); + test1 = "empty input1"; + test2 = "empty input2"; + + + } + @Test + public void TestSetQueryString() + { + test.setQueryString(test1,test2); + Assert.assertEquals(test.querystring,"org.apache.qpid:*"); + + } + + @After + public void cleanup() + { + try{ + conn.getConnector().close(); + }catch(Exception ex) + { + ex.printStackTrace(); + } + + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestConnectionObject.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestConnectionObject.java new file mode 100644 index 0000000000..8f98d1ac37 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestConnectionObject.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. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.commands.objects; + +import junit.framework.TestCase; +import org.apache.qpid.ConnectorFactory; +import org.apache.qpid.Connector; +import org.junit.After; +import org.junit.Test; +import org.junit.Assert; +import org.junit.Before; + +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:24:14 PM + * To change this template use File | Settings | File Templates. + */ +public class TestConnectionObject { + Connector conn; + MBeanServerConnection mbsc; + ConnectionObject test; + String test1,test2,test3; + + @Before + public void startup() + { + conn = ConnectorFactory.getConnector("localhost", "8999"); + mbsc = conn.getMBeanServerConnection(); + test = new ConnectionObject(mbsc); + test1 = "ping"; + test2 = "test"; + test3 = "object"; + + + } + @Test + public void TestSetQueryString() + { + test.setQueryString(test3,test1,null); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=Connection,name=ping,*"); + test.querystring = null; + test.setQueryString(test3,null,test2); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=Connection,VirtualHost=test,*"); + test.querystring = null; + test.setQueryString(test3,test1,test2); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=Connection,VirtualHost=test,name=ping,*"); + test.querystring = null; + test.setQueryString(test3,null,null); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=Connection,*"); + + + + } + + @After + public void cleanup() + { + try{ + conn.getConnector().close(); + }catch(Exception ex) + { + ex.printStackTrace(); + } + + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestExchangeObject.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestExchangeObject.java new file mode 100644 index 0000000000..64f2bef79a --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestExchangeObject.java @@ -0,0 +1,103 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.commands.objects; + +import junit.framework.TestCase; +import org.junit.Assert; +import org.junit.Test; +import org.junit.After; +import org.junit.Before; +import org.apache.qpid.Connector; +import org.apache.qpid.ConnectorFactory; + +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:24:49 PM + * To change this template use File | Settings | File Templates. + */ +public class TestExchangeObject { + Connector conn; + MBeanServerConnection mbsc; + ExchangeObject test; + String test1,test2,test3; + + @Before + public void startup() + { + conn = ConnectorFactory.getConnector("localhost", "8999"); + mbsc = conn.getMBeanServerConnection(); + test = new ExchangeObject(mbsc); + test1 = "ping"; + test2 = "test"; + test3 = "object"; + + + } + @Test + public void TestSetQueryString() + { + test.setQueryString(test3,test1,null); +// System.out.println(test.querystring); +// System.out.println("org.apache.qpid:type=VitualHost.Exchange,name=ping,*"); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=VirtualHost.Exchange,name=ping,*"); + test.querystring = null; + test.setQueryString(test3,null,test2); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=test,*"); + test.querystring = null; + test.setQueryString(test3,test1,test2); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=test,name=ping,*"); + test.querystring = null; + test.setQueryString(test3,null,null); + } + + @After + public void cleanup() + { + try{ + conn.getConnector().close(); + }catch(Exception ex) + { + ex.printStackTrace(); + } + + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestObjectNames.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestObjectNames.java new file mode 100644 index 0000000000..b26d1f5a82 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestObjectNames.java @@ -0,0 +1,51 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.commands.objects; + +import junit.framework.TestCase; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:22:54 PM + * To change this template use File | Settings | File Templates. + */ +public class TestObjectNames { + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestQueueObject.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestQueueObject.java new file mode 100644 index 0000000000..96b153f65d --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestQueueObject.java @@ -0,0 +1,106 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.commands.objects; + +import junit.framework.TestCase; +import org.junit.Assert; +import org.junit.Test; +import org.junit.After; +import org.junit.Before; +import org.apache.qpid.Connector; +import org.apache.qpid.ConnectorFactory; + +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:25:21 PM + * To change this template use File | Settings | File Templates. + */ +public class TestQueueObject{ + Connector conn; + MBeanServerConnection mbsc; + QueueObject test; + String test1,test2,test3; + + @Before + public void startup() + { + conn = ConnectorFactory.getConnector("localhost", "8999"); + mbsc = conn.getMBeanServerConnection(); + test = new QueueObject(mbsc); + test1 = "ping"; + test2 = "test"; + test3 = "object"; + + + } + @Test + public void TestSetQueryString() + { + test.setQueryString(test3,test1,null); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=VirtualHost.Queue,name=ping,*"); + test.querystring = null; + test.setQueryString(test3,null,test2); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=VirtualHost.Queue,VirtualHost=test,*"); + test.querystring = null; + test.setQueryString(test3,test1,test2); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=VirtualHost.Queue,VirtualHost=test,name=ping,*"); + test.querystring = null; + test.setQueryString(test3,null,null); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=VirtualHost.Queue,*"); + + + + } + + @After + public void cleanup() + { + try{ + conn.getConnector().close(); + }catch(Exception ex) + { + ex.printStackTrace(); + } + + } +} + diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestUserManagementObject.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestUserManagementObject.java new file mode 100644 index 0000000000..a9123eb604 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestUserManagementObject.java @@ -0,0 +1,102 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.commands.objects; + +import junit.framework.TestCase; +import org.junit.Assert; +import org.junit.After; +import org.junit.Test; +import org.junit.Before; +import org.apache.qpid.Connector; +import org.apache.qpid.ConnectorFactory; + +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:26:09 PM + * To change this template use File | Settings | File Templates. + */ + + + +public class TestUserManagementObject{ + Connector conn; + MBeanServerConnection mbsc; + UserManagementObject test; + String test1,test2,test3; + + @Before + public void startup() + { + conn = ConnectorFactory.getConnector("localhost", "8999"); + mbsc = conn.getMBeanServerConnection(); + test = new UserManagementObject(mbsc); + test1 = "ping"; + test2 = "test"; + test3 = "object"; + + + } + @Test + public void TestSetQueryString() + { + test.setQueryString(test3,test1,test2); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=UserManagement,*"); + + + + + } + + @After + public void cleanup() + { + try{ + conn.getConnector().close(); + }catch(Exception ex) + { + ex.printStackTrace(); + } + + } +} + + diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestVirtualHostObject.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestVirtualHostObject.java new file mode 100644 index 0000000000..29a233733d --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestVirtualHostObject.java @@ -0,0 +1,88 @@ +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ +package org.apache.qpid.commands.objects; + +import junit.framework.TestCase; +import org.junit.Assert; +import org.junit.After; +import org.junit.Test; +import org.junit.Before; +import org.apache.qpid.Connector; +import org.apache.qpid.ConnectorFactory; + +import javax.management.MBeanServerConnection; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:26:40 PM + * To change this template use File | Settings | File Templates. + */ +public class TestVirtualHostObject{ + Connector conn; + MBeanServerConnection mbsc; + VirtualHostObject test; + String test1,test2,test3; + + @Before + public void startup() + { + conn = ConnectorFactory.getConnector("localhost", "8999"); + mbsc = conn.getMBeanServerConnection(); + test = new VirtualHostObject(mbsc); + test1 = "ping"; + test2 = "test"; + test3 = "object"; + + + } + @Test + public void TestSetQueryString() + { + test.setQueryString(test3,test1,null); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=VirtualHost.VirtualHostManager,name=ping,*"); + test.querystring = null; + test.setQueryString(test3,null,test2); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=test,*"); + test.querystring = null; + test.setQueryString(test3,test1,test2); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=test,name=ping,*"); + test.querystring = null; + test.setQueryString(test3,null,null); + Assert.assertEquals(test.querystring,"org.apache.qpid:type=VirtualHost.VirtualHostManager,*"); + + + + } + + @After + public void cleanup() + { + try{ + conn.getConnector().close(); + }catch(Exception ex) + { + ex.printStackTrace(); + } + + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOption.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOption.java new file mode 100644 index 0000000000..58d71a4de6 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOption.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. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.utils; + +import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.Assert; +import org.junit.After; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:17:26 PM + * To change this template use File | Settings | File Templates. + */ +public class TestCommandLineOption { + String input1; + String input2; + String options; + String [] list; + CommandLineOption option; + + @Before + public void setup() + { + input1 = "-h"; + input2 = "--help"; + options = "localhost testing"; + list = options.split(" "); + option = new CommandLineOption(input1,list); + + } + @Test + public void TestGetOptinValue() + { + Assert.assertEquals(option.getOptionValue(),"localhost"); + } + @Test + public void TestGetOptionType() + { + Assert.assertEquals(option.getOptionType(),"h"); + } + @After + public void cleanup() + { + option = null; + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOptionParser.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOptionParser.java new file mode 100644 index 0000000000..989fc61418 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOptionParser.java @@ -0,0 +1,100 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.utils; + +import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.After; +import org.junit.Assert; + +import java.util.Map; +import java.util.HashMap; +import java.util.ArrayList; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:16:30 PM + * To change this template use File | Settings | File Templates. + */ +public class TestCommandLineOptionParser { + CommandLineOptionParser parser; + String [] input; + CommandLineOption option1; + CommandLineOption option2; + ArrayList list1; + ArrayList list2; + @Before + public void setup() + { + String temp = "run -h localhost -p 23232"; + input = temp.split(" "); + parser = new CommandLineOptionParser(input); + list1 = new ArrayList(); + list2 = new ArrayList(); + } + @Test + public void TestParse() + { + Map hash = new HashMap(); + + list1.add("localhost"); + list2.add("23232"); + option1 = new CommandLineOption("h",list1); + option2 = new CommandLineOption("p",list2); + hash.put("h",option1); + hash.put("p",option2); + option1 = (CommandLineOption)parser.parse(input).get("h"); + Assert.assertEquals(option1.getOptionType(),"h"); + Assert.assertEquals(option1.getOptionValue(),"localhost"); + option1 = (CommandLineOption)parser.parse(input).get("p"); + Assert.assertEquals(option1.getOptionType(),"p"); + Assert.assertEquals(option1.getOptionValue(),"23232"); + Assert.assertEquals(parser.parse(input).size(),hash.size()); + } + @After + public void cleanup() + { + parser = null; + option1 = null; + option2 = null; + + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfigProperty.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfigProperty.java new file mode 100644 index 0000000000..a5d3122406 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfigProperty.java @@ -0,0 +1,51 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.utils; + +import junit.framework.TestCase; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:15:35 PM + * To change this template use File | Settings | File Templates. + */ +public class TestJMXConfigProperty { + +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfiguration.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfiguration.java new file mode 100644 index 0000000000..02dd7219db --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfiguration.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. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.utils; + +import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.After; +import org.junit.Assert; + +import java.util.ArrayList; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:14:32 PM + * To change this template use File | Settings | File Templates. + */ +public class TestJMXConfiguration { + CommandLineOptionParser clop; + JMXConfiguration jmc; + CommandLineOption option; + String [] input; + @Before + public void setup() + { + String temp = "command -h 127.0.0.1 -p 1234"; + input = temp.split(" "); + clop = new CommandLineOptionParser(input); + jmc = new JMXConfiguration(clop.getAlloptions()); + } + @Test + public void TestLoadOption() + { + ArrayList list = new ArrayList(); + list.add("127.0.0.1"); + option = new CommandLineOption("-h",list); + CommandLineOption expect = jmc.loadoption("h",clop.getAlloptions()); + Assert.assertEquals(expect.getOptionType(),option.getOptionType()); + Assert.assertEquals(expect.getOptionValue(),option.getOptionValue()); + } + @After + public void cleanup() + { + clop = null; + jmc = null; + option = null; + } +} diff --git a/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXinfo.java b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXinfo.java new file mode 100644 index 0000000000..449609c639 --- /dev/null +++ b/RC9/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXinfo.java @@ -0,0 +1,53 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.utils; + +import junit.framework.TestCase; + +/** + * Created by IntelliJ IDEA. + * User: lahiru + * Date: Jun 30, 2008 + * Time: 12:12:43 PM + * To change this template use File | Settings | File Templates. + */ +public class TestJMXinfo { + /* this class is having only three simple getter methods. Therefore no + testcases + */ +} |
