diff options
author | Rafael H. Schloming <rhs@apache.org> | 2006-09-19 22:06:50 +0000 |
---|---|---|
committer | Rafael H. Schloming <rhs@apache.org> | 2006-09-19 22:06:50 +0000 |
commit | 913489deb2ee9dbf44455de5f407ddaf4bd8c540 (patch) | |
tree | 7ea442d6867d0076f1c9ea4f4265664059e7aff5 /java/management/cli | |
download | qpid-python-913489deb2ee9dbf44455de5f407ddaf4bd8c540.tar.gz |
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
Diffstat (limited to 'java/management/cli')
19 files changed, 1318 insertions, 0 deletions
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 @@ +<!-- + - + - 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. + - + --> +<project name="AMQ Management Client" default="build"> + <property name="module.depends" value="common,client,management/core"/> + <import file="../../module.xml"/> +</project> 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 @@ +<?xml version="1.0"?> +<!-- + - + - 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. + - + --> + +<!-- AMQP STAC Java build file --> + +<project name="management-stac" default="jar" basedir="."> + <property name="lib" value="${basedir}/lib"/> + <property name="src" value="${basedir}/src"/> + <property name="tests" value="${basedir}/test"/> + <property name="classes" value="${basedir}/classes"/> + <property name="testclasses" value="${basedir}/testclasses"/> + <property name="dist" value="${basedir}/dist"/> + <property name="amqp.root" value="${basedir}/../../clients_java"/> + <property name="amqp.lib" value="${amqp.root}/lib"/> + <property name="amqp.dist" value="${amqp.root}/dist"/> + <property name="managementcore.root" value="${basedir}/../core"/> + <property name="managementcore.dist" value="${managementcore.root}/dist"/> + <property name="managementcore.lib" value="${managementcore.root}/lib"/> + + <!-- Setup details --> + <target name="init"> + <tstamp> + <format property="release" pattern="-dMMMyy" locale="en" timezone="GMT"/> + </tstamp> + + <mkdir dir="${classes}"/> + <mkdir dir="${testclasses}"/> + <mkdir dir="${dist}"/> + </target> + + <path id="core.classpath"> + <fileset dir="${lib}"> + <include name="**/*.jar"/> + </fileset> + <pathelement path="${classes}"/> + <pathelement path="${testclasses}/"/> + <fileset dir="${managementcore.dist}"> + <include name="**/*.jar"/> + </fileset> + <fileset dir="${managementcore.lib}"> + <include name="**/*.jar"/> + </fileset> + <fileset dir="${amqp.dist}"> + <include name="**/*.jar"/> + </fileset> + <fileset dir="${amqp.lib}"> + <include name="**/*.jar"/> + </fileset> + </path> + + <!-- Remove all built files --> + <target name="clean" depends="init"> + <delete dir="${classes}"/> + <delete dir="${dist}"/> + <delete dir="${testclasses}"/> + </target> + + <!-- Compile Java --> + <target name="compile" depends="init"> + <javac destdir="${classes}" target="1.5" source="1.5" debug="on"> + <classpath refid="core.classpath"/> + <src path="${src}"/> + </javac> + + <copy todir="${classes}"> + <!-- copy any non java src files into the build tree, e.g. log4j.properties --> + <fileset dir="${src}"> + <exclude name="**/*.java"/> + <exclude name="**/package.html"/> + </fileset> + </copy> + </target> + + + <target name="compiletests" depends="compile"> + <javac destdir="${testclasses}" target="1.5" source="1.5" classpathref="core.classpath" + debug="on"> + <src path="${tests}"/> + </javac> + + <copy todir="${testclasses}"> + <!-- copy any non java src files into the build tree, e.g. log4j.properties --> + <fileset dir="${tests}"> + <exclude name="**/*.java"/> + <exclude name="**/package.html"/> + </fileset> + </copy> + </target> + + <!-- Build jar archive --> + <target name="jar" depends="compiletests"> + <mkdir dir="${dist}"/> + <jar basedir="${classes}" jarfile="${dist}/amqp-stac.jar"/> + <jar basedir="${testclasses}" jarfile="${dist}/amqp-stac-tests.jar"/> + </target> + + + <target name="javadoc" depends="compile, compiletests"> + <mkdir dir="${dist}/docs/api"/> + <javadoc sourcepath="${src}" destdir="${dist}/docs/api" + packagenames="org.apache.qpid.*" classpathref="amqp.classpath" author="true" + version="true" windowTitle="AMQP STAC API" doctitle="AMQP STAC API" + footer="See <a href="http://www.amqp.org">www.amqp.org</a> for more information." + use="true" verbose="false"/> + </target> +</project> diff --git a/java/management/cli/lib/jython/jython.jar b/java/management/cli/lib/jython/jython.jar Binary files differnew file mode 100644 index 0000000000..517c60dd0e --- /dev/null +++ b/java/management/cli/lib/jython/jython.jar 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<MBeanAttributeInfo> 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<MBeanAttributeInfo> 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<MBeanOperationInfo> 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<String, ObjectName> _name2ObjectNameMap = new HashMap<String, ObjectName>(); + + 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<MBeanAttributeInfo> getOrderedObjects() throws AMQException + { + TreeSet<MBeanAttributeInfo> attributes = new TreeSet<MBeanAttributeInfo>(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<MBeanAttributeInfo> getOrderedAttributes() + { + TreeSet<MBeanAttributeInfo> attributes = new TreeSet<MBeanAttributeInfo>(new MBeanAttributeInfoComparator()); + for (MBeanAttributeInfo ai : _mbeanInfo.getAttributes()) + { + String type = ai.getType(); + if (!"javax.management.ObjectName".equals(type)) + { + attributes.add(ai); + } + } + return attributes; + } + + public SortedSet<MBeanOperationInfo> getOrderedOperations() + { + TreeSet<MBeanOperationInfo> operations = new TreeSet<MBeanOperationInfo>(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<MBeanAttributeInfo> +{ + 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<MBeanOperationInfo> +{ + 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<ObjectInstance> 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<String, String> props = new Hashtable<String, String>(); + 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(); + } +} |