From 913489deb2ee9dbf44455de5f407ddaf4bd8c540 Mon Sep 17 00:00:00 2001 From: "Rafael H. Schloming" Date: Tue, 19 Sep 2006 22:06:50 +0000 Subject: Import of qpid from etp: URL: https://etp.108.redhat.com/svn/etp/trunk/blaze Repository Root: https://etp.108.redhat.com/svn/etp Repository UUID: 06e15bec-b515-0410-bef0-cc27a458cf48 Revision: 608 git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@447994 13f79535-47bb-0310-9956-ffa450edef68 --- java/management/cli/bin/stac.bat | 38 ++ java/management/cli/bin/stac.sh | 39 ++ java/management/cli/bin/stacDEV.bat | 41 ++ java/management/cli/build-module.xml | 21 + java/management/cli/build-old.xml | 122 +++++ java/management/cli/lib/jython/jython.jar | Bin 0 -> 719950 bytes .../cli/src/org/apache/qpid/stac/Stac.java | 94 ++++ .../src/org/apache/qpid/stac/StacInterpreter.java | 31 ++ .../org/apache/qpid/stac/commands/CdCommand.java | 50 ++ .../apache/qpid/stac/commands/InvokeCommand.java | 31 ++ .../org/apache/qpid/stac/commands/LsCommand.java | 123 +++++ .../src/org/apache/qpid/stac/jmx/CurrentMBean.java | 180 +++++++ .../stac/jmx/MBeanAttributeInfoComparator.java | 29 + .../stac/jmx/MBeanOperationInfoComparator.java | 29 + .../stac/jmx/MBeanServerConnectionContext.java | 202 +++++++ .../src/org/apache/qpid/stac/jmx/MBeanUtils.java | 35 ++ .../qpid/stac/jmx/NotConnectedException.java | 28 + java/management/cli/src/python/stac.py | 190 +++++++ .../test/org/apache/qpid/stac/ConnectionTest.java | 35 ++ java/management/core/build-module.xml | 47 ++ java/management/core/build-old.xml | 189 +++++++ java/management/core/etc/cml-exampleschema.xml | 51 ++ java/management/core/etc/cml.xsd | 175 ++++++ .../lib/jakarta-commons/commons-attributes-api.jar | Bin 0 -> 36342 bytes .../commons-attributes-compiler.jar | Bin 0 -> 29216 bytes .../core/lib/jakarta-commons/commons-beanutils.jar | Bin 0 -> 188671 bytes .../core/lib/jakarta-commons/commons-codec.jar | Bin 0 -> 46725 bytes .../lib/jakarta-commons/commons-collections.jar | Bin 0 -> 559366 bytes .../core/lib/jakarta-commons/commons-dbcp.jar | Bin 0 -> 107631 bytes .../core/lib/jakarta-commons/commons-digester.jar | Bin 0 -> 168446 bytes .../core/lib/jakarta-commons/commons-discovery.jar | Bin 0 -> 74527 bytes .../lib/jakarta-commons/commons-fileupload.jar | Bin 0 -> 22379 bytes .../lib/jakarta-commons/commons-httpclient.jar | Bin 0 -> 279317 bytes .../core/lib/jakarta-commons/commons-lang.jar | Bin 0 -> 207723 bytes .../core/lib/jakarta-commons/commons-logging.jar | Bin 0 -> 38015 bytes .../core/lib/jakarta-commons/commons-pool.jar | Bin 0 -> 42492 bytes .../core/lib/jakarta-commons/commons-validator.jar | Bin 0 -> 84462 bytes java/management/core/lib/log4j/log4j-1.2.9.jar | Bin 0 -> 352291 bytes java/management/core/lib/spring/spring-beans.dtd | 587 +++++++++++++++++++++ java/management/core/lib/spring/spring.ftl | 316 +++++++++++ java/management/core/lib/spring/spring.tld | 311 +++++++++++ java/management/core/lib/spring/spring.vm | 294 +++++++++++ java/management/core/lib/xmlbeans/jsr173_api.jar | Bin 0 -> 26396 bytes java/management/core/lib/xmlbeans/resolver.jar | Bin 0 -> 60047 bytes java/management/core/lib/xmlbeans/saxon8.jar | Bin 0 -> 2297989 bytes java/management/core/lib/xmlbeans/xbean.jar | Bin 0 -> 2526707 bytes java/management/core/lib/xmlbeans/xbean_xpath.jar | Bin 0 -> 5182 bytes java/management/core/lib/xmlbeans/xmlpublic.jar | Bin 0 -> 425062 bytes java/management/core/src/log4j.properties | 6 + .../qpid/management/ManagementConnection.java | 120 +++++ .../org/apache/qpid/management/jmx/AMQConsole.java | 95 ++++ .../apache/qpid/management/jmx/AMQMBeanInfo.java | 40 ++ .../org/apache/qpid/management/jmx/CMLMBean.java | 298 +++++++++++ .../apache/qpid/management/jmx/JmxConstants.java | 23 + .../qpid/management/jmx/MBeanInfoRegistry.java | 201 +++++++ .../apache/qpid/management/jmx/MBeanRegistrar.java | 141 +++++ .../jmx/UnsupportedCMLTypeException.java | 36 ++ .../management/messaging/CMLMessageFactory.java | 59 +++ .../messaging/ManagementDestination.java | 43 ++ .../qpid/management/harness/SimpleJMXClient.java | 25 + .../qpid/management/schema/TestParseSchema.java | 87 +++ java/management/mc4j/qpid/BlazeConnections.xml | 84 +++ java/management/mc4j/qpid/BlazeExchanges.xml | 81 +++ java/management/mc4j/qpid/BlazeQueues.xml | 83 +++ java/management/mc4j/qpid/BlazeSingleQueue.xml | 99 ++++ java/management/webapp/META-INF/context.xml | 20 + java/management/webapp/WEB-INF/web.xml | 24 + 67 files changed, 4853 insertions(+) create mode 100644 java/management/cli/bin/stac.bat create mode 100755 java/management/cli/bin/stac.sh create mode 100644 java/management/cli/bin/stacDEV.bat create mode 100644 java/management/cli/build-module.xml create mode 100644 java/management/cli/build-old.xml create mode 100644 java/management/cli/lib/jython/jython.jar create mode 100644 java/management/cli/src/org/apache/qpid/stac/Stac.java create mode 100644 java/management/cli/src/org/apache/qpid/stac/StacInterpreter.java create mode 100644 java/management/cli/src/org/apache/qpid/stac/commands/CdCommand.java create mode 100644 java/management/cli/src/org/apache/qpid/stac/commands/InvokeCommand.java create mode 100644 java/management/cli/src/org/apache/qpid/stac/commands/LsCommand.java create mode 100644 java/management/cli/src/org/apache/qpid/stac/jmx/CurrentMBean.java create mode 100644 java/management/cli/src/org/apache/qpid/stac/jmx/MBeanAttributeInfoComparator.java create mode 100644 java/management/cli/src/org/apache/qpid/stac/jmx/MBeanOperationInfoComparator.java create mode 100644 java/management/cli/src/org/apache/qpid/stac/jmx/MBeanServerConnectionContext.java create mode 100644 java/management/cli/src/org/apache/qpid/stac/jmx/MBeanUtils.java create mode 100644 java/management/cli/src/org/apache/qpid/stac/jmx/NotConnectedException.java create mode 100644 java/management/cli/src/python/stac.py create mode 100644 java/management/cli/test/org/apache/qpid/stac/ConnectionTest.java create mode 100644 java/management/core/build-module.xml create mode 100644 java/management/core/build-old.xml create mode 100644 java/management/core/etc/cml-exampleschema.xml create mode 100644 java/management/core/etc/cml.xsd create mode 100644 java/management/core/lib/jakarta-commons/commons-attributes-api.jar create mode 100644 java/management/core/lib/jakarta-commons/commons-attributes-compiler.jar create mode 100644 java/management/core/lib/jakarta-commons/commons-beanutils.jar create mode 100644 java/management/core/lib/jakarta-commons/commons-codec.jar create mode 100644 java/management/core/lib/jakarta-commons/commons-collections.jar create mode 100644 java/management/core/lib/jakarta-commons/commons-dbcp.jar create mode 100644 java/management/core/lib/jakarta-commons/commons-digester.jar create mode 100644 java/management/core/lib/jakarta-commons/commons-discovery.jar create mode 100644 java/management/core/lib/jakarta-commons/commons-fileupload.jar create mode 100644 java/management/core/lib/jakarta-commons/commons-httpclient.jar create mode 100644 java/management/core/lib/jakarta-commons/commons-lang.jar create mode 100644 java/management/core/lib/jakarta-commons/commons-logging.jar create mode 100644 java/management/core/lib/jakarta-commons/commons-pool.jar create mode 100644 java/management/core/lib/jakarta-commons/commons-validator.jar create mode 100644 java/management/core/lib/log4j/log4j-1.2.9.jar create mode 100644 java/management/core/lib/spring/spring-beans.dtd create mode 100644 java/management/core/lib/spring/spring.ftl create mode 100644 java/management/core/lib/spring/spring.tld create mode 100644 java/management/core/lib/spring/spring.vm create mode 100644 java/management/core/lib/xmlbeans/jsr173_api.jar create mode 100644 java/management/core/lib/xmlbeans/resolver.jar create mode 100644 java/management/core/lib/xmlbeans/saxon8.jar create mode 100644 java/management/core/lib/xmlbeans/xbean.jar create mode 100644 java/management/core/lib/xmlbeans/xbean_xpath.jar create mode 100644 java/management/core/lib/xmlbeans/xmlpublic.jar create mode 100644 java/management/core/src/log4j.properties create mode 100644 java/management/core/src/org/apache/qpid/management/ManagementConnection.java create mode 100644 java/management/core/src/org/apache/qpid/management/jmx/AMQConsole.java create mode 100644 java/management/core/src/org/apache/qpid/management/jmx/AMQMBeanInfo.java create mode 100644 java/management/core/src/org/apache/qpid/management/jmx/CMLMBean.java create mode 100644 java/management/core/src/org/apache/qpid/management/jmx/JmxConstants.java create mode 100644 java/management/core/src/org/apache/qpid/management/jmx/MBeanInfoRegistry.java create mode 100644 java/management/core/src/org/apache/qpid/management/jmx/MBeanRegistrar.java create mode 100644 java/management/core/src/org/apache/qpid/management/jmx/UnsupportedCMLTypeException.java create mode 100644 java/management/core/src/org/apache/qpid/management/messaging/CMLMessageFactory.java create mode 100644 java/management/core/src/org/apache/qpid/management/messaging/ManagementDestination.java create mode 100644 java/management/core/test/org/apache/qpid/management/harness/SimpleJMXClient.java create mode 100644 java/management/core/test/org/apache/qpid/management/schema/TestParseSchema.java create mode 100644 java/management/mc4j/qpid/BlazeConnections.xml create mode 100644 java/management/mc4j/qpid/BlazeExchanges.xml create mode 100644 java/management/mc4j/qpid/BlazeQueues.xml create mode 100644 java/management/mc4j/qpid/BlazeSingleQueue.xml create mode 100644 java/management/webapp/META-INF/context.xml create mode 100644 java/management/webapp/WEB-INF/web.xml (limited to 'java/management') diff --git a/java/management/cli/bin/stac.bat b/java/management/cli/bin/stac.bat new file mode 100644 index 0000000000..156b7792cb --- /dev/null +++ b/java/management/cli/bin/stac.bat @@ -0,0 +1,38 @@ +@REM +@REM Copyright (c) 2006 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM 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, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@echo off +set COREROOT=..\..\core +set AMQROOT=..\..\..\clients_java + +set CP=..\lib\jython\jython.jar +set CP=%CP%;..\dist\amqp-stac.jar +set CP=%CP%;%COREROOT%\dist\amqp-management-common.jar +set CP=%CP%;%COREROOT%\lib\log4j\log4j-1.2.9.jar +set CP=%CP%;%COREROOT%\lib\xmlbeans\jsr173_api.jar +set CP=%CP%;%COREROOT%\lib\xmlbeans\resolver.jar +set CP=%CP%;%COREROOT%\lib\xmlbeans\xbean.jar +set CP=%CP%;%COREROOT%\lib\xmlbeans\xbean_xpath.jar +set CP=%CP%;%COREROOT%\lib\xmlbeans\xmlpublic.jar +set CP=%CP%;%COREROOT%\lib\xmlbeans\saxon8.jar +set CP=%CP%;%AMQROOT%\dist\amqp-common.jar +set CP=%CP%;%AMQROOT%\dist\amqp-jms.jar +set CP=%CP%;%AMQROOT%\lib\mina\mina-0.7.3.jar +set CP=%CP%;%AMQROOT%\lib\jms\jms.jar +set CP=%CP%;%AMQROOT%\lib\util-concurrent\backport-util-concurrent.jar +set CP=%CP%;%AMQROOT%\lib\jakarta-commons\commons-collections-3.1.jar + +%JAVA_HOME%\bin\java -Damqj.logging.level="ERROR" -cp %CP% org.apache.qpid.stac.Stac diff --git a/java/management/cli/bin/stac.sh b/java/management/cli/bin/stac.sh new file mode 100755 index 0000000000..8fabe3a606 --- /dev/null +++ b/java/management/cli/bin/stac.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# +# 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. +# + + +COREROOT=../../core +AMQROOT=../../../clients_java + +CP=../lib/jython/jython.jar +CP=$CP:../dist/amqp-stac.jar +CP=$CP:$COREROOT/dist/amqp-management-common.jar +CP=$CP:$COREROOT/lib/log4j/log4j-1.2.9.jar +CP=$CP:$COREROOT/lib/xmlbeans/jsr173_api.jar +CP=$CP:$COREROOT/lib/xmlbeans/resolver.jar +CP=$CP:$COREROOT/lib/xmlbeans/xbean.jar +CP=$CP:$COREROOT/lib/xmlbeans/xbean_xpath.jar +CP=$CP:$COREROOT/lib/xmlbeans/xmlpublic.jar +CP=$CP:$COREROOT/lib/xmlbeans/saxon8.jar +CP=$CP:$AMQROOT/dist/amqp-common.jar +CP=$CP:$AMQROOT/dist/amqp-jms.jar +CP=$CP:$AMQROOT/lib/mina/mina-0.7.3.jar +CP=$CP:$AMQROOT/lib/jms/jms.jar +CP=$CP:$AMQROOT/lib/util-concurrent/backport-util-concurrent.jar +CP=$CP:$AMQROOT/lib/jakarta-commons/commons-collections-3.1.jar + +$JAVA_HOME/bin/java -Damqj.logging.level="ERROR" -cp $CP org.apache.qpid.stac.Stac diff --git a/java/management/cli/bin/stacDEV.bat b/java/management/cli/bin/stacDEV.bat new file mode 100644 index 0000000000..2a5bb88065 --- /dev/null +++ b/java/management/cli/bin/stacDEV.bat @@ -0,0 +1,41 @@ +@REM +@REM Copyright (c) 2006 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM 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, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@echo off +set COREROOT=..\..\core +set AMQROOT=..\..\..\clients_java + +set CP=..\lib\jython\jython.jar +set CP=%CP%;..\intellijclasses +set CP=%CP%;%COREROOT%\intellijclasses +set CP=%CP%;%COREROOT%\classes +set CP=%CP%;%COREROOT%\lib\log4j\log4j-1.2.9.jar +set CP=%CP%;%COREROOT%\lib\xmlbeans\jsr173_api.jar +set CP=%CP%;%COREROOT%\lib\xmlbeans\resolver.jar +set CP=%CP%;%COREROOT%\lib\xmlbeans\xbean.jar +set CP=%CP%;%COREROOT%\lib\xmlbeans\xbean_xpath.jar +set CP=%CP%;%COREROOT%\lib\xmlbeans\xmlpublic.jar +set CP=%CP%;%COREROOT%\lib\xmlbeans\saxon8.jar +set CP=%CP%;%AMQROOT%\dist\amqp-common.jar +set CP=%CP%;%AMQROOT%\dist\amqp-jms.jar +set CP=%CP%;%AMQROOT%\lib\mina\mina-0.7.3.jar +set CP=%CP%;%AMQROOT%\lib\jms\jms.jar +set CP=%CP%;%AMQROOT%\lib\util-concurrent\backport-util-concurrent.jar +set CP=%CP%;%AMQROOT%\lib\jakarta-commons\commons-collections-3.1.jar + + +@rem %JAVA_HOME%\bin\java -Damqj.logging.level="ERROR" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -cp %CP% org.amqp.blaze.stac.Stac +%JAVA_HOME%\bin\java -Damqj.logging.level="ERROR" -cp %CP% org.amqp.blaze.stac.Stac \ No newline at end of file diff --git a/java/management/cli/build-module.xml b/java/management/cli/build-module.xml new file mode 100644 index 0000000000..2c52418e46 --- /dev/null +++ b/java/management/cli/build-module.xml @@ -0,0 +1,21 @@ + + + + + diff --git a/java/management/cli/build-old.xml b/java/management/cli/build-old.xml new file mode 100644 index 0000000000..8445e4484f --- /dev/null +++ b/java/management/cli/build-old.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/cli/lib/jython/jython.jar b/java/management/cli/lib/jython/jython.jar new file mode 100644 index 0000000000..517c60dd0e Binary files /dev/null and b/java/management/cli/lib/jython/jython.jar differ diff --git a/java/management/cli/src/org/apache/qpid/stac/Stac.java b/java/management/cli/src/org/apache/qpid/stac/Stac.java new file mode 100644 index 0000000000..98633286fb --- /dev/null +++ b/java/management/cli/src/org/apache/qpid/stac/Stac.java @@ -0,0 +1,94 @@ +/* + * + * 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.stac; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.InputStream; + +public class Stac +{ + public static void main(String[] args) + { + BufferedReader terminal = new BufferedReader(new InputStreamReader(System.in)); + System.out.println("\nInitializing the Scripting Tool for AMQ Console (STAC) ..."); + String var = System.getProperty("python.verbose"); + if (var != null) + { + System.setProperty("python.verbose", var); + } + else + { + System.setProperty("python.verbose", "warning"); + } + StacInterpreter interp = new StacInterpreter(); + InputStream is = Stac.class.getResourceAsStream("/python/stac.py"); + if (is == null) + { + System.err.println("Unable to load STAC Python library. Terminating."); + System.exit(1); + } + interp.execfile(is); + + boolean running = true; + + while (running) + { + interp.write(interp.get("commandPrompt").toString()); + + String line = null; + try + { + line = terminal.readLine(); + if (line != null) + { + if (line.equalsIgnoreCase("quit") || line.equalsIgnoreCase("exit")) + { + running = false; + line = "quit()"; + } + while (interp.runsource(line)) + { + interp.write("..."); + try + { + String s = terminal.readLine(); + line = line + "\n" + s; + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + else + { + System.out.println(); + running = false; + } + } + catch (IOException ie) + { + System.err.println("An error occurred: " + ie); + ie.printStackTrace(System.err); + } + } + System.exit(0); + } +} diff --git a/java/management/cli/src/org/apache/qpid/stac/StacInterpreter.java b/java/management/cli/src/org/apache/qpid/stac/StacInterpreter.java new file mode 100644 index 0000000000..14f9a34504 --- /dev/null +++ b/java/management/cli/src/org/apache/qpid/stac/StacInterpreter.java @@ -0,0 +1,31 @@ +/* + * + * 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.stac; + +import org.python.util.InteractiveInterpreter; +import org.python.core.PySystemState; + +public class StacInterpreter extends InteractiveInterpreter +{ + public StacInterpreter() + { + PySystemState.initialize(); + super.set("theInterpreter", this); + super.exec("import sys\n"); + } +} diff --git a/java/management/cli/src/org/apache/qpid/stac/commands/CdCommand.java b/java/management/cli/src/org/apache/qpid/stac/commands/CdCommand.java new file mode 100644 index 0000000000..b21bc450bd --- /dev/null +++ b/java/management/cli/src/org/apache/qpid/stac/commands/CdCommand.java @@ -0,0 +1,50 @@ +/* + * + * 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.stac.commands; + +import org.apache.qpid.stac.jmx.MBeanServerConnectionContext; +import org.apache.qpid.stac.jmx.CurrentMBean; +import org.apache.qpid.AMQException; + +public class CdCommand +{ + public static void execute(MBeanServerConnectionContext context, String destination) + throws AMQException + { + // check if it is an absolute path and if so change to the root first + if (destination.startsWith("/")) + { + context.changeBean("/"); + destination = destination.substring(1); + } + if (destination.length() == 0) + { + return; + } + String[] destinations = destination.split("/"); + for (String item : destinations) + { + if ("..".equals(item)) + { + item = CurrentMBean.PARENT_ATTRIBUTE; + } + context.changeBean(item); + } + } + +} diff --git a/java/management/cli/src/org/apache/qpid/stac/commands/InvokeCommand.java b/java/management/cli/src/org/apache/qpid/stac/commands/InvokeCommand.java new file mode 100644 index 0000000000..68b4a6f8aa --- /dev/null +++ b/java/management/cli/src/org/apache/qpid/stac/commands/InvokeCommand.java @@ -0,0 +1,31 @@ +/* + * + * 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.stac.commands; + +import org.apache.qpid.stac.jmx.MBeanServerConnectionContext; +import org.apache.qpid.AMQException; + +public class InvokeCommand +{ + public static void execute(MBeanServerConnectionContext context, String methodName, Object... args) + throws AMQException + { + // Not used currently + + } +} diff --git a/java/management/cli/src/org/apache/qpid/stac/commands/LsCommand.java b/java/management/cli/src/org/apache/qpid/stac/commands/LsCommand.java new file mode 100644 index 0000000000..4cfa96b030 --- /dev/null +++ b/java/management/cli/src/org/apache/qpid/stac/commands/LsCommand.java @@ -0,0 +1,123 @@ +/* + * + * 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.stac.commands; + +import org.apache.qpid.AMQException; +import org.apache.qpid.stac.jmx.CurrentMBean; +import org.apache.qpid.stac.jmx.MBeanServerConnectionContext; +import org.apache.qpid.stac.jmx.MBeanUtils; + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanParameterInfo; +import java.util.SortedSet; + +public class LsCommand +{ + public static void execute(MBeanServerConnectionContext context) + throws AMQException + { + CurrentMBean currentMBean = context.getCurrentMBean(); + + SortedSet directories = currentMBean.getOrderedObjects(); + System.out.println(); + for (MBeanAttributeInfo ai : directories) + { + if (!MBeanUtils.isHidden(ai)) + { + outputAccess(ai); + System.out.println(" " + ai.getName()); + } + } + System.out.println(); + + SortedSet attributes = currentMBean.getOrderedAttributes(); + for (MBeanAttributeInfo ai : attributes) + { + outputAccess(ai); + System.out.printf(" %1$-15s%2$-15s %3$s\n", ai.getName(), "[" + convertType(ai.getType()) + "]", + currentMBean.getAttributeValue(ai.getName(), ai.getType())); + } + System.out.println(); + SortedSet operations = currentMBean.getOrderedOperations(); + + for (MBeanOperationInfo oi : operations) + { + System.out.printf("-r-x %1$-15s", oi.getName()); + MBeanParameterInfo[] paramInfos = oi.getSignature(); + System.out.print("["); + if (paramInfos.length == 0) + { + System.out.print("No arguments"); + } + + for (int i = 0; i < paramInfos.length; i++) + { + MBeanParameterInfo pi = paramInfos[i]; + System.out.printf("%1$s:%2$s%3$s", pi.getName(), convertType(pi.getType()), + (i < paramInfos.length)?",":""); + } + System.out.println("]"); + } + System.out.println(); + } + + private static void outputAccess(MBeanAttributeInfo ai) + { + boolean isObject = ai.getType().equals("javax.management.ObjectName"); + System.out.print(isObject?"d":"-"); + System.out.print(ai.isReadable()?"r":"-"); + System.out.print(ai.isWritable()?"w":"-"); + System.out.print("-"); + } + + /** + * Converts the type name to a non-Java type (e.g. java.lang.String -> String) + * @param javaType + * @return a generic type + */ + private static String convertType(String javaType) + { + if ("java.lang.String".equals(javaType)) + { + return "String"; + } + else if ("java.lang.Integer".equals(javaType)) + { + return "Integer"; + } + else if ("java.lang.Boolean".equals(javaType)) + { + return "Boolean"; + } + else if ("java.lang.Double".equals(javaType)) + { + return "Double"; + } + else if ("java.util.Date".equals(javaType)) + { + return "Date"; + } + else + { + return javaType; + } + } + + +} diff --git a/java/management/cli/src/org/apache/qpid/stac/jmx/CurrentMBean.java b/java/management/cli/src/org/apache/qpid/stac/jmx/CurrentMBean.java new file mode 100644 index 0000000000..d378329220 --- /dev/null +++ b/java/management/cli/src/org/apache/qpid/stac/jmx/CurrentMBean.java @@ -0,0 +1,180 @@ +/* + * + * 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.stac.jmx; + +import org.apache.qpid.AMQException; + +import javax.management.*; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * Stores information about the "current" MBean. This data is used when navigating the hierarchy. + * + * For example, we need to map between a name and an object id, and this stores that link. + * + */ +public class CurrentMBean +{ + private MBeanServerConnection _mbeanServerConnection; + + public static final String PARENT_ATTRIBUTE = "__parent"; + + private static final SimpleDateFormat _dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + /** + * Maps names to ObjectNames. Used for efficiency to avoid iterating through all names when doing a CD command. + */ + private Map _name2ObjectNameMap = new HashMap(); + + private ObjectName _mbeanObjectName; + + private MBeanInfo _mbeanInfo; + + public CurrentMBean(MBeanServerConnection mbeanServerConnection) + { + _mbeanServerConnection = mbeanServerConnection; + } + + public void changeMBean(ObjectName objectName) throws AMQException + { + try + { + _mbeanInfo = _mbeanServerConnection.getMBeanInfo(objectName); + } + catch (Exception e) + { + throw new AMQException("Unable to look up MBean for object name " + objectName + ": " + e, e); + } + _mbeanObjectName = objectName; + } + + public ObjectName getMBeanObjectName() + { + return _mbeanObjectName; + } + + public MBeanInfo getMBeanInfo() + { + return _mbeanInfo; + } + + public Object getAttributeValue(String name, String type) throws AMQException + { + // TODO: The type argument is a temporary workaround for a bug (somewhere!) in which + // a date is returned as a String + try + { + Object o = _mbeanServerConnection.getAttribute(_mbeanObjectName, name); + if ("java.util.Date".equals(type)) + { + + return _dateFormat.format(new Date(Long.parseLong((String)o))); + } + else + { + return o; + } + } + catch (Exception e) + { + throw new AMQException("Unable to read attribute value for attribute name " + name, e); + } + } + + /** + * Get the objects (i.e. "directories") under the current mbean, ordered alphabetically. This method also + * refreshes the cache that maps from name to ObjectName (this saves iterating through the attributes again). + * @return a set containing the attribute infos, sorted by name + */ + public SortedSet getOrderedObjects() throws AMQException + { + TreeSet attributes = new TreeSet(new MBeanAttributeInfoComparator()); + _name2ObjectNameMap.clear(); + for (MBeanAttributeInfo ai : _mbeanInfo.getAttributes()) + { + String type = ai.getType(); + + if ("javax.management.ObjectName".equals(type)) + { + _name2ObjectNameMap.put(ai.getName(), (ObjectName)getAttributeValue(ai.getName(), type)); + attributes.add(ai); + } + } + return attributes; + } + + public void refreshNameToObjectNameMap() throws AMQException + { + _name2ObjectNameMap.clear(); + for (MBeanAttributeInfo ai : _mbeanInfo.getAttributes()) + { + final String type = ai.getType(); + + if ("javax.management.ObjectName".equals(type)) + { + _name2ObjectNameMap.put(ai.getName(), (ObjectName)getAttributeValue(ai.getName(), type)); + } + } + } + + /** + * Gets an object name, given the "display name" + * @param name the display name (usually returned to the user when he does an ls() + * @return the object name + */ + public ObjectName getObjectNameByName(String name) + { + return _name2ObjectNameMap.get(name); + } + + public SortedSet getOrderedAttributes() + { + TreeSet attributes = new TreeSet(new MBeanAttributeInfoComparator()); + for (MBeanAttributeInfo ai : _mbeanInfo.getAttributes()) + { + String type = ai.getType(); + if (!"javax.management.ObjectName".equals(type)) + { + attributes.add(ai); + } + } + return attributes; + } + + public SortedSet getOrderedOperations() + { + TreeSet operations = new TreeSet(new MBeanOperationInfoComparator()); + for (MBeanOperationInfo oi : _mbeanInfo.getOperations()) + { + operations.add(oi); + } + return operations; + } + + public void invoke(String methodName, Object... args) throws AMQException + { + try + { + _mbeanServerConnection.invoke(_mbeanObjectName, methodName, null, null); + } + catch (Exception e) + { + throw new AMQException("Error invoking method " + methodName + ": " + e, e); + } + } +} diff --git a/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanAttributeInfoComparator.java b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanAttributeInfoComparator.java new file mode 100644 index 0000000000..b5c2437d58 --- /dev/null +++ b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanAttributeInfoComparator.java @@ -0,0 +1,29 @@ +/* + * + * 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.stac.jmx; + +import javax.management.MBeanAttributeInfo; +import java.util.Comparator; + +public class MBeanAttributeInfoComparator implements Comparator +{ + public int compare(MBeanAttributeInfo o1, MBeanAttributeInfo o2) + { + return o1.getName().compareTo(o2.getName()); + } +} diff --git a/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanOperationInfoComparator.java b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanOperationInfoComparator.java new file mode 100644 index 0000000000..4c490d92d5 --- /dev/null +++ b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanOperationInfoComparator.java @@ -0,0 +1,29 @@ +/* + * + * 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.stac.jmx; + +import javax.management.MBeanOperationInfo; +import java.util.Comparator; + +public class MBeanOperationInfoComparator implements Comparator +{ + public int compare(MBeanOperationInfo o1, MBeanOperationInfo o2) + { + return o1.getName().compareTo(o2.getName()); + } +} diff --git a/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanServerConnectionContext.java b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanServerConnectionContext.java new file mode 100644 index 0000000000..18e5359b8c --- /dev/null +++ b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanServerConnectionContext.java @@ -0,0 +1,202 @@ +/* + * + * 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.stac.jmx; + +import org.apache.qpid.AMQException; +import org.apache.qpid.management.jmx.JmxConstants; +import org.apache.qpid.stac.commands.CdCommand; +import org.apache.qpid.stac.commands.LsCommand; +import org.apache.log4j.Logger; + +import javax.management.MBeanServerConnection; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.management.ObjectInstance; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; +import java.lang.management.ManagementFactory; +import java.util.Hashtable; +import java.util.Set; + +public class MBeanServerConnectionContext +{ + private static final Logger _log = Logger.getLogger(MBeanServerConnectionContext.class); + + /** + * The connection to the MBean server. Can be remote or local, depending on whether we are proxying. + */ + private MBeanServerConnection _connection; + + /** + * The connector used to make the connection to the remote MBean server + */ + private JMXConnector _connector; + + private CurrentMBean _currentMBean; + + /* + * Initialize connection to the Domain Runtime MBean Server + */ + public void connect(String host) throws AMQException + { + if (host == null) + { + _connection = (MBeanServerConnection) ManagementFactory.getPlatformMBeanServer(); + } + else + { + String serviceURLString = "service:jmx:local://localhost"; + + try + { + JMXServiceURL serviceURL = new JMXServiceURL(serviceURLString); + _connector = JMXConnectorFactory.connect(serviceURL, null); + _connection = _connector.getMBeanServerConnection(); + } + catch (Exception e) + { + throw new AMQException("Unable to connect to remote MBean server with service url " + serviceURLString + + ": " + e, e); + } + } + _currentMBean = new CurrentMBean(_connection); + changeBean(getRootObjectName()); + } + + /** + * Connect to the local MBean server + * @throws AMQException + */ + public void connect() throws AMQException + { + connect(null); + } + + public void disconnect() throws AMQException + { + if (_connection != null) + { + try + { + ObjectName queryName = new ObjectName(JmxConstants.JMX_DOMAIN + ":*"); + Set beans = _connection.queryMBeans(queryName, null); + for (ObjectInstance bean : beans) + { + _log.debug("Unregistering MBean: " + bean.getObjectName()); + _connection.unregisterMBean(bean.getObjectName()); + } + } + catch (Exception e) + { + throw new AMQException("Error unregistering MBeans: " + e, e); + } + } + } + + public ObjectName getRootObjectName() throws AMQException + { + Hashtable props = new Hashtable(); + props.put("objectid", "0"); + props.put("type", "broker"); + try + { + return new ObjectName(JmxConstants.JMX_DOMAIN, props); + } + catch (MalformedObjectNameException e) + { + throw new AMQException("Cannot construct root MBean object name: " + e, e); + } + } + + private void changeBean(ObjectName objectName) throws AMQException + { + _currentMBean.changeMBean(objectName); + } + + /** + * Change the current bean to the one underneath the current bean, represented by the display name + * @param name + * @throws AMQException + */ + public void changeBean(String name) throws AMQException + { + checkConnection(); + if (name.equals("/")) + { + changeBean(getRootObjectName()); + } + else + { + ObjectName objName = _currentMBean.getObjectNameByName(name); + if (CurrentMBean.PARENT_ATTRIBUTE.equals(name) && objName == null) + { + // we have tried to change up a level from the root, so just ignore + return; + } + if (objName == null) + { + // could be stale cache, so refresh + _currentMBean.refreshNameToObjectNameMap(); + objName = _currentMBean.getObjectNameByName(name); + } + if (objName == null) + { + throw new AMQException("Unknown managed object with name: " + name); + } + else + { + changeBean(objName); + } + } + } + + public void ls() throws AMQException + { + checkConnection(); + LsCommand.execute(this); + } + + public void cd(String destination) throws AMQException + { + CdCommand.execute(this, destination); + } + + public void invoke(String methodName, Object... args) throws AMQException + { + _currentMBean.invoke(methodName, args); + } + + public CurrentMBean getCurrentMBean() + { + return _currentMBean; + } + + public MBeanServerConnection getMBeanServerConnection() + { + return _connection; + } + + private void checkConnection() throws NotConnectedException + { + if (_connection == null) + { + throw new NotConnectedException(); + } + } +} diff --git a/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanUtils.java b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanUtils.java new file mode 100644 index 0000000000..57bba9d4d3 --- /dev/null +++ b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanUtils.java @@ -0,0 +1,35 @@ +/* + * + * 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.stac.jmx; + +import javax.management.MBeanAttributeInfo; + +/** + * Useful MBean methods. Also provides functionality for our CMLMBean + */ +public class MBeanUtils +{ + public static boolean isHidden(MBeanAttributeInfo ai) + { + /* This is JDK 1.6 only + String hidden = (String) ai.getDescriptor().getFieldValue("hidden"); + return hidden != null && "true".equals(hidden); + */ + return ai.getName().startsWith("__"); + } +} diff --git a/java/management/cli/src/org/apache/qpid/stac/jmx/NotConnectedException.java b/java/management/cli/src/org/apache/qpid/stac/jmx/NotConnectedException.java new file mode 100644 index 0000000000..2fcb6e5ddf --- /dev/null +++ b/java/management/cli/src/org/apache/qpid/stac/jmx/NotConnectedException.java @@ -0,0 +1,28 @@ +/* + * + * 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.stac.jmx; + +import org.apache.qpid.AMQException; + +public class NotConnectedException extends AMQException +{ + public NotConnectedException() + { + super("Not connected to JMX server"); + } +} diff --git a/java/management/cli/src/python/stac.py b/java/management/cli/src/python/stac.py new file mode 100644 index 0000000000..d521dc18c3 --- /dev/null +++ b/java/management/cli/src/python/stac.py @@ -0,0 +1,190 @@ +# +# 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. +# + +""" +Bridges between Python and Java, to provide a simpler and more Pythonesque environment. +Certified to be free of dead parrots. +""" +# Imports +from java.lang import * +import org.amqp.blaze.management.jmx.AMQConsole as AMQConsole +import org.amqp.blaze.stac.jmx.MBeanServerConnectionContext as MBeanServerConnectionContext + +# Globals +commandPrompt = "" +proxied = 0 +connected = 0 +amqConsole = None +connectionContext = None + +# Functions +def connect(url="", username="", password=""): + """ + Connects to an AMQP broker. The URL must be in the form amq://host:port/context + """ + try: + global connected + global connectionContext + if connected==1: + print "Already Connected!" + return + + try: + parsedURL = parseURL(url) + except URLFormatError, ufe: + print "Invalid URL: " + ufe.msg + return + + amqConsole = AMQConsole(parsedURL['host'], parsedURL['port'], username, password, parsedURL['context']) + + amqConsole.initialise() + amqConsole.registerAllMBeans() + connectionContext = MBeanServerConnectionContext() + connectionContext.connect() + connected = 1 + except Exception, e: + updateGlobals() + print e + e.printStackTrace() + cause = e.getCause() + if cause != None: + cause.printStackTrace() + else: + updateGlobals(); + +def disconnect(): + """ + Disconnects from the broker + """ + global connected + global connectionContext + + if connected==0: + print "Not connected!" + return + try: + connectionContext.disconnect() + connected = 0 + except Exception, e: + updateGlobals() + print e + else: + updateGlobals() + +def quit(): + global connected + if connected != 0: + disconnect() + +def ls(): + """ + Lists the current mbean + """ + global connected + if connected == 0: + print "Not connected!" + return + + connectionContext.ls() + +def cd(beanName): + """ + Changes the current mbean + """ + global connected + global connectionContext + if connected == 0: + print "Not connected!" + return + + try: + connectionContext.cd(beanName) + except Exception, e: + updateGlobals() + msg = "Error: " + e.getMessage() + print msg + else: + updateGlobals() + +def invoke(methodName): + """ + Invokes an operation of the current mbean + """ + global connected + global connectionContext + + if connected == 0: + print "Not connected!" + return + + try: + connectionContext.invoke(methodName, None) + except Exception, e: + updateGlobals() + msg = "Error: " + e.getMessage() + print msg + else: + updateGlobals() + +class URLFormatError(Exception): + """Exception raised for errors in format of the URL + + Attributes: + expression -- input expression in which the error occurred + message -- explanation of the error + """ + + def __init__(self, url, message): + self.url = url + self.msg = message + +def parseURL(url): + """ + Parses an AMQ URL into host, port and context components returning them in a dictionary + """ + idx = url.find("amq://") + errorMsg = "Invalid URL - must be format amq://hostname:port/vhost" + if idx != 0: + raise URLFormatError(url, errorMsg) + + hostEndIdx = url.find(":", 6) + if hostEndIdx == -1: + raise URLFormatError(url, errorMsg) + + hostname = url[6:hostEndIdx] + + portIdx = url.find("/", hostEndIdx + 1) + port = url[hostEndIdx + 1:portIdx] + vhost = url[portIdx + 1:] + if portIdx == -1: + raise URLFormatError(url, errorMsg) + + return {'host':hostname,'port':int(port),'context':vhost} + +def updateGlobals(): + global commandPrompt + global connectionContext + if connected == 1: + commandPrompt = "AMQ:connected#" + connectionContext.getCurrentMBean().getAttributeValue("name", "java.lang.String") + "> " + else: + commandPrompt = "AMQ:disconnected> " +# Classes + + +# Global execution + +# Update all the global variables - this is called to sync everything at the start +updateGlobals() diff --git a/java/management/cli/test/org/apache/qpid/stac/ConnectionTest.java b/java/management/cli/test/org/apache/qpid/stac/ConnectionTest.java new file mode 100644 index 0000000000..cf728cc6aa --- /dev/null +++ b/java/management/cli/test/org/apache/qpid/stac/ConnectionTest.java @@ -0,0 +1,35 @@ +/* + * + * 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.stac; + +import org.apache.qpid.management.jmx.AMQConsole; +import org.apache.qpid.stac.jmx.MBeanServerConnectionContext; + +public class ConnectionTest +{ + public static void main(String[] args) throws Exception + { + + AMQConsole console = new AMQConsole("localhost", 5672, "guest", "guest", "/test"); + console.initialise(); + console.registerAllMBeans(); + MBeanServerConnectionContext connectionContext = new MBeanServerConnectionContext(); + connectionContext.connect(); + connectionContext.ls(); + } +} diff --git a/java/management/core/build-module.xml b/java/management/core/build-module.xml new file mode 100644 index 0000000000..07e17a44d4 --- /dev/null +++ b/java/management/core/build-module.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/core/build-old.xml b/java/management/core/build-old.xml new file mode 100644 index 0000000000..df00b95bcc --- /dev/null +++ b/java/management/core/build-old.xml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This target can only run inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + This target can only run inside the NetBeans IDE. + + + + + diff --git a/java/management/core/etc/cml-exampleschema.xml b/java/management/core/etc/cml-exampleschema.xml new file mode 100644 index 0000000000..bcee38246f --- /dev/null +++ b/java/management/core/etc/cml-exampleschema.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/core/etc/cml.xsd b/java/management/core/etc/cml.xsd new file mode 100644 index 0000000000..99c21b41f9 --- /dev/null +++ b/java/management/core/etc/cml.xsd @@ -0,0 +1,175 @@ + + + + + + Defines a CML document as a schema or a... + + + + + + + + + + + + + + + + + + Client request for a schema + + + + + + + + + + + + + + + + + + Defines a class which is a managable object + + + + + + + + + + + + + + + + + + + + Defines a field within a class + + + + + + + + + + + + + + + + + + + + + + + + Defines a method within a class + + + + + + + + + + + + + + A request to get the property values of an instance + + + + + + A response containing the properties of an instance + + + + + + + + + + + + + + + + + + + + + A reference to an object instance + + + + + + + A request to invoke a method + + + + + + + A reply to a method invocation request + + + + + + + + + + + + + + diff --git a/java/management/core/lib/jakarta-commons/commons-attributes-api.jar b/java/management/core/lib/jakarta-commons/commons-attributes-api.jar new file mode 100644 index 0000000000..b41cd055bb Binary files /dev/null and b/java/management/core/lib/jakarta-commons/commons-attributes-api.jar differ diff --git a/java/management/core/lib/jakarta-commons/commons-attributes-compiler.jar b/java/management/core/lib/jakarta-commons/commons-attributes-compiler.jar new file mode 100644 index 0000000000..ffd93f79eb Binary files /dev/null and b/java/management/core/lib/jakarta-commons/commons-attributes-compiler.jar differ diff --git a/java/management/core/lib/jakarta-commons/commons-beanutils.jar b/java/management/core/lib/jakarta-commons/commons-beanutils.jar new file mode 100644 index 0000000000..b1b89c9c92 Binary files /dev/null and b/java/management/core/lib/jakarta-commons/commons-beanutils.jar differ diff --git a/java/management/core/lib/jakarta-commons/commons-codec.jar b/java/management/core/lib/jakarta-commons/commons-codec.jar new file mode 100644 index 0000000000..957b6752af Binary files /dev/null and b/java/management/core/lib/jakarta-commons/commons-codec.jar differ diff --git a/java/management/core/lib/jakarta-commons/commons-collections.jar b/java/management/core/lib/jakarta-commons/commons-collections.jar new file mode 100644 index 0000000000..41e230feea Binary files /dev/null and b/java/management/core/lib/jakarta-commons/commons-collections.jar differ diff --git a/java/management/core/lib/jakarta-commons/commons-dbcp.jar b/java/management/core/lib/jakarta-commons/commons-dbcp.jar new file mode 100644 index 0000000000..08440c02e5 Binary files /dev/null and b/java/management/core/lib/jakarta-commons/commons-dbcp.jar differ diff --git a/java/management/core/lib/jakarta-commons/commons-digester.jar b/java/management/core/lib/jakarta-commons/commons-digester.jar new file mode 100644 index 0000000000..9765493306 Binary files /dev/null and b/java/management/core/lib/jakarta-commons/commons-digester.jar differ diff --git a/java/management/core/lib/jakarta-commons/commons-discovery.jar b/java/management/core/lib/jakarta-commons/commons-discovery.jar new file mode 100644 index 0000000000..eff4db19ef Binary files /dev/null and b/java/management/core/lib/jakarta-commons/commons-discovery.jar differ diff --git a/java/management/core/lib/jakarta-commons/commons-fileupload.jar b/java/management/core/lib/jakarta-commons/commons-fileupload.jar new file mode 100644 index 0000000000..1ca4a9cd31 Binary files /dev/null and b/java/management/core/lib/jakarta-commons/commons-fileupload.jar differ diff --git a/java/management/core/lib/jakarta-commons/commons-httpclient.jar b/java/management/core/lib/jakarta-commons/commons-httpclient.jar new file mode 100644 index 0000000000..c17584060d Binary files /dev/null and b/java/management/core/lib/jakarta-commons/commons-httpclient.jar differ diff --git a/java/management/core/lib/jakarta-commons/commons-lang.jar b/java/management/core/lib/jakarta-commons/commons-lang.jar new file mode 100644 index 0000000000..87b80ab5db Binary files /dev/null and b/java/management/core/lib/jakarta-commons/commons-lang.jar differ diff --git a/java/management/core/lib/jakarta-commons/commons-logging.jar b/java/management/core/lib/jakarta-commons/commons-logging.jar new file mode 100644 index 0000000000..b73a80fab6 Binary files /dev/null and b/java/management/core/lib/jakarta-commons/commons-logging.jar differ diff --git a/java/management/core/lib/jakarta-commons/commons-pool.jar b/java/management/core/lib/jakarta-commons/commons-pool.jar new file mode 100644 index 0000000000..4ba534c90e Binary files /dev/null and b/java/management/core/lib/jakarta-commons/commons-pool.jar differ diff --git a/java/management/core/lib/jakarta-commons/commons-validator.jar b/java/management/core/lib/jakarta-commons/commons-validator.jar new file mode 100644 index 0000000000..bf76e86c29 Binary files /dev/null and b/java/management/core/lib/jakarta-commons/commons-validator.jar differ diff --git a/java/management/core/lib/log4j/log4j-1.2.9.jar b/java/management/core/lib/log4j/log4j-1.2.9.jar new file mode 100644 index 0000000000..a6568b01a2 Binary files /dev/null and b/java/management/core/lib/log4j/log4j-1.2.9.jar differ diff --git a/java/management/core/lib/spring/spring-beans.dtd b/java/management/core/lib/spring/spring-beans.dtd new file mode 100644 index 0000000000..050f845788 --- /dev/null +++ b/java/management/core/lib/spring/spring-beans.dtd @@ -0,0 +1,587 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/core/lib/spring/spring.ftl b/java/management/core/lib/spring/spring.ftl new file mode 100644 index 0000000000..45d8ad0b39 --- /dev/null +++ b/java/management/core/lib/spring/spring.ftl @@ -0,0 +1,316 @@ +<#-- + * spring.ftl + * + * This file consists of a collection of FreeMarker macros aimed at easing + * some of the common requirements of web applications - in particular + * handling of forms. + * + * Spring's FreeMarker support will automatically make this file and therefore + * all macros within it available to any application using Spring's + * FreeMarkerConfigurer. + * + * To take advantage of these macros, the "exposeSpringMacroHelpers" property + * of the FreeMarker class needs to be set to "true". This will expose a + * RequestContext under the name "springMacroRequestContext", as needed by + * the macros in this library. + * + * @author Darren Davison + * @author Juergen Hoeller + * @since 1.1 + --> + +<#-- + * message + * + * Macro to translate a message code into a message. + --> +<#macro message code>${springMacroRequestContext.getMessage(code)} + +<#-- + * messageText + * + * Macro to translate a message code into a message, + * using the given default text if no message found. + --> +<#macro messageText code, text>${springMacroRequestContext.getMessage(code, text)} + +<#-- + * url + * + * Takes a relative URL and makes it absolute from the server root by + * adding the context root for the web application. + --> +<#macro url relativeUrl>${springMacroRequestContext.getContextPath()}${relativeUrl} + +<#-- + * bind + * + * Exposes a BindStatus object for the given bind path, which can be + * a bean (e.g. "person") to get global errors, or a bean property + * (e.g. "person.name") to get field errors. Can be called multiple times + * within a form to bind to multiple command objects and/or field names. + * + * This macro will participate in the default HTML escape setting for the given + * RequestContext. This can be customized by calling "setDefaultHtmlEscape" + * on the "springMacroRequestContext" context variable, or via the + * "defaultHtmlEscape" context-param in web.xml (same as for the JSP bind tag). + * Also regards a "htmlEscape" variable in the namespace of this library. + * + * Producing no output, the following context variable will be available + * each time this macro is referenced (assuming you import this library in + * your templates with the namespace 'spring'): + * + * spring.status : a BindStatus instance holding the command object name, + * expression, value, and error messages and codes for the path supplied + * + * @param path : the path (string value) of the value required to bind to. + * Spring defaults to a command name of "command" but this can be overridden + * by user config. + --> +<#macro bind path> + <#if htmlEscape?exists> + <#assign status = springMacroRequestContext.getBindStatus(path, htmlEscape)> + <#else> + <#assign status = springMacroRequestContext.getBindStatus(path)> + + <#-- assign a temporary value, forcing a string representation for any + kind of variable. This temp value is only used in this macro lib --> + <#if status.value?exists && status.value?is_boolean> + <#assign stringStatusValue=status.value?string> + <#else> + <#assign stringStatusValue=status.value?default("")> + + + +<#-- + * bindEscaped + * + * Similar to spring:bind, but takes an explicit HTML escape flag rather + * than relying on the default HTML escape setting. + --> +<#macro bindEscaped path, htmlEscape> + <#assign status = springMacroRequestContext.getBindStatus(path, htmlEscape)> + <#-- assign a temporary value, forcing a string representation for any + kind of variable. This temp value is only used in this macro lib --> + <#if status.value?exists && status.value?is_boolean> + <#assign stringStatusValue=status.value?string> + <#else> + <#assign stringStatusValue=status.value?default("")> + + + +<#-- + * formInput + * + * Display a form input field of type 'text' and bind it to an attribute + * of a command or bean. + * + * @param path the name of the field to bind to + * @param attributes any additional attributes for the element (such as class + * or CSS styles or size + --> +<#macro formInput path attributes="" fieldType="text" > + <@bind path/> + ${stringStatusValue}" ${attributes} + <@closeTag/> + + +<#-- + * formPasswordInput + * + * Display a form input field of type 'password' and bind it to an attribute + * of a command or bean. No value will ever be displayed. This functionality + * can also be obtained by calling the formInput macro with a 'type' parameter + * of 'password' + * + * @param path the name of the field to bind to + * @param attributes any additional attributes for the element (such as class + * or CSS styles or size + --> +<#macro formPasswordInput path attributes="" > + <@formInput path, attributes, "password"/> + + +<#-- + * formHiddenInput + * + * Generate a form input field of type 'hidden' and bind it to an attribute + * of a command or bean. This functionality can also be obtained by calling + * the formInput macro with a 'type' parameter of 'hidden' + * + * @param path the name of the field to bind to + * @param attributes any additional attributes for the element (such as class + * or CSS styles or size + --> +<#macro formHiddenInput path attributes="" > + <@formInput path, attributes, "hidden"/> + + +<#-- + * formTextarea + * + * Display a text area and bind it to an attribute of a command or bean. + * + * @param path the name of the field to bind to + * @param attributes any additional attributes for the element (such as class + * or CSS styles or size + --> +<#macro formTextarea path attributes="" > + <@bind path/> + + + +<#-- + * formSingleSelect + * + * Show a selectbox (dropdown) input element allowing a single value to be chosen + * from a list of options. + * + * @param path the name of the field to bind to + * @param options a map (value=label) of all the available options + * @param attributes any additional attributes for the element (such as class + * or CSS styles or size +--> +<#macro formSingleSelect path options attributes=""> + <@bind path/> + + + +<#-- + * formMultiSelect + * + * Show a listbox of options allowing the user to make 0 or more choices from + * the list of options. + * + * @param path the name of the field to bind to + * @param options a map (value=label) of all the available options + * @param attributes any additional attributes for the element (such as class + * or CSS styles or size +--> +<#macro formMultiSelect path options attributes=""> + <@bind path/> + + + +<#-- + * formRadioButtons + * + * Show radio buttons. + * + * @param path the name of the field to bind to + * @param options a map (value=label) of all the available options + * @param separator the html tag or other character list that should be used to + * separate each option. Typically ' ' or '
' + * @param attributes any additional attributes for the element (such as class + * or CSS styles or size +--> +<#macro formRadioButtons path options separator attributes=""> + <@bind path/> + <#list options?keys as value> + checked="checked" ${attributes} + <@closeTag/> + ${options[value]}${separator} + + + +<#-- + * formCheckboxes + * + * Show checkboxes. + * + * @param path the name of the field to bind to + * @param options a map (value=label) of all the available options + * @param separator the html tag or other character list that should be used to + * separate each option. Typically ' ' or '
' + * @param attributes any additional attributes for the element (such as class + * or CSS styles or size +--> +<#macro formCheckboxes path options separator attributes=""> + <@bind path/> + <#list options?keys as value> + <#assign isSelected = contains(status.value?default([""]), value)> + checked="checked" ${attributes} + <@closeTag/> + ${options[value]}${separator} + + + +<#-- + * showErrors + * + * Show validation errors for the currently bound field, with + * optional style attributes. + * + * @param separator the html tag or other character list that should be used to + * separate each option. Typically '
'. + * @param classOrStyle either the name of a CSS class element (which is defined in + * the template or an external CSS file) or an inline style. If the value passed in here + * contains a colon (:) then a 'style=' attribute will be used, else a 'class=' attribute + * will be used. +--> +<#macro showErrors separator classOrStyle=""> + <#list status.errorMessages as error> + <#if classOrStyle == ""> + ${error} + <#else> + <#if classOrStyle?index_of(":") == -1><#assign attr="class"><#else><#assign attr="style"> + ${error} + + <#if error_has_next>${separator} + + + +<#-- + * checkSelected + * + * Check a value in a list to see if it is the currently selected value. + * If so, add the 'selected="selected"' text to the output. + * Handles values of numeric and string types. + * This function is used internally but can be accessed by user code if required. + * + * @param value the current value in a list iteration +--> +<#macro checkSelected value> + <#if stringStatusValue?is_number && stringStatusValue == value?number>selected="selected" + <#if stringStatusValue?is_string && stringStatusValue == value>selected="selected" + + +<#-- + * contains + * + * Macro to return true if the list contains the scalar, false if not. + * Surprisingly not a FreeMarker builtin. + * This function is used internally but can be accessed by user code if required. + * + * @param list the list to search for the item + * @param item the item to search for in the list + * @return true if item is found in the list, false otherwise +--> +<#function contains list item> + <#list list as nextInList> + <#if nextInList == item><#return true> + + <#return false> + + +<#-- + * closeTag + * + * Simple macro to close an HTML tag that has no body with '>' or '/>', + * depending on the value of a 'xhtmlCompliant' variable in the namespace + * of this library. +--> +<#macro closeTag> + <#if xhtmlCompliant?exists && xhtmlCompliant>/><#else>> + diff --git a/java/management/core/lib/spring/spring.tld b/java/management/core/lib/spring/spring.tld new file mode 100644 index 0000000000..1bc7091f03 --- /dev/null +++ b/java/management/core/lib/spring/spring.tld @@ -0,0 +1,311 @@ + + + + + + 1.1.1 + + 1.2 + + Spring + + http://www.springframework.org/tags + + Spring Framework JSP Tag Library. Authors: Rod Johnson, Juergen Hoeller + + + + + htmlEscape + org.springframework.web.servlet.tags.HtmlEscapeTag + JSP + + + Sets default HTML escape value for the current page. + Overrides a "defaultHtmlEscape" context-param in web.xml, if any. + + + + defaultHtmlEscape + true + true + + + + + + + + escapeBody + org.springframework.web.servlet.tags.EscapeBodyTag + JSP + + + Escapes its enclosed body content, applying HTML escaping and/or JavaScript escaping. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + htmlEscape + false + true + + + + javaScriptEscape + false + true + + + + + + + + message + org.springframework.web.servlet.tags.MessageTag + JSP + + + Retrieves the message with the given code, or text if code isn't resolvable. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + code + false + true + + + + arguments + false + true + + + + text + false + true + + + + var + false + true + + + + scope + false + true + + + + htmlEscape + false + true + + + + javaScriptEscape + false + true + + + + + + + + theme + org.springframework.web.servlet.tags.ThemeTag + JSP + + + Retrieves the theme message with the given code, or text if code isn't resolvable. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + code + false + true + + + + arguments + false + true + + + + text + false + true + + + + var + false + true + + + + scope + false + true + + + + htmlEscape + false + true + + + + javaScriptEscape + false + true + + + + + + + + hasBindErrors + org.springframework.web.servlet.tags.BindErrorsTag + JSP + + + Provides Errors instance in case of bind errors. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + errors + org.springframework.validation.Errors + + + + name + true + true + + + + htmlEscape + false + true + + + + + + + + nestedPath + org.springframework.web.servlet.tags.NestedPathTag + JSP + + + Sets a nested path to be used by the bind tag's path. + + + + nestedPath + java.lang.String + + + + path + true + true + + + + + + + + bind + org.springframework.web.servlet.tags.BindTag + JSP + + + Provides BindStatus object for the given bind path. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + status + org.springframework.web.servlet.support.BindStatus + + + + path + true + true + + + + ignoreNestedPath + false + true + + + + htmlEscape + false + true + + + + + + + + transform + org.springframework.web.servlet.tags.TransformTag + JSP + + + Provides transformation of variables to Strings, using an appropriate + custom PropertyEditor from BindTag (can only be used inside BindTag). + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + value + true + true + + + + var + false + true + + + + scope + false + true + + + + htmlEscape + false + true + + + + + diff --git a/java/management/core/lib/spring/spring.vm b/java/management/core/lib/spring/spring.vm new file mode 100644 index 0000000000..50e104328c --- /dev/null +++ b/java/management/core/lib/spring/spring.vm @@ -0,0 +1,294 @@ +#** + * spring.vm + * + * This file consists of a collection of Velocity macros aimed at easing + * some of the common requirements of web applications - in particular + * handling of forms. + * + * Spring's Velocity support will automatically make this file and therefore + * all macros within it available to any application using Spring's + * VelocityConfigurer. + * + * To take advantage of these macros, the "exposeSpringMacroHelpers" property + * of the VelocityView class needs to be set to "true". This will expose a + * RequestContext under the name "springMacroRequestContext", as needed by + * the macros in this library. + * + * @author Darren Davison + * @author Juergen Hoeller + * @since 1.1 + *# + +#** + * springMessage + * + * Macro to translate a message code into a message. + *# +#macro( springMessage $code )$springMacroRequestContext.getMessage($code)#end + +#** + * springMessageText + * + * Macro to translate a message code into a message, + * using the given default text if no message found. + *# +#macro( springMessageText $code $text )$springMacroRequestContext.getMessage($code, $text)#end + +#** + * springUrl + * + * Takes a relative URL and makes it absolute from the server root by + * adding the context root for the web application. + *# +#macro( springUrl $relativeUrl )$springMacroRequestContext.getContextPath()${relativeUrl}#end + +#** + * springBind + * + * Exposes a BindStatus object for the given bind path, which can be + * a bean (e.g. "person") to get global errors, or a bean property + * (e.g. "person.name") to get field errors. Can be called multiple times + * within a form to bind to multiple command objects and/or field names. + * + * This macro will participate in the default HTML escape setting for the given + * RequestContext. This can be customized by calling "setDefaultHtmlEscape" + * on the "springMacroRequestContext" context variable, or via the + * "defaultHtmlEscape" context-param in web.xml (same as for the JSP bind tag). + * Also regards a "springHtmlEscape" variable in the template context. + * + * Producing no output, the following context variable will be available + * each time this macro is referenced: + * + * $status : a BindStatus instance holding the command object name, + * expression, value, and error codes and messages for the path supplied + * + * @param $path : the path (string value) of the value required to bind to. + * Spring defaults to a command name of "command" but this can be overridden + * by user config. + *# +#macro( springBind $path ) + #if("$!springHtmlEscape" != "") + #set( $status = $springMacroRequestContext.getBindStatus($path, $springHtmlEscape) ) + #else + #set( $status = $springMacroRequestContext.getBindStatus($path) ) + #end +#end + +#** + * springBindEscaped + * + * Similar to springBind, but takes an explicit HTML escape flag rather + * than relying on the default HTML escape setting. + *# +#macro( springBindEscaped $path $htmlEscape ) + #set( $status = $springMacroRequestContext.getBindStatus($path, $htmlEscape) ) +#end + +#** + * springFormInput + * + * Display a form input field of type 'text' and bind it to an attribute + * of a command or bean. + * + * @param path the name of the field to bind to + * @param attributes any additional attributes for the element (such as class + * or CSS styles or size + * + *# +#macro( springFormInput $path $attributes ) + #springBind($path) + $!status.value +#end + +#** + * springFormSingleSelect + * + * Show a selectbox (dropdown) input element allowing a single value to be chosen + * from a list of options. + * + * The null check for $status.value leverages Velocity's 'quiet' notation rather + * than the more common #if($status.value) since this method evaluates to the + * boolean 'false' if the content of $status.value is the String "false" - not + * what we want. + * + * @param path the name of the field to bind to + * @param options a map (value=label) of all the available options + * @param attributes any additional attributes for the element (such as class + * or CSS styles or size +*# +#macro( springFormSingleSelect $path $options $attributes ) + #springBind($path) + +#end + +#** + * springFormMultiSelect + * + * Show a listbox of options allowing the user to make 0 or more choices from + * the list of options. + * + * @param path the name of the field to bind to + * @param options a map (value=label) of all the available options + * @param attributes any additional attributes for the element (such as class + * or CSS styles or size +*# +#macro( springFormMultiSelect $path $options $attributes ) + #springBind($path) + +#end + +#** + * springFormRadioButtons + * + * Show radio buttons. + * + * @param path the name of the field to bind to + * @param options a map (value=label) of all the available options + * @param separator the html tag or other character list that should be used to + * separate each option. Typically ' ' or '
' + * @param attributes any additional attributes for the element (such as class + * or CSS styles or size +*# +#macro( springFormRadioButtons $path $options $separator $attributes ) + #springBind($path) + #foreach($option in $options.keySet()) + ' + * @param attributes any additional attributes for the element (such as class + * or CSS styles or size +*# +#macro( springFormCheckboxes $path $options $separator $attributes ) + #springBind($path) + #foreach($option in $options.keySet()) + '. + * @param classOrStyle either the name of a CSS class element (which is defined in + * the template or an external CSS file) or an inline style. If the value passed in here + * contains a colon (:) then a 'style=' attribute will be used, else a 'class=' attribute + * will be used. +*# +#macro( springShowErrors $separator $classOrStyle ) + #foreach($error in $status.errorMessages) + #if($classOrStyle == "") + ${error} + #else + #if($classOrStyle.indexOf(":") == -1) + #set($attr="class") + #else + #set($attr="style") + #end + ${error} + #end + ${separator} + #end +#end + +#** + * springCloseTag + * + * Simple macro to close an HTML tag that has no body with '>' or '/>', + * depending on the value of a 'springXhtmlCompliant' variable in the + * template context. + *# +#macro( springCloseTag )#if($springXhtmlCompliant)/>#else>#end #end diff --git a/java/management/core/lib/xmlbeans/jsr173_api.jar b/java/management/core/lib/xmlbeans/jsr173_api.jar new file mode 100644 index 0000000000..d6fdfad49b Binary files /dev/null and b/java/management/core/lib/xmlbeans/jsr173_api.jar differ diff --git a/java/management/core/lib/xmlbeans/resolver.jar b/java/management/core/lib/xmlbeans/resolver.jar new file mode 100644 index 0000000000..073d789675 Binary files /dev/null and b/java/management/core/lib/xmlbeans/resolver.jar differ diff --git a/java/management/core/lib/xmlbeans/saxon8.jar b/java/management/core/lib/xmlbeans/saxon8.jar new file mode 100644 index 0000000000..f3a2484882 Binary files /dev/null and b/java/management/core/lib/xmlbeans/saxon8.jar differ diff --git a/java/management/core/lib/xmlbeans/xbean.jar b/java/management/core/lib/xmlbeans/xbean.jar new file mode 100644 index 0000000000..08c72cd5b7 Binary files /dev/null and b/java/management/core/lib/xmlbeans/xbean.jar differ diff --git a/java/management/core/lib/xmlbeans/xbean_xpath.jar b/java/management/core/lib/xmlbeans/xbean_xpath.jar new file mode 100644 index 0000000000..c3366ebc8b Binary files /dev/null and b/java/management/core/lib/xmlbeans/xbean_xpath.jar differ diff --git a/java/management/core/lib/xmlbeans/xmlpublic.jar b/java/management/core/lib/xmlbeans/xmlpublic.jar new file mode 100644 index 0000000000..8c79b44c47 Binary files /dev/null and b/java/management/core/lib/xmlbeans/xmlpublic.jar differ diff --git a/java/management/core/src/log4j.properties b/java/management/core/src/log4j.properties new file mode 100644 index 0000000000..367153b2d9 --- /dev/null +++ b/java/management/core/src/log4j.properties @@ -0,0 +1,6 @@ +log4j.rootCategory=${amqj.logging.level}, console + +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.Threshold=DEBUG +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%t %d %p [%c{4}] %m%n diff --git a/java/management/core/src/org/apache/qpid/management/ManagementConnection.java b/java/management/core/src/org/apache/qpid/management/ManagementConnection.java new file mode 100644 index 0000000000..1dbfe6826c --- /dev/null +++ b/java/management/core/src/org/apache/qpid/management/ManagementConnection.java @@ -0,0 +1,120 @@ +/* + * + * 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.management; + +import org.apache.qpid.AMQException; +import org.apache.qpid.url.URLSyntaxException; +import org.apache.qpid.management.messaging.ManagementDestination; +import org.apache.qpid.jms.Session; +import org.apache.qpid.jms.MessageProducer; +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.AMQQueue; +import org.apache.log4j.Logger; + +import javax.jms.*; + +public class ManagementConnection +{ + private static final Logger _log = Logger.getLogger(ManagementConnection.class); + + private String _brokerHost; + + private int _brokerPort; + + private String _username; + + private String _password; + + private String _virtualPath; + + private AMQConnection _connection; + + private Session _session; + + private MessageConsumer _consumer; + + private MessageProducer _producer; + + private AMQQueue _replyQueue; + + public ManagementConnection(String brokerHost, int brokerPort, String username, + String password, String virtualPath) + { + _brokerHost = brokerHost; + _brokerPort = brokerPort; + _username = username; + _password = password; + _virtualPath = virtualPath; + } + + public void connect() throws AMQException, JMSException, URLSyntaxException + { + _connection = new AMQConnection(_brokerHost, _brokerPort, _username, _password, + "clientName" + System.currentTimeMillis(), _virtualPath); + _connection.setExceptionListener(new ExceptionListener() + { + public void onException(JMSException jmsException) + { + _log.error("Error occurred: " + jmsException, jmsException); + try + { + _connection.close(); + } + catch (JMSException e) + { + _log.error("Error closing connection: " + e, e); + } + } + }); + _session = (Session)_connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); + _replyQueue = new AMQQueue("response", true) + { + public String getEncodedName() + { + return getQueueName(); + } + }; + _consumer = _session.createConsumer(_replyQueue, 100, true, true, null); + + _producer = (MessageProducer) _session.createProducer(new ManagementDestination()); + _connection.start(); + } + + /** + * Send a request and wait for a response. + * @param xmlRequest the request to send + * @return the response received from the broker + * @throws AMQException when an AMQ error occurs + * @throws JMSException when a JMS error occurs + */ + public TextMessage sendRequest(String xmlRequest) throws AMQException, JMSException + { + TextMessage requestMsg = _session.createTextMessage(xmlRequest); + requestMsg.setJMSReplyTo(_replyQueue); + _producer.send(requestMsg); + return (TextMessage) _consumer.receive(); + } + + public void close() throws AMQException, JMSException + { + if (_connection != null) + { + _connection.close(); + } + } +} diff --git a/java/management/core/src/org/apache/qpid/management/jmx/AMQConsole.java b/java/management/core/src/org/apache/qpid/management/jmx/AMQConsole.java new file mode 100644 index 0000000000..c312ef63bf --- /dev/null +++ b/java/management/core/src/org/apache/qpid/management/jmx/AMQConsole.java @@ -0,0 +1,95 @@ +/* + * + * 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.management.jmx; + +import org.apache.log4j.Logger; +import org.apache.xmlbeans.XmlException; +import org.apache.qpid.AMQException; +import org.apache.qpid.url.URLSyntaxException; +import org.apache.qpid.management.ManagementConnection; +import org.apache.qpid.management.messaging.CMLMessageFactory; +import org.apache.qpid.schema.cml.CmlDocument; + +import javax.jms.JMSException; +import javax.jms.TextMessage; +import javax.management.MBeanServer; +import java.lang.management.ManagementFactory; + +/** + * Main entry point for AMQ console implementation. + * + */ +public class AMQConsole +{ + private static final Logger _log = Logger.getLogger(AMQConsole.class); + + private ManagementConnection _connection; + + private MBeanInfoRegistry _mbeanInfoRegistry; + + private MBeanRegistrar _mbeanRegistrar; + + private MBeanServer _mbeanServer; + + public AMQConsole(String host, int port, String username, String password, + String context) + { + _connection = new ManagementConnection(host, port, username, password, context); + } + + public void initialise() throws AMQException, JMSException, XmlException, URLSyntaxException + { + _connection.connect(); + createMBeanInfo(); + _mbeanServer = ManagementFactory.getPlatformMBeanServer(); + _mbeanRegistrar = new MBeanRegistrar(_mbeanServer, _connection, _mbeanInfoRegistry); + } + + public void registerAllMBeans() throws JMSException, AMQException + { + _mbeanRegistrar.registerAllMBeans(); + } + + private void createMBeanInfo() throws JMSException, AMQException, XmlException + { + TextMessage tm = _connection.sendRequest(CMLMessageFactory.createSchemaRequest()); + if (_log.isDebugEnabled()) + { + _log.debug("Response document: \n" + tm.getText()); + } + CmlDocument cmlDoc = CmlDocument.Factory.parse(tm.getText()); + _mbeanInfoRegistry = new MBeanInfoRegistry(cmlDoc); + } + + public static void main(String[] args) + { + AMQConsole console = new AMQConsole(args[0], Integer.parseInt(args[1]), args[2], args[3], + args[4]); + try + { + console.initialise(); + _log.info("Registering all MBeans..."); + console.registerAllMBeans(); + _log.info("MBean registration completed successfully"); + } + catch (Exception e) + { + _log.error("Console initialisation error: " + e, e); + } + } +} diff --git a/java/management/core/src/org/apache/qpid/management/jmx/AMQMBeanInfo.java b/java/management/core/src/org/apache/qpid/management/jmx/AMQMBeanInfo.java new file mode 100644 index 0000000000..9663a7f783 --- /dev/null +++ b/java/management/core/src/org/apache/qpid/management/jmx/AMQMBeanInfo.java @@ -0,0 +1,40 @@ +/* + * + * 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.management.jmx; + +import javax.management.openmbean.OpenMBeanAttributeInfo; +import java.util.Map; +import java.util.HashMap; + +public class AMQMBeanInfo +{ + private Map _name2AttributeInfoMap = new HashMap(); + + public AMQMBeanInfo(OpenMBeanAttributeInfo[] attributeInfos) + { + for (OpenMBeanAttributeInfo attributeInfo: attributeInfos) + { + _name2AttributeInfoMap.put(attributeInfo.getName(), attributeInfo); + } + } + + public OpenMBeanAttributeInfo getAttributeInfo(String name) + { + return _name2AttributeInfoMap.get(name); + } +} diff --git a/java/management/core/src/org/apache/qpid/management/jmx/CMLMBean.java b/java/management/core/src/org/apache/qpid/management/jmx/CMLMBean.java new file mode 100644 index 0000000000..2d1dafb9f0 --- /dev/null +++ b/java/management/core/src/org/apache/qpid/management/jmx/CMLMBean.java @@ -0,0 +1,298 @@ +/* + * + * 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.management.jmx; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.management.ManagementConnection; +import org.apache.qpid.management.messaging.CMLMessageFactory; +import org.apache.qpid.schema.cml.CmlDocument; +import org.apache.qpid.schema.cml.FieldType; +import org.apache.qpid.schema.cml.InspectReplyType; +import org.apache.qpid.schema.cml.MethodReplyType; + +import javax.jms.JMSException; +import javax.jms.TextMessage; +import javax.management.*; +import javax.management.openmbean.OpenMBeanAttributeInfo; +import javax.management.openmbean.OpenMBeanInfoSupport; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import java.util.Hashtable; + +public class CMLMBean implements DynamicMBean +{ + private static final Logger _log = Logger.getLogger(CMLMBean.class); + + /** + * The number of milliseconds after which data values are considered "stale" and will be + * refreshed by querying the broker. This is a way of ensure that reading attributes + * repeatedly does not hit the broker heavily. + */ + private static final long REFRESH_IN_MILLIS = 2000; + + /** + * Name of the attribute for the parent MBean + */ + public static final String PARENT_ATTRIBUTE = "__parent"; + + private OpenMBeanInfoSupport _mbeanInfo; + + private AMQMBeanInfo _extraMbeanInfo; + + /** + * The cached inspect reply. This is used to read attribute values and is refreshed automatically + * if a request for an attribute is made after the time interval specified in REFRESH_IN_MILLIS + */ + private InspectReplyType _inspectReply; + + private CMLMBean _parent; + + private ObjectName _objectName; + + private ManagementConnection _connection; + + private int _objectId; + + private long _lastRefreshTime = System.currentTimeMillis(); + + public CMLMBean(CMLMBean parent, OpenMBeanInfoSupport mbeanInfo, AMQMBeanInfo extraMbeanInfo, + InspectReplyType inspectReply, ManagementConnection connection, int objectId) + { + _mbeanInfo = mbeanInfo; + _extraMbeanInfo = extraMbeanInfo; + _inspectReply = inspectReply; + _parent = parent; + _connection = connection; + _objectId = objectId; + } + + /** + * Utility method that populates all the type infos up to the root. Used when + * constructing the ObjectName. + * We end up with properties of the form "className", "objectId" in the map. + * @param leaf the child node. Must not be null. Note that the child types are not populated since the + * convention is different for the child where instead of "className" the word "type" is + * used. See the JMX Best Practices document on the Sun JMX website for details. + * @param properties + */ + public static void populateAllTypeInfo(Hashtable properties, CMLMBean leaf) + { + CMLMBean current = leaf.getParent(); + while (current != null) + { + properties.put(current.getType(), Integer.toString(current.getObjectId())); + current = current.getParent(); + } + } + + public String getType() + { + return _inspectReply.getClass1(); + } + + public int getObjectId() + { + return _inspectReply.getObject2(); + } + + public InspectReplyType getInspectReply() + { + return _inspectReply; + } + + public CMLMBean getParent() + { + return _parent; + } + + public ObjectName getObjectName() + { + return _objectName; + } + + public void setObjectName(ObjectName objectName) + { + _objectName = objectName; + } + + public Object getAttribute(String attribute) + throws AttributeNotFoundException, MBeanException, ReflectionException + { + if (PARENT_ATTRIBUTE.equals(attribute)) + { + if (_parent == null) + { + return null; + } + else + { + return _parent.getObjectName(); + } + } + if (needRefresh()) + { + refreshValues(); + } + String nsDecl = "declare namespace cml='http://www.amqp.org/schema/cml';"; + FieldType[] fields = (FieldType[]) _inspectReply.selectPath(nsDecl + "$this/cml:field[@name='" + + attribute + "']"); + if (fields == null || fields.length == 0) + { + throw new AttributeNotFoundException("Attribute " + attribute + " not found"); + } + else + { + OpenMBeanAttributeInfo attrInfo = _extraMbeanInfo.getAttributeInfo(attribute); + OpenType openType = attrInfo.getOpenType(); + String value = fields[0].getStringValue(); + try + { + return createAttributeValue(openType, value, attrInfo.getName()); + } + catch (MalformedObjectNameException e) + { + throw new MBeanException(e); + } + } + } + + private boolean needRefresh() + { + return ((System.currentTimeMillis() - _lastRefreshTime) > REFRESH_IN_MILLIS); + } + + private void refreshValues() throws MBeanException + { + _log.debug("Refreshing values..."); + try + { + TextMessage response = _connection.sendRequest(CMLMessageFactory.createInspectRequest(_objectId)); + + CmlDocument cmlDoc = CmlDocument.Factory.parse(response.getText()); + _inspectReply = cmlDoc.getCml().getInspectReply(); + _lastRefreshTime = System.currentTimeMillis(); + } + catch (Exception e) + { + throw new MBeanException(e); + } + } + + private Object createAttributeValue(OpenType openType, String value, String mbeanType) + throws MalformedObjectNameException + { + if (openType.equals(SimpleType.STRING)) + { + return value; + } + else if (openType.equals(SimpleType.BOOLEAN)) + { + return Boolean.valueOf(value); + } + else if (openType.equals(SimpleType.INTEGER)) + { + return Integer.valueOf(value); + } + else if (openType.equals(SimpleType.DOUBLE)) + { + return Double.valueOf(value); + } + else if (openType.equals(SimpleType.OBJECTNAME)) + { + Hashtable props = new Hashtable(); + props.put("objectid", value); + props.put("type", mbeanType); + // this populates all type info for parents + populateAllTypeInfo(props, this); + // add in type info for this level. This information is available from the inspect reply xml fragment + props.put(_inspectReply.getClass1(), Integer.toString(_inspectReply.getObject2())); + return new ObjectName(JmxConstants.JMX_DOMAIN, props); + } + else + { + _log.warn("Unsupported open type: " + openType + " - returning string value"); + return value; + } + } + + public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, + MBeanException, ReflectionException + { + + } + + public AttributeList getAttributes(String[] attributes) + { + AttributeList al = new AttributeList(attributes.length); + for (String name : attributes) + { + try + { + Object value = getAttribute(name); + final Attribute attr = new Attribute(name, value); + al.add(attr); + } + catch (Exception e) + { + _log.error("Unable to get value for attribute: " + name, e); + } + } + return al; + } + + public AttributeList setAttributes(AttributeList attributes) + { + return null; + } + + public Object invoke(String actionName, Object params[], String signature[]) throws MBeanException, + ReflectionException + { + _log.debug("Invoke called on action " + actionName); + try + { + TextMessage response = _connection.sendRequest(CMLMessageFactory.createMethodRequest(_objectId, actionName)); + CmlDocument cmlDoc = CmlDocument.Factory.parse(response.getText()); + CmlDocument.Cml cml = cmlDoc.getCml(); + MethodReplyType methodReply = cml.getMethodReply(); + if (methodReply.getStatus() != MethodReplyType.Status.OK) + { + throw new MBeanException(new Exception("Response code from method: " + methodReply.getStatus())); + } + return null; + } + catch (AMQException e) + { + throw new MBeanException(e); + } + catch (JMSException e) + { + throw new MBeanException(e); + } + catch (org.apache.xmlbeans.XmlException e) + { + throw new MBeanException(e); + } + } + + public MBeanInfo getMBeanInfo() + { + return _mbeanInfo; + } +} diff --git a/java/management/core/src/org/apache/qpid/management/jmx/JmxConstants.java b/java/management/core/src/org/apache/qpid/management/jmx/JmxConstants.java new file mode 100644 index 0000000000..a1944bfeb1 --- /dev/null +++ b/java/management/core/src/org/apache/qpid/management/jmx/JmxConstants.java @@ -0,0 +1,23 @@ +/* + * + * 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.management.jmx; + +public interface JmxConstants +{ + String JMX_DOMAIN = "org.apache.qpid"; +} diff --git a/java/management/core/src/org/apache/qpid/management/jmx/MBeanInfoRegistry.java b/java/management/core/src/org/apache/qpid/management/jmx/MBeanInfoRegistry.java new file mode 100644 index 0000000000..f6abb5028b --- /dev/null +++ b/java/management/core/src/org/apache/qpid/management/jmx/MBeanInfoRegistry.java @@ -0,0 +1,201 @@ +/* + * + * 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.management.jmx; + +import org.apache.qpid.AMQException; +import org.apache.qpid.schema.cml.CmlDocument; +import org.apache.qpid.schema.cml.FieldType; +import org.apache.qpid.schema.cml.MethodType; +import org.apache.qpid.schema.cml.SchemaReplyType; + +import javax.management.modelmbean.DescriptorSupport; +import javax.management.openmbean.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Stores all OpenMBeanInfo instances. + *

+ * Builds MBeanInfo instances from the CML schema (which is parsed by XMLBeans) and + * stores these indexed by CML class name. + *

+ * When constructing a DynamicMBean this registry is consulted for the MBeanInfo. + * + */ +public class MBeanInfoRegistry +{ + private Map _cmlClass2OpenMBeanInfoMap = new HashMap(); + + private Map _cmlClass2AMQMBeanInfoMap = new HashMap(); + + public MBeanInfoRegistry(CmlDocument cmlDocument) throws AMQException + { + initialise(cmlDocument); + } + + private void initialise(CmlDocument cmlDocument) throws AMQException + { + CmlDocument.Cml cml = cmlDocument.getCml(); + SchemaReplyType schema = cml.getSchemaReply(); + for (org.apache.qpid.schema.cml.ClassType c : schema.getClass1List()) + { + OpenMBeanAttributeInfo[] attributes = createAttributeInfos(c.getFieldList()); + OpenMBeanOperationInfo[] operations = createOperationInfos(c.getMethodList()); + String className = c.getName(); + OpenMBeanInfoSupport support = new OpenMBeanInfoSupport(className, null, attributes, + null, operations, null); + // we need to store the extra information separately since we cannot subclass + // OpenMBeanInfoSupport. Doing so means we need to have an AMQMBeanInfo class on each client + // which defeats the point of OpenMBeans. The extra info is only used by the CMLBean implementation + // to assist with runtime value lookups. + AMQMBeanInfo extra = new AMQMBeanInfo(attributes); + _cmlClass2OpenMBeanInfoMap.put(className, support); + _cmlClass2AMQMBeanInfoMap.put(className, extra); + } + } + + public OpenMBeanInfoSupport getOpenMBeanInfo(String cmlType) + { + return _cmlClass2OpenMBeanInfoMap.get(cmlType); + } + + public AMQMBeanInfo getAMQMBeanInfo(String cmlType) + { + return _cmlClass2AMQMBeanInfoMap.get(cmlType); + } + + private OpenMBeanAttributeInfo[] createAttributeInfos(List fields) + throws AMQException + { + OpenMBeanAttributeInfo[] attributes = new OpenMBeanAttributeInfo[fields.size() + 1]; + + // we up the parent attribute which is always present + try + { + DescriptorSupport descriptor = new DescriptorSupport(new String[]{"hidden=true"}); + attributes[attributes.length - 1] = new OpenMBeanAttributeInfoSupport(CMLMBean.PARENT_ATTRIBUTE, + "Parent", SimpleType.OBJECTNAME, + true, false, false); + //descriptor); JDK 1.6 only + } + catch (Exception e) + { + // should never happen + throw new AMQException("Unable to create Parent attribute", e); + } + // add all the type-specific attributes + for (int i = 0; i < attributes.length - 1; i++) + { + FieldType field = fields.get(i); + OpenType openType = getOpenType(field.getType(), field.getModify()); + String description = field.getLabel(); + attributes[i] = new OpenMBeanAttributeInfoSupport(field.getName(), + description != null ? description:"No description", + openType, + true, + field.getModify(), + openType == SimpleType.BOOLEAN); + } + + return attributes; + } + + private static OpenType getOpenType(FieldType.Type.Enum type, boolean isArray) + throws UnsupportedCMLTypeException, AMQException + { + SimpleType simpleType; + boolean primitive; + switch (type.intValue()) + { + // the constants are not public (bug in xmlbeans) so we cannot use + // the constants that are defined + // TODO: raise defect with xmlbeans projects + case 1: + simpleType = SimpleType.BOOLEAN; + primitive = true; + break; + case 2: + simpleType = SimpleType.STRING; + primitive = false; + break; + case 3: + simpleType = SimpleType.INTEGER; + primitive = true; + break; + case 4: + simpleType = SimpleType.OBJECTNAME; + primitive = false; + break; + case 5: + simpleType = SimpleType.DATE; + primitive = false; + break; + default: + throw new UnsupportedCMLTypeException(type.toString()); + } + if (isArray) + { + try + { + //return new ArrayType(simpleType, primitive); + return new ArrayType(1, simpleType); + } + catch (OpenDataException e) + { + throw new AMQException("Error constructing array type: " + e, e); + } + } + else + { + return simpleType; + } + } + + private OpenMBeanOperationInfo[] createOperationInfos(List methods) + throws AMQException + { + OpenMBeanOperationInfo[] methodInfos = new OpenMBeanOperationInfo[methods.size()]; + for (int i = 0; i < methodInfos.length; i++) + { + MethodType methodType = methods.get(i); + OpenMBeanParameterInfo[] parameters = createParameterInfos(methodType.getFieldList()); + methodInfos[i] = new OpenMBeanOperationInfoSupport(methodType.getName(), "No description", + parameters, SimpleType.VOID, + OpenMBeanOperationInfoSupport.ACTION); + } + return methodInfos; + } + + private OpenMBeanParameterInfo[] createParameterInfos(List parameters) + throws AMQException + { + OpenMBeanParameterInfo[] paramInfos = new OpenMBeanParameterInfo[parameters.size()]; + for (int i = 0; i < paramInfos.length; i++) + { + FieldType field = parameters.get(i); + String description = field.getLabel(); + OpenType openType = getOpenType(field.getType(), field.getModify()); + paramInfos[i] = new OpenMBeanParameterInfoSupport(field.getName(), + description==null?"No description":description, + openType); + } + return paramInfos; + } +} + diff --git a/java/management/core/src/org/apache/qpid/management/jmx/MBeanRegistrar.java b/java/management/core/src/org/apache/qpid/management/jmx/MBeanRegistrar.java new file mode 100644 index 0000000000..bdc3772553 --- /dev/null +++ b/java/management/core/src/org/apache/qpid/management/jmx/MBeanRegistrar.java @@ -0,0 +1,141 @@ +/* + * + * 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.management.jmx; + +import org.apache.log4j.Logger; +import org.apache.xmlbeans.XmlException; +import org.apache.qpid.AMQException; +import org.apache.qpid.management.ManagementConnection; +import org.apache.qpid.management.messaging.CMLMessageFactory; +import org.apache.qpid.schema.cml.CmlDocument; +import org.apache.qpid.schema.cml.FieldType; +import org.apache.qpid.schema.cml.InspectReplyType; + +import javax.jms.JMSException; +import javax.jms.TextMessage; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.management.openmbean.OpenMBeanAttributeInfo; +import javax.management.openmbean.SimpleType; +import javax.management.openmbean.OpenMBeanInfoSupport; +import java.util.Hashtable; + +/** + * Responsible for registering MBeans. This class will navigate through + * our hierarchy of MBeans, registering them with the appropriate ObjectNames. + * + */ +public class MBeanRegistrar +{ + private static final Logger _log = Logger.getLogger(MBeanRegistrar.class); + + /** The MBean server with which all MBeans will be registered. */ + private MBeanServer _targetMBeanServer; + + /** The connection used to communicate with the broker */ + private ManagementConnection _connection; + + private MBeanInfoRegistry _mbeanInfoRegistry; + + /** + * Create a registrar for the specified MBean server + * @param targetMBeanServer the MBean server with which all MBeans will be registered + */ + public MBeanRegistrar(MBeanServer targetMBeanServer, ManagementConnection connection, + MBeanInfoRegistry mbeanInfoRegistry) + { + _targetMBeanServer = targetMBeanServer; + _connection = connection; + _mbeanInfoRegistry = mbeanInfoRegistry; + } + + public void registerAllMBeans() throws AMQException, JMSException + { + registerMBean(null, 0); + } + + /** + * Asks the broker for details of a particular object id then creates and registers an + * MBean with the MBeanServer. + * @param objectId id of the object we want to inspect + * @return the registered bean, from which the underlying inspect response can be retrieved if required + * @throws AMQException + * @throws JMSException + */ + private CMLMBean registerMBean(CMLMBean parent, int objectId) throws AMQException, JMSException + { + TextMessage response = _connection.sendRequest(CMLMessageFactory.createInspectRequest(objectId)); + try + { + CmlDocument cmlDoc = CmlDocument.Factory.parse(response.getText()); + CmlDocument.Cml cml = cmlDoc.getCml(); + InspectReplyType inspect = cml.getInspectReply(); + if (_log.isDebugEnabled()) + { + _log.debug("Inspect reply: " + inspect); + } + OpenMBeanInfoSupport mbeanInfo = _mbeanInfoRegistry.getOpenMBeanInfo(inspect.getClass1()); + AMQMBeanInfo extraMbeanInfo = _mbeanInfoRegistry.getAMQMBeanInfo(inspect.getClass1()); + CMLMBean mbean = new CMLMBean(parent, mbeanInfo, extraMbeanInfo, inspect, _connection, objectId); + Hashtable props = new Hashtable(); + props.put("objectid", Integer.toString(objectId)); + props.put("type", mbean.getType()); + CMLMBean.populateAllTypeInfo(props, mbean); + ObjectName mbeanObjectName = new ObjectName("org.apache.qpid", props); + mbean.setObjectName(mbeanObjectName); + _targetMBeanServer.registerMBean(mbean, mbeanObjectName); + + // recursively register all beans + String nsDecl = "declare namespace cml='http://www.amqp.org/schema/cml';"; + for (MBeanAttributeInfo attributeInfo: mbeanInfo.getAttributes()) + { + OpenMBeanAttributeInfo openAttributeInfo = (OpenMBeanAttributeInfo) attributeInfo; + if (openAttributeInfo.getOpenType().equals(SimpleType.OBJECTNAME) && + !"__parent".equals(openAttributeInfo.getName())) + { + if (_log.isDebugEnabled()) + { + _log.debug("Searching for fields with name: " + openAttributeInfo.getName()); + } + FieldType[] fields = (FieldType[]) inspect.selectPath(nsDecl + "$this/cml:field[@name='" + + openAttributeInfo.getName() + "']"); + if (fields == null || fields.length == 0) + { + throw new AMQException("inspect xml did not contain field value for field " + + attributeInfo.getName()); + } + for (FieldType field : fields) + { + registerMBean(mbean, Integer.parseInt(field.getStringValue())); + } + } + } + return mbean; + } + catch (XmlException e) + { + throw new AMQException(_log, "Error parsing broker response: " + e, e); + } + catch (Exception e) + { + e.printStackTrace(); + throw new AMQException(_log, "Error registering MBean: " + e, e); + } + } +} diff --git a/java/management/core/src/org/apache/qpid/management/jmx/UnsupportedCMLTypeException.java b/java/management/core/src/org/apache/qpid/management/jmx/UnsupportedCMLTypeException.java new file mode 100644 index 0000000000..bb866f8d17 --- /dev/null +++ b/java/management/core/src/org/apache/qpid/management/jmx/UnsupportedCMLTypeException.java @@ -0,0 +1,36 @@ +/* + * + * 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.management.jmx; + +import org.apache.qpid.AMQException; + +public class UnsupportedCMLTypeException extends AMQException +{ + private String _type; + + public UnsupportedCMLTypeException(String type) + { + super("CML type " + type + " is unsupported by the JMX layer"); + _type = type; + } + + public String getType() + { + return _type; + } +} diff --git a/java/management/core/src/org/apache/qpid/management/messaging/CMLMessageFactory.java b/java/management/core/src/org/apache/qpid/management/messaging/CMLMessageFactory.java new file mode 100644 index 0000000000..e47eb66c65 --- /dev/null +++ b/java/management/core/src/org/apache/qpid/management/messaging/CMLMessageFactory.java @@ -0,0 +1,59 @@ +/* + * + * 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.management.messaging; + +import org.apache.qpid.schema.cml.CmlDocument; +import org.apache.qpid.schema.cml.InspectRequestType; +import org.apache.qpid.schema.cml.MethodRequestType; + +public class CMLMessageFactory +{ + public static String createSchemaRequest() + { + CmlDocument cmlDoc = CmlDocument.Factory.newInstance(); + CmlDocument.Cml cml = createStandardCml(cmlDoc); + cml.addNewSchemaRequest(); + return cmlDoc.toString(); + } + + public static String createInspectRequest(int objectId) + { + CmlDocument cmlDoc = CmlDocument.Factory.newInstance(); + CmlDocument.Cml cml = createStandardCml(cmlDoc); + InspectRequestType inspect = cml.addNewInspectRequest(); + inspect.setObject(objectId); + return cmlDoc.toString(); + } + + public static String createMethodRequest(int objectId, String methodName) + { + CmlDocument cmlDoc = CmlDocument.Factory.newInstance(); + CmlDocument.Cml cml = createStandardCml(cmlDoc); + MethodRequestType methodReq = cml.addNewMethodRequest(); + methodReq.setObject(objectId); + methodReq.setName(methodName); + return cmlDoc.toString(); + } + + private static CmlDocument.Cml createStandardCml(CmlDocument cmlDoc) + { + CmlDocument.Cml cml = cmlDoc.addNewCml(); + cml.setVersion("1.0"); + return cml; + } +} diff --git a/java/management/core/src/org/apache/qpid/management/messaging/ManagementDestination.java b/java/management/core/src/org/apache/qpid/management/messaging/ManagementDestination.java new file mode 100644 index 0000000000..f6edb9394a --- /dev/null +++ b/java/management/core/src/org/apache/qpid/management/messaging/ManagementDestination.java @@ -0,0 +1,43 @@ +/* + * + * 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.management.messaging; + +import org.apache.qpid.client.AMQDestination; + +public class ManagementDestination extends AMQDestination +{ + public ManagementDestination() + { + super("amq.system", "system", "amq.console"); + } + + public boolean isNameRequired() + { + return false; + } + + public String getEncodedName() + { + return null; + } + + public String getRoutingKey() + { + return getDestinationName(); + } +} diff --git a/java/management/core/test/org/apache/qpid/management/harness/SimpleJMXClient.java b/java/management/core/test/org/apache/qpid/management/harness/SimpleJMXClient.java new file mode 100644 index 0000000000..68e1325b1d --- /dev/null +++ b/java/management/core/test/org/apache/qpid/management/harness/SimpleJMXClient.java @@ -0,0 +1,25 @@ +/* + * + * 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.management.harness; + +public class SimpleJMXClient +{ + + + +} diff --git a/java/management/core/test/org/apache/qpid/management/schema/TestParseSchema.java b/java/management/core/test/org/apache/qpid/management/schema/TestParseSchema.java new file mode 100644 index 0000000000..8672207e59 --- /dev/null +++ b/java/management/core/test/org/apache/qpid/management/schema/TestParseSchema.java @@ -0,0 +1,87 @@ +/* + * + * 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.management.schema; + +import org.apache.log4j.Logger; +import org.apache.qpid.management.ManagementConnection; +import org.apache.qpid.management.messaging.CMLMessageFactory; +import org.apache.qpid.schema.cml.CmlDocument; + +import javax.jms.TextMessage; + +public class TestParseSchema +{ + private static final Logger _logger = Logger.getLogger(TestParseSchema.class); + + private static ManagementConnection _con; + + private static void parseCMLSchema(String xml) throws Exception + { + CmlDocument cmlDoc = CmlDocument.Factory.parse(xml); + CmlDocument.Cml cml = cmlDoc.getCml(); + /*SchemaReplyDocument.SchemaReply schema = cml.getSchemaReply(); + for (ClassDocument.Class classDefn: schema.getClass1List()) + { + System.out.println("Class: " + classDefn.getName()); + } */ + } + + public static void main(String[] args) + { + _logger.info("Starting..."); + + if (args.length != 5) + { + System.out.println("Usage: host port username password vhost"); + System.exit(1); + } + try + { + _con = new ManagementConnection(args[0], Integer.parseInt(args[1]), args[2], args[3], + args[4]); + + _con.connect(); + TextMessage tm = _con.sendRequest(CMLMessageFactory.createSchemaRequest()); + parseCMLSchema(tm.getText()); + _logger.info("Closing management connection"); + _con.close(); + + //_logger.info("Waiting..."); + } + catch (Throwable t) + { + _logger.error("Fatal error: " + t, t); + } + finally + { + if (_con != null) + { + _logger.info("Closing connection"); + try + { + _con.close(); + } + catch (Exception e) + { + _logger.error("Error closing connection: " + e); + } + } + } + + } +} diff --git a/java/management/mc4j/qpid/BlazeConnections.xml b/java/management/mc4j/qpid/BlazeConnections.xml new file mode 100644 index 0000000000..b75f49d95b --- /dev/null +++ b/java/management/mc4j/qpid/BlazeConnections.xml @@ -0,0 +1,84 @@ + + + + + + + This dashboard shows the statistics of all Qpid Client Connections. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/mc4j/qpid/BlazeExchanges.xml b/java/management/mc4j/qpid/BlazeExchanges.xml new file mode 100644 index 0000000000..6612c711c3 --- /dev/null +++ b/java/management/mc4j/qpid/BlazeExchanges.xml @@ -0,0 +1,81 @@ + + + + + + + This dashboard shows the statistics of all Qpid Exchanges. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/mc4j/qpid/BlazeQueues.xml b/java/management/mc4j/qpid/BlazeQueues.xml new file mode 100644 index 0000000000..4a6e55cdb7 --- /dev/null +++ b/java/management/mc4j/qpid/BlazeQueues.xml @@ -0,0 +1,83 @@ + + + + + + + This dashboard shows the statistics of all Qpid Queues. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/mc4j/qpid/BlazeSingleQueue.xml b/java/management/mc4j/qpid/BlazeSingleQueue.xml new file mode 100644 index 0000000000..0879801746 --- /dev/null +++ b/java/management/mc4j/qpid/BlazeSingleQueue.xml @@ -0,0 +1,99 @@ + + + + + + + This dashboard shows the statistics of a Qpid Queue + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/webapp/META-INF/context.xml b/java/management/webapp/META-INF/context.xml new file mode 100644 index 0000000000..1d3d5683b9 --- /dev/null +++ b/java/management/webapp/META-INF/context.xml @@ -0,0 +1,20 @@ + + + + diff --git a/java/management/webapp/WEB-INF/web.xml b/java/management/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..db467779bf --- /dev/null +++ b/java/management/webapp/WEB-INF/web.xml @@ -0,0 +1,24 @@ + + + + + -- cgit v1.2.1