diff options
author | Robert Greig <rgreig@apache.org> | 2007-01-07 17:03:17 +0000 |
---|---|---|
committer | Robert Greig <rgreig@apache.org> | 2007-01-07 17:03:17 +0000 |
commit | e4f9d0f1bb278cc4ae76a9e0bd4a70763297d464 (patch) | |
tree | eb714b2437f78674bb51fab85b994d32bc9e4089 | |
parent | 84220aa52dabd8d4df9203fdde61c1a560b85970 (diff) | |
download | qpid-python-e4f9d0f1bb278cc4ae76a9e0bd4a70763297d464.tar.gz |
Merge from trunk rev 493060
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/branches/new_persistence@493771 13f79535-47bb-0310-9956-ffa450edef68
28 files changed, 1544 insertions, 380 deletions
diff --git a/java/ReadMe.txt b/java/ReadMe.txt deleted file mode 100644 index a389131844..0000000000 --- a/java/ReadMe.txt +++ /dev/null @@ -1,15 +0,0 @@ -Running the Broker ------------------- - -To run the broker, set the QPID_HOME environment variable to -distribution directory and add $QPID_HOME/bin to your PATH. Then run -the qpid-server shell script or qpid-server.bat batch file to start -the broker. By default, the broker will use $QPID_HOME/etc to find -the configuration files. You can supply a custom configuration using -the -c argument. - -For example: - -qpid-server -c ~/etc/config.xml - -You can get a list of all command line arguments by using the -h argument. diff --git a/java/broker/etc/config.xml b/java/broker/etc/config.xml index 0862588a0d..0e2a9187d7 100644 --- a/java/broker/etc/config.xml +++ b/java/broker/etc/config.xml @@ -64,7 +64,7 @@ <class>org.apache.qpid.server.security.auth.amqplain.AmqPlainInitialiser</class> <principal-database>passwordfile</principal-database> </initialiser> - </mechanism>--> + </mechanism> <mechanism> <initialiser> <class>org.apache.qpid.server.security.auth.plain.PlainInitialiser</class> diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java index 4362f64ec5..42d13653a9 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java @@ -164,17 +164,14 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, _minor = pi.protocolMinor; String mechanisms = ApplicationRegistry.getInstance().getAuthenticationManager().getMechanisms(); String locales = "en_US"; - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. + // Interfacing with generated code - be aware of possible changes to parameter order as versions change. AMQFrame response = ConnectionStartBody.createAMQFrame((short) 0, - (byte)8, (byte)0, // AMQP version (major, minor) + _major, _minor, // AMQP version (major, minor) locales.getBytes(), // locales mechanisms.getBytes(), // mechanisms null, // serverProperties - (short)8, // versionMajor - (short)0 // versionMinor - ); + (short)_major, // versionMajor + (short)_minor); // versionMinor _minaProtocolSession.write(response); } catch (AMQException e) diff --git a/java/client/example/bin/set_classpath.bat b/java/client/example/bin/set_classpath.bat new file mode 100644 index 0000000000..d528967024 --- /dev/null +++ b/java/client/example/bin/set_classpath.bat @@ -0,0 +1,50 @@ +@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+
+@REM Helper script to set classpath for running Qpid example classes
+@REM NB: You must add the Qpid client and common jars to your CLASSPATH
+@REM before running this script
+
+@echo off
+
+if "%QPID_HOME%" == "" GOTO ERROR_QPID_HOME
+
+set QPIDLIB=%QPID_HOME%\lib
+
+if "%CLASSPATH%" == "" GOTO ERROR_CLASSPATH
+
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\backport-util-concurrent-2.2.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\geronimo-jms_1.1_spec-1.0.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\commons-collections-3.1.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\commons-configuration-1.2.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\commons-cli-1.0.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\commons-lang-2.1.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\commons-logging-api-1.0.4.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\commons-logging-1.0.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\log4j-1.2.12.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\mina-core-1.0.0.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\mina-filter-ssl-1.0.0.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\mina-java5-1.0.0.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\slf4j-simple-1.0.jar
+
+GOTO END
+
+:ERROR_CLASSPATH
+Echo Please set set your CLASSPATH variable to include the Qpid client and common jars. Exiting ....
+:ERROR_QPID_HOME
+Echo Please set QPID_HOME variable. Exiting ....
+:END
diff --git a/java/client/example/bin/set_classpath.sh b/java/client/example/bin/set_classpath.sh new file mode 100755 index 0000000000..89e9bc8242 --- /dev/null +++ b/java/client/example/bin/set_classpath.sh @@ -0,0 +1,83 @@ +#!/bin/sh -xv +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Helper script to set classpath for running Qpid example classes +# NB: You must add the Qpid client and common jars to your CLASSPATH +# before running this script + + +cygwin=false +if [[ "$(uname -a | fgrep Cygwin)" != "" ]]; then + cygwin=true +fi + +#Should have set the QPID_HOME var after install to the working dir e.g. home/qpid/qpid-1.0-incubating-M2-SNAPSHOT +if [ "$QPID_HOME" = "" ] ; then + echo "ERROR: Please set QPID_HOME variable. Exiting ...." + exit 1 +else + QPIDLIB=$QPID_HOME/lib +fi + +if $cygwin; then + QPIDLIB=$(cygpath -w $QPIDLIB) +fi + +if [ "$CLASSPATH" = "" ] ; then + echo "ERROR: Please set set your CLASSPATH variable to include the Qpid client and common jars. Exiting ...." + exit 2 +fi + +#Converts paths for cygwin if req +#Some nasty concatenation to get round cygpath line limits +if $cygwin; then + SEP=";" + CLASSPATH=`cygpath -w $CLASSPATH` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/backport-util-concurrent-2.2.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/geronimo-jms_1.1_spec-1.0.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/commons-collections-3.1.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/commons-configuration-1.2.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/commons-cli-1.0.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/commons-lang-2.1.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/commons-logging-api-1.0.4.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/commons-logging-1.0.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/log4j-1.2.12.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/mina-core-1.0.0.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/mina-filter-ssl-1.0.0.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/mina-java5-1.0.0.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/slf4j-simple-1.0.jar` + export CLASSPATH +else + CLASSPATH=$CLASSPATH:$QPIDLIB/backport-util-concurrent-2.2.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/geronimo-jms_1.1_spec-1.0.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/commons-collections-3.1.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/commons-configuration-1.2.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/commons-cli-1.0.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/commons-lang-2.1.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/commons-logging-api-1.0.4.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/commons-logging-1.0.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/log4j-1.2.12.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/mina-core-1.0.0.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/mina-filter-ssl-1.0.0.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/mina-java5-1.0.0.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/slf4j-simple-1.0.jar + export CLASSPATH +fi + diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQType.java b/java/common/src/main/java/org/apache/qpid/framing/AMQType.java index 4bce1ca5f0..ad07634554 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/AMQType.java +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQType.java @@ -28,35 +28,39 @@ public enum AMQType //AMQP FieldTable Wire Types
- DECIMAL('D')
+ LONG_STRING('S')
{
-
public int getEncodingSize(Object value)
{
- // TODO : fixme
- throw new UnsupportedOperationException();
+ return EncodingUtils.encodedLongStringLength((String) value);
}
- public Object toNativeValue(Object value)
+
+ public String toNativeValue(Object value)
{
- // TODO : fixme
- throw new UnsupportedOperationException();
+ if (value != null)
+ {
+ return value.toString();
+ }
+ else
+ {
+ throw new NullPointerException("Cannot convert: null to String.");
+ }
}
public void writeValueImpl(Object value, ByteBuffer buffer)
{
- // TODO : fixme
- throw new UnsupportedOperationException();
+ EncodingUtils.writeLongStringBytes(buffer, (String) value);
}
public Object readValueFromBuffer(ByteBuffer buffer)
{
- // TODO : fixme
- throw new UnsupportedOperationException();
+ return EncodingUtils.readLongString(buffer);
}
+
},
- UNSIGNED_SHORT('S')
+ INTEGER('I')
{
public int getEncodingSize(Object value)
@@ -65,6 +69,7 @@ public enum AMQType throw new UnsupportedOperationException();
}
+
public Object toNativeValue(Object value)
{
// TODO : fixme
@@ -82,10 +87,9 @@ public enum AMQType // TODO : fixme
throw new UnsupportedOperationException();
}
-
},
- UNSIGNED_INT('I')
+ DECIMAL('D')
{
public int getEncodingSize(Object value)
@@ -94,7 +98,6 @@ public enum AMQType throw new UnsupportedOperationException();
}
-
public Object toNativeValue(Object value)
{
// TODO : fixme
@@ -114,7 +117,7 @@ public enum AMQType }
},
- UNSIGNED_LONG('L')
+ TIMESTAMP('T')
{
public int getEncodingSize(Object value)
@@ -124,7 +127,7 @@ public enum AMQType }
- public Long toNativeValue(Object value)
+ public Object toNativeValue(Object value)
{
// TODO : fixme
throw new UnsupportedOperationException();
@@ -143,9 +146,8 @@ public enum AMQType }
},
- EXTTENDED('D')
+ FIELD_TABLE('F')
{
-
public int getEncodingSize(Object value)
{
// TODO : fixme
@@ -172,35 +174,39 @@ public enum AMQType }
},
- TIMESTAMP('T')
+ VOID('V')
{
-
public int getEncodingSize(Object value)
{
- // TODO : fixme
- throw new UnsupportedOperationException();
+ return 0;
}
public Object toNativeValue(Object value)
{
- // TODO : fixme
- throw new UnsupportedOperationException();
+ if (value == null)
+ {
+ return null;
+ }
+ else
+ {
+ throw new NumberFormatException("Cannot convert: " + value + "(" +
+ value.getClass().getName() + ") to null String.");
+ }
}
public void writeValueImpl(Object value, ByteBuffer buffer)
{
- // TODO : fixme
- throw new UnsupportedOperationException();
}
public Object readValueFromBuffer(ByteBuffer buffer)
{
- // TODO : fixme
- throw new UnsupportedOperationException();
+ return null;
}
},
+ // Extended types
+
BINARY('x')
{
public int getEncodingSize(Object value)
@@ -299,38 +305,6 @@ public enum AMQType }
},
- NULL_STRING('n')
- {
-
- public int getEncodingSize(Object value)
- {
- return 0;
- }
-
-
- public String toNativeValue(Object value)
- {
- if (value == null)
- {
- return null;
- }
- else
- {
- throw new NumberFormatException("Cannot convert: " + value + "(" +
- value.getClass().getName() + ") to null String.");
- }
- }
-
- public void writeValueImpl(Object value, ByteBuffer buffer)
- {
- }
-
- public Object readValueFromBuffer(ByteBuffer buffer)
- {
- return null;
- }
- },
-
BOOLEAN('t')
{
public int getEncodingSize(Object value)
@@ -368,77 +342,77 @@ public enum AMQType }
},
- BYTE('b')
+ ASCII_CHARACTER('k')
{
public int getEncodingSize(Object value)
{
- return EncodingUtils.encodedByteLength();
+ return EncodingUtils.encodedCharLength();
}
- public Byte toNativeValue(Object value)
+ public Character toNativeValue(Object value)
{
- if (value instanceof Byte)
+ if (value instanceof Character)
{
- return (Byte) value;
+ return (Character) value;
}
- else if ((value instanceof String) || (value == null))
+ else if (value == null)
{
- return Byte.valueOf((String)value);
+ throw new NullPointerException("Cannot convert null into char");
}
else
{
throw new NumberFormatException("Cannot convert: " + value + "(" +
- value.getClass().getName() + ") to byte.");
+ value.getClass().getName() + ") to char.");
}
}
public void writeValueImpl(Object value, ByteBuffer buffer)
{
- EncodingUtils.writeByte(buffer, (Byte) value);
+ EncodingUtils.writeChar(buffer, (Character) value);
}
public Object readValueFromBuffer(ByteBuffer buffer)
{
- return EncodingUtils.readByte(buffer);
+ return EncodingUtils.readChar(buffer);
}
+
},
- ASCII_CHARACTER('k')
+ BYTE('b')
{
public int getEncodingSize(Object value)
{
- return EncodingUtils.encodedCharLength();
+ return EncodingUtils.encodedByteLength();
}
- public Character toNativeValue(Object value)
+ public Byte toNativeValue(Object value)
{
- if (value instanceof Character)
+ if (value instanceof Byte)
{
- return (Character) value;
+ return (Byte) value;
}
- else if (value == null)
+ else if ((value instanceof String) || (value == null))
{
- throw new NullPointerException("Cannot convert null into char");
+ return Byte.valueOf((String)value);
}
else
{
throw new NumberFormatException("Cannot convert: " + value + "(" +
- value.getClass().getName() + ") to char.");
+ value.getClass().getName() + ") to byte.");
}
}
public void writeValueImpl(Object value, ByteBuffer buffer)
{
- EncodingUtils.writeChar(buffer, (Character) value);
+ EncodingUtils.writeByte(buffer, (Byte) value);
}
public Object readValueFromBuffer(ByteBuffer buffer)
{
- return EncodingUtils.readChar(buffer);
+ return EncodingUtils.readByte(buffer);
}
-
},
SHORT('s')
diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQTypeMap.java b/java/common/src/main/java/org/apache/qpid/framing/AMQTypeMap.java index e24fd7efeb..5ac7f8827b 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/AMQTypeMap.java +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQTypeMap.java @@ -37,7 +37,12 @@ public class AMQTypeMap public static AMQType getType(Byte identifier)
{
- return _reverseTypeMap.get(identifier);
+ AMQType result = _reverseTypeMap.get(identifier);
+ if (result == null) {
+ throw new IllegalArgumentException
+ ("no such type code: " + Integer.toHexString(identifier.intValue()));
+ }
+ return result;
}
}
diff --git a/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java b/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java index 4d88009076..3c18683609 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java +++ b/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java @@ -257,7 +257,7 @@ public class FieldTable checkPropertyName(string); if (value == null) { - return _properties.put(string, AMQType.NULL_STRING.asTypedValue(null)); + return _properties.put(string, AMQType.VOID.asTypedValue(null)); } else { @@ -344,7 +344,7 @@ public class FieldTable public boolean isNullStringValue(String name) { AMQTypedValue value = _properties.get(name); - return (value != null) && (value.getType() == AMQType.NULL_STRING); + return (value != null) && (value.getType() == AMQType.VOID); } // ***** Methods diff --git a/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java b/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java index f0d5489527..f2d1a70cdc 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java +++ b/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java @@ -146,18 +146,6 @@ public class ProtocolInitiation extends AMQDataBlock implements EncodableAMQData throw new AMQProtocolInstanceException("Protocol instance " + CURRENT_PROTOCOL_INSTANCE + " was expected; received " + protocolInstance); } - /* - if (protocolMajor != CURRENT_PROTOCOL_VERSION_MAJOR) - { - throw new AMQProtocolVersionException("Protocol major version " + CURRENT_PROTOCOL_VERSION_MAJOR + - " was expected; received " + protocolMajor); - } - if (protocolMinor != CURRENT_PROTOCOL_VERSION_MINOR) - { - throw new AMQProtocolVersionException("Protocol minor version " + CURRENT_PROTOCOL_VERSION_MINOR + - " was expected; received " + protocolMinor); - } - */ /* Look through list of available protocol versions */ boolean found = false; diff --git a/java/distribution/src/main/assembly/bin.xml b/java/distribution/src/main/assembly/bin.xml index 9b0a56a744..00ffd86bd0 100644 --- a/java/distribution/src/main/assembly/bin.xml +++ b/java/distribution/src/main/assembly/bin.xml @@ -31,14 +31,17 @@ <directory>src/main/release</directory> <outputDirectory>qpid-${qpid.version}</outputDirectory> <includes> - <include>DISCLAIMER</include> + <include>DISCLAIMER</include> + <include>LICENSE.txt</include> + <include>NOTICE.txt</include> + <include>README.txt</include> </includes> </fileSet> <fileSet> <directory>..</directory> <outputDirectory>qpid-${qpid.version}</outputDirectory> <includes> - <include>*.txt</include> + <include>*.txt</include> </includes> </fileSet> <fileSet> @@ -53,14 +56,14 @@ <directory>src/main/release/docs</directory> <outputDirectory>qpid-${qpid.version}/docs</outputDirectory> <includes> - <include>RELEASE_NOTES.txt</include> + <include>RELEASE_NOTES.txt</include> </includes> </fileSet> <fileSet> <directory>target</directory> <outputDirectory>qpid-${qpid.version}/lib</outputDirectory> <includes> - <include>qpid-incubating.jar</include> + <include>qpid-incubating.jar</include> </includes> </fileSet> </fileSets> diff --git a/java/distribution/src/main/assembly/client-bin.xml b/java/distribution/src/main/assembly/client-bin.xml index f89b1a39d2..b9e9939c95 100644 --- a/java/distribution/src/main/assembly/client-bin.xml +++ b/java/distribution/src/main/assembly/client-bin.xml @@ -43,6 +43,9 @@ <outputDirectory>qpid-${qpid.version}</outputDirectory> <includes> <include>DISCLAIMER</include> + <include>LICENSE.txt</include> + <include>NOTICE.txt</include> + <include>README.txt</include> </includes> </fileSet> <fileSet> diff --git a/java/distribution/src/main/assembly/src.xml b/java/distribution/src/main/assembly/src.xml index b66425c3d2..49e1f8bfb2 100644 --- a/java/distribution/src/main/assembly/src.xml +++ b/java/distribution/src/main/assembly/src.xml @@ -32,10 +32,10 @@ <outputDirectory>qpid-${qpid.version}-src</outputDirectory> <includes> <include>DISCLAIMER</include> - <include>LICENSE</include> + <include>LICENSE.txt</include> <include>licenses/*.*</include> - <include>NOTICE</include> - <include>README</include> + <include>NOTICE.txt</include> + <include>README.txt</include> <include>BUILDING.txt</include> </includes> </fileSet> diff --git a/java/distribution/src/main/release/LICENSE.txt b/java/distribution/src/main/release/LICENSE.txt new file mode 100755 index 0000000000..6b0b1270ff --- /dev/null +++ b/java/distribution/src/main/release/LICENSE.txt @@ -0,0 +1,203 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/java/distribution/src/main/release/NOTICE.txt b/java/distribution/src/main/release/NOTICE.txt new file mode 100644 index 0000000000..82d3dbc632 --- /dev/null +++ b/java/distribution/src/main/release/NOTICE.txt @@ -0,0 +1,36 @@ +========================================================================= +== NOTICE file corresponding to the section 4 d of == +== the Apache License, Version 2.0, == +== in this case for the Apache Qpid distribution. == +========================================================================= + +This product includes software developed by the Apache Software Foundation +(http://www.apache.org/). + +Please read the LICENSE.txt file present in the root directory of this +distribution. + + +Aside from contributions to the Apache Qpid project, this software also +includes (binary only): + + - The SAXON XSLT Processor from Michael Kay distributed under the + Mozilla Public License v1.0, which is available for download at + http://saxon.sourceforge.net/ + + - The JUnit regression testing framework written by Erich Gamma + and Kent Beck and distributed under the Common Public License v1.0. + JUnit is available for download at + http://sourceforge.net/projects/junit/ + + - The Simple Logging Facade For Java (slf4j), Copyright (c) + 2004-2005 SLF4J.ORG, Copyright (c) 2004-2005 QOS.ch. slf4j is + licensed under identical terms to the MIT/X11 license and + available for download at http://www.slf4j.org/ + + - Software from the Eclipse project. The binaries from this project are + distributed under the Eclipse Public License and can be donwloaded + from http://www.eclipse.org/ + + + diff --git a/java/distribution/src/main/release/README.txt b/java/distribution/src/main/release/README.txt new file mode 100644 index 0000000000..14706170bc --- /dev/null +++ b/java/distribution/src/main/release/README.txt @@ -0,0 +1,104 @@ + +Documentation +-------------- +All of our user documentation for the Qpid Java components can be accessed on our wiki at: + +http://cwiki.apache.org/confluence/display/qpid/Qpid+Java+Documentation + +This includes a Getting Started Guide and FAQ as well as detailed developer documentation. +However, here's a VERY quick guide to running the installed Qpid broker, once you have installed it somewhere ! + + +Running the Broker +------------------ + +To run the broker, set the QPID_HOME environment variable to +distribution directory and add $QPID_HOME/bin to your PATH. Then run +the qpid-server shell script or qpid-server.bat batch file to start +the broker. By default, the broker will use $QPID_HOME/etc to find +the configuration files. You can supply a custom configuration using +the -c argument. + +For example: + +qpid-server -c ~/etc/config.xml + +You can get a list of all command line arguments by using the -h argument. + + +Developing +---------- + +In order to build Qpid you need Ant 1.6.5. Use ant -p to list the +available targets. The default ant target, build, creates a working +development-mode distribution in the build directory. To run the +scripts in build/bin set QPID_HOME to the build directory and put +${QPID_HOME}/bin on your PATH. The scripts in that directory include +the standard ones in the distribution and a number of testing scripts. + + +Running Tests +------------- + +The simplest test to ensure everything is working is the "service +request reply" test. This involves one client that is known as a +"service provider" and it listens on a well-known queue for +requests. Another client, known as the "service requester" creates a +private (temporary) response queue, creates a message with the private +response queue set as the "reply to" field and then publishes the +message to the well known service queue. The test allows you to time +how long it takes to send messages and receive the response back. It +also allows varying of the message size. + +You must start the service provider first: + +serviceProvidingClient.sh nop host:port + +where host:port is the host and port you are running the broker +on. + +To run the service requester: + +serviceRequestingClient.sh nop host:post <count> <bytes> + +This requests <count> messages, each of size <bytes>. After +receiving all the messages the client outputs the rate it achieved. + +A more realistic test is the "headers test", which tests the +performance of routing messages based on message headers to a +configurable number of clients (e.g. 50). A publisher sends 10000 +messages to each client and waits to receive a message from each +client when it has received all the messages. + +You run the listener processes first: + +run_many.sh 10 header "headersListener.sh -host 10.0.0.1 -port 5672" + +In this command, the first argument means start 10 processes, the +second is just a name use in the log files generated and the third +argument is the command to run. In this case it runs another shell +script but it could be anything. + +Then run the publisher process: + +headersPublisher.sh -host 10.0.0.1 -port 5672 10000 10 + +The last two arguments are: the number of messages to send to each +client, and the number of clients. + +Note that before starting the publisher you should wait about 30 +seconds to ensure all the clients are registered with the broker (you +can see this from the broker output). Otherwise the numbers will be +slightly skewed. + +A third useful test, which can easily be ported to other JMS +implementations is the "topic test". It does the same as the headers +test but using a standard topic (e.g. pub sub). + +To run the listeners: + +run_many.sh 10 topic "topicListener.sh -host 10.0.0.1 -port 5672" + +and to run the publisher: + +topicPublisher.sh -host 10.0.0.1 -port 5672 -clients 10 -messages 10000 diff --git a/java/management/eclipse-plugin/bin/qpidmc.sh b/java/management/eclipse-plugin/bin/qpidmc.sh index c9ab423fdd..13e3edcc94 100755 --- a/java/management/eclipse-plugin/bin/qpidmc.sh +++ b/java/management/eclipse-plugin/bin/qpidmc.sh @@ -1,3 +1,13 @@ #!/bin/bash +if [ "$JAVA_HOME" == "" ]; then + echo "The JAVA_HOME environment variable is not defined"; + exit 0; +fi + +if [ "$QPIDMC_HOME" == "" ]; then + echo "The QPIDMC_HOME environment variable is not defined correctly"; + exit 0; +fi + "$JAVA_HOME/bin/java" -Xms40m -Xmx256m -Declipse.consoleLog=false -jar $QPIDMC_HOME/eclipse/startup.jar org.eclipse.core.launcher.Main -launcher $QPIDMC_HOME/eclipse/eclipse -name "Qpid Management Console" -showsplash 600 -configuration "file:$QPIDMC_HOME/configuration" diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java index adb20b1cd9..756d404596 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java @@ -34,10 +34,13 @@ public class Constants public final static String DOMAIN = "domain"; public final static String TYPE = "mbeantype"; public final static String MBEAN = "mbean"; + public final static String ATTRIBUTE = "Attribute"; public final static String ATTRIBUTES = "Attributes"; public final static String NOTIFICATION = "Notifications"; public final static String RESULT = "Result"; + public final static String ATTRIBUTE_QUEUE_DEPTH = "QueueDepth"; + public final static String ALL = "All"; public final static String NAVIGATION_ROOT = "Qpid Connections"; diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java index 0beeda84dd..6fbfdcd06f 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java @@ -21,15 +21,23 @@ package org.apache.qpid.management.ui; +import java.util.ArrayList; import java.util.List; import org.apache.qpid.management.ui.jmx.ClientListener; +import org.apache.qpid.management.ui.model.ManagedAttributeModel; import org.apache.qpid.management.ui.model.NotificationObject; import org.apache.qpid.management.ui.model.OperationDataModel; public abstract class ServerRegistry { private ManagedServer _managedServer = null; + // list of all Connection mbeans + protected List<ManagedBean> _connections = new ArrayList<ManagedBean>(); + // list of all exchange mbeans + protected List<ManagedBean> _exchanges = new ArrayList<ManagedBean>(); + // list of all queue mbenas + protected List<ManagedBean> _queues = new ArrayList<ManagedBean>(); public ServerRegistry() { @@ -51,6 +59,64 @@ public abstract class ServerRegistry _managedServer = server; } + protected void addConnectionMBean(ManagedBean mbean) + { + _connections.add(mbean); + } + + protected void addExchangeMBean(ManagedBean mbean) + { + _exchanges.add(mbean); + } + + protected void addQueueMBean(ManagedBean mbean) + { + _queues.add(mbean); + } + + protected void removeConnectionMBean(ManagedBean mbean) + { + _connections.remove(mbean); + } + + protected void removeExchangeMBean(ManagedBean mbean) + { + _exchanges.remove(mbean); + } + + protected void removeQueueMBean(ManagedBean mbean) + { + _queues.remove(mbean); + } + + public List<ManagedBean> getConnections() + { + return _connections; + } + + public List<ManagedBean> getExchanges() + { + return _exchanges; + } + + public List<ManagedBean> getQueues() + { + return _queues; + } + + public abstract void addManagedObject(ManagedBean key); + + public abstract List<ManagedBean> getMBeans(); + + public abstract void removeManagedObject(ManagedBean mbean); + + public List<ManagedBean> getObjectsToBeRemoved() + { + return null; + } + + public abstract ManagedAttributeModel getAttributeModel(ManagedBean mbean); + public abstract Object getServerConnection(); public abstract void closeServerConnection() throws Exception; @@ -61,6 +127,8 @@ public abstract class ServerRegistry public abstract String[] getExchangeNames(); + public abstract String[] getConnectionNames(); + public abstract List<NotificationObject> getNotifications(ManagedBean mbean); public abstract boolean hasSubscribedForNotifications(ManagedBean mbean, String name, String type); diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java index 85b312cf99..a2335c5841 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.management.ui.actions; +import org.apache.qpid.management.ui.jmx.MBeanUtility; import org.apache.qpid.management.ui.views.MBeanView; import org.apache.qpid.management.ui.views.NavigationView; import org.eclipse.jface.action.IAction; @@ -27,6 +28,10 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkbenchWindowActionDelegate; +/** + * This action refreshes both the views -Navigation and MBeanView + * @author Bhupendra Bhardwaj + */ public class Refresh implements IWorkbenchWindowActionDelegate { private IWorkbenchWindow _window; @@ -71,7 +76,14 @@ public class Refresh implements IWorkbenchWindowActionDelegate view.refresh(); MBeanView mbeanview = (MBeanView)_window.getActivePage().findView(MBeanView.ID); - mbeanview.refreshMBeanView(); + try + { + mbeanview.refreshMBeanView(); + } + catch (Exception ex) + { + MBeanUtility.handleException(ex); + } } } } diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java index 9bc3ea1b0f..c087bd2e72 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import javax.management.ListenerNotFoundException; import javax.management.MBeanInfo; import javax.management.MBeanServerConnection; import javax.management.Notification; @@ -50,21 +51,31 @@ public class JMXServerRegistry extends ServerRegistry private JMXConnector _jmxc = null; private MBeanServerConnection _mbsc = null; - private List<ManagedBean> _mbeansToBeAdded = new ArrayList<ManagedBean>(); + // When an mbean gets removed from mbean server, then the notification listener + // will add that mbean in this list. private List<ManagedBean> _mbeansToBeRemoved = new ArrayList<ManagedBean>(); - private List<String> _queues = new ArrayList<String>(); - private List<String> _exchanges = new ArrayList<String>(); - - private HashMap<String, ManagedBean> _mbeansMap = new HashMap<String, ManagedBean>(); + // Map containing all managed beans and ampped with unique mbean name + private HashMap<String, ManagedBean> _mbeansMap = new HashMap<String, ManagedBean>(); + // Map containing MBeanInfo for all mbeans and mapped with unique mbean name private HashMap<String, MBeanInfo> _mbeanInfoMap = new HashMap<String, MBeanInfo>(); + // Map containing attribute model for all mbeans and mapped with unique mbean name private HashMap<String, ManagedAttributeModel> _attributeModelMap = new HashMap<String, ManagedAttributeModel>(); + // Map containing operation model for all mbeans and mapped with unique mbean name private HashMap<String, OperationDataModel> _operationModelMap = new HashMap<String, OperationDataModel>(); + // Map containing NotificationInfo for all mbeans and mapped with unique mbean name private HashMap<String, List<NotificationInfoModel>> _notificationInfoMap = new HashMap<String, List<NotificationInfoModel>>(); + // Map containing all notifications sent for all mbeans, which are registered for notification private HashMap<String, List<NotificationObject>> _notificationsMap = new HashMap<String, List<NotificationObject>>(); + // For mbeans which have subscribed for a notification type + // mbean unique name mapped with notification map. Notification map contains list of notification type + // mapped with notification name. Notification type list contains those notification types, + // which are subscribed for notification. private HashMap<String, HashMap<String, List<String>>> _subscribedNotificationMap = new HashMap<String, HashMap<String, List<String>>>(); + // listener for registration or unregistratioj of mbeans on mbean server private ClientNotificationListener _notificationListener = null; + // listener for server connection. Receives notification if server connection goes down private ClientListener _clientListener = null; public JMXServerRegistry(ManagedServer server) throws Exception @@ -93,16 +104,23 @@ public class JMXServerRegistry extends ServerRegistry */ public void closeServerConnection() throws Exception { - if (_jmxc != null) - _jmxc.removeConnectionNotificationListener(_clientListener); - - if (_mbsc != null) - _mbsc.removeNotificationListener(_serverObjectName, _clientListener); - - // remove mbean notification listeners - for (String mbeanName : _subscribedNotificationMap.keySet()) + try + { + if (_jmxc != null) + _jmxc.removeConnectionNotificationListener(_clientListener); + + if (_mbsc != null) + _mbsc.removeNotificationListener(_serverObjectName, _clientListener); + + // remove mbean notification listeners + for (String mbeanName : _subscribedNotificationMap.keySet()) + { + _mbsc.removeNotificationListener(new ObjectName(mbeanName), _notificationListener); + } + } + catch (ListenerNotFoundException ex) { - _mbsc.removeNotificationListener(new ObjectName(mbeanName), _notificationListener); + System.out.println(ex.toString()); } } @@ -111,22 +129,32 @@ public class JMXServerRegistry extends ServerRegistry return _mbeansMap.get(uniqueName); } - public void addManagedObject(ManagedBean key) + public void addManagedObject(ManagedBean mbean) { - if (Constants.QUEUE.equals(key.getType())) - _queues.add(key.getName()); - else if (Constants.EXCHANGE.equals(key.getType())) - _exchanges.add(key.getName()); + if (Constants.QUEUE.equals(mbean.getType()) && !mbean.getName().startsWith("tmp_")) + { + addQueueMBean(mbean); + } + else if (Constants.EXCHANGE.equals(mbean.getType())) + { + addExchangeMBean(mbean); + } + else if (Constants.CONNECTION.equals(mbean.getType())) + { + addConnectionMBean(mbean); + } - _mbeansMap.put(key.getUniqueName(), key); + _mbeansMap.put(mbean.getUniqueName(), mbean); } public void removeManagedObject(ManagedBean mbean) { if (Constants.QUEUE.equals(mbean.getType())) - _queues.remove(mbean.getName()); + removeQueueMBean(mbean); else if (Constants.EXCHANGE.equals(mbean.getType())) - _exchanges.remove(mbean.getName()); + removeExchangeMBean(mbean); + else if (Constants.CONNECTION.equals(mbean.getType())) + removeConnectionMBean(mbean); _mbeansMap.remove(mbean.getUniqueName()); } @@ -140,6 +168,11 @@ public class JMXServerRegistry extends ServerRegistry return _mbeanInfoMap.get(mbean.getUniqueName()); } + public List<ManagedBean> getMBeans() + { + return new ArrayList<ManagedBean>(_mbeansMap.values()); + } + public void setNotificationInfo(ManagedBean mbean, List<NotificationInfoModel>value) { _notificationInfoMap.put(mbean.getUniqueName(), value); @@ -259,27 +292,15 @@ public class JMXServerRegistry extends ServerRegistry public void registerManagedObject(ObjectName objName) { JMXManagedObject managedObject = new JMXManagedObject(objName); + managedObject.setServer(getManagedServer()); - _mbeansToBeAdded.add(managedObject); + addManagedObject(managedObject); } public void unregisterManagedObject(ObjectName objName) { - JMXManagedObject managedObject = new JMXManagedObject(objName); - managedObject.setServer(getManagedServer()); - _mbeansToBeRemoved.add(managedObject); - } - - public List<ManagedBean> getObjectsToBeAdded() - { - if (_mbeansToBeAdded.isEmpty()) - return null; - else - { - List<ManagedBean> list = _mbeansToBeAdded; - _mbeansToBeAdded = new ArrayList<ManagedBean>(); - return list; - } + ManagedBean mbean = _mbeansMap.get(objName.toString()); + _mbeansToBeRemoved.add(mbean); } public List<ManagedBean> getObjectsToBeRemoved() @@ -316,12 +337,35 @@ public class JMXServerRegistry extends ServerRegistry public String[] getQueueNames() { - return _queues.toArray(new String[0]); + String[] queues = new String[_queues.size()]; + int i = 0; + for (ManagedBean mbean : _queues) + { + queues[i++] = mbean.getName(); + } + return queues; } public String[] getExchangeNames() { - return _exchanges.toArray(new String[0]); + String[] exchanges = new String[_exchanges.size()]; + int i = 0; + for (ManagedBean mbean : _exchanges) + { + exchanges[i++] = mbean.getName(); + } + return exchanges; + } + + public String[] getConnectionNames() + { + String[] connections = new String[_connections.size()]; + int i = 0; + for (ManagedBean mbean : _connections) + { + connections[i++] = mbean.getName(); + } + return connections; } public ClientNotificationListener getNotificationListener() diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java index 923fd4a12a..8334beeeb9 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java @@ -22,8 +22,10 @@ package org.apache.qpid.management.ui.jmx; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Iterator; import java.util.List; +import java.util.Set; import javax.management.Attribute; import javax.management.AttributeList; @@ -35,6 +37,7 @@ import javax.management.MBeanInfo; import javax.management.MBeanNotificationInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanServerConnection; +import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.ReflectionException; @@ -140,30 +143,30 @@ public class MBeanUtility { if (mbean == null) { - ViewUtility.popupErrorMessage("Error", ex.getMessage()); + ViewUtility.popupErrorMessage("Error", "Managed Object is null \n" + ex.toString()); } else if (ex instanceof IOException) { - ViewUtility.popupErrorMessage(mbean.getName(), ex.getMessage()); + ViewUtility.popupErrorMessage(mbean.getName(), "IO Error occured \n" + ex.toString()); } else if (ex instanceof ReflectionException) { - ViewUtility.popupErrorMessage(mbean.getName(), ex.getMessage()); + ViewUtility.popupErrorMessage(mbean.getName(), "Server has thrown error \n" + ex.toString()); } else if (ex instanceof InstanceNotFoundException) { - ViewUtility.popupErrorMessage(mbean.getName(), ex.getMessage()); + ViewUtility.popupErrorMessage(mbean.getName(), "Managed Object Not Found \n" + ex.toString()); } else if (ex instanceof MBeanException) { - String cause = ((MBeanException)ex).getTargetException().getMessage(); + String cause = ((MBeanException)ex).getTargetException().toString(); if (cause == null) - cause = ex.getMessage(); + cause = ex.toString(); ViewUtility.popupInfoMessage(mbean.getName(), cause); } else if (ex instanceof JMException) { - ViewUtility.popupErrorMessage(mbean.getName(), ex.getMessage()); + ViewUtility.popupErrorMessage(mbean.getName(), "Management Exception occured \n" + ex.toString()); } else if (ex instanceof ManagementConsoleException) { @@ -171,9 +174,9 @@ public class MBeanUtility } else { - ViewUtility.popupError(mbean.getName(), "Error occured", ex); + ViewUtility.popupErrorMessage(mbean.getName(), ex.toString()); } - //ex.printStackTrace(); + ex.printStackTrace(); } /** @@ -204,7 +207,36 @@ public class MBeanUtility serverRegistry.removeNotificationListener(mbean, name, type); } - public static int refreshAttribute(ManagedBean mbean, String attribute) throws Exception + /** + * Checks if the server registry contains attribute information for this mbean. If not then it queries the + * mbean server for complete mbean information, else it gets the latest value of the given attribute + * from mbean server. + * @return attribute data for the given mbean attribute + */ + public static AttributeData getAttributeData(ManagedBean mbean, String attribute) throws Exception + { + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean); + if (attributeModel == null) + { + // If process is here, it means the mbeanInfo is not retrieved from mbean server even once for this mbean + getMBeanInfo(mbean); + } + else + { + // refresh attribute value from mbean server + refreshAttribute(mbean, attribute); + } + attributeModel = serverRegistry.getAttributeModel(mbean); + return attributeModel.getAttribute(attribute); + } + + /** + * Retrieves the latest attribute value from mbean server for the given mbean attribute + * and also sets that value in the attribute model in the server registry + * @return latest attribute value for the given mbean attribute + */ + public static Object refreshAttribute(ManagedBean mbean, String attribute) throws Exception { JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); MBeanServerConnection mbsc = serverRegistry.getServerConnection(); @@ -215,10 +247,10 @@ public class MBeanUtility } Object value = mbsc.getAttribute(((JMXManagedObject)mbean).getObjectName(), attribute); - + // update the attribute data in server registry for this attribute ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean); attributeModel.setAttributeValue(attribute, value); - return Integer.parseInt(String.valueOf(value)); + return value; } /** @@ -237,9 +269,12 @@ public class MBeanUtility MBeanServerConnection mbsc = serverRegistry.getServerConnection(); MBeanAttributeInfo[] attributesInfo = null; ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean); - // If retrieving attributeInfo for the first time. + if (attributeModel == null) { + // If the process is here, then it means the attribute values are not retrieved from mbean server + // even once for this mbean. Create attribute model, retrieve values from mbean server and + // set the attribute model in server registry for this mbean attributeModel = new ManagedAttributeModel(); attributesInfo = serverRegistry.getMBeanInfo(mbean).getAttributes(); attributes = new String[attributesInfo.length]; @@ -311,8 +346,8 @@ public class MBeanUtility OperationDataModel dataModel = serverRegistry.getOperationModel(mbean); if (dataModel == null) { - MBeanInfo mbeanInfo = serverRegistry.getMBeanInfo(mbean); - MBeanOperationInfo[] operationsInfo = mbeanInfo.getOperations(); + // Create operation model and set it in server registry for this mbean + MBeanOperationInfo[] operationsInfo = serverRegistry.getMBeanInfo(mbean).getOperations(); dataModel = new OperationDataModel(); for (int i = 0; i < operationsInfo.length; i++) @@ -322,7 +357,6 @@ public class MBeanUtility serverRegistry.setOperationModel(mbean, dataModel); } - return dataModel; } @@ -333,15 +367,15 @@ public class MBeanUtility */ public static NotificationInfoModel[] getNotificationInfo(ManagedBean mbean) { - JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); MBeanNotificationInfo[] info = serverRegistry.getMBeanInfo(mbean).getNotifications(); + // Check if this mbean sends any notification if (info == null || info.length == 0) return null; + // Create notification model if not already set in the server registry for this mbean List<NotificationInfoModel> list = serverRegistry.getNotificationInfo(mbean); - if (list != null) return list.toArray(new NotificationInfoModel[0]); else @@ -351,8 +385,43 @@ public class MBeanUtility { list.add(new NotificationInfoModel(info[i].getName(), info[i].getDescription(), info[i].getNotifTypes())); } - serverRegistry.setNotificationInfo(mbean, list); + // Set the notification model in the server registry for this mbean + serverRegistry.setNotificationInfo(mbean, list); return list.toArray(new NotificationInfoModel[0]); } + + /** + * Retrieves all the MBeans from mbean server for a given domain + * @return list of ManagedBeans + */ + public static List<ManagedBean> getManagedObjectsForDomain(ManagedServer server, String domain) throws Exception + { + List<ManagedBean> mbeans = new ArrayList<ManagedBean>(); + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + ObjectName objName = new ObjectName(domain + ":*"); + Set objectInstances = mbsc.queryMBeans(objName, null); + + for (Iterator itr = objectInstances.iterator(); itr.hasNext();) + { + ObjectInstance instance = (ObjectInstance)itr.next(); + ManagedBean obj = new JMXManagedObject(instance.getObjectName()); + mbeans.add(obj); + } + + return mbeans; + } + + /** + * Returns all the domains for the given server. This method can be removed as now this RCP is specific to + * Qpid and domain is also fixed + */ + public static List<String> getAllDomains(ManagedServer server) throws Exception + { + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + String[] domains = mbsc.getDomains(); + return Arrays.asList(domains); + } } diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.java index 692e72fc5a..b3219f15ea 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.java @@ -106,6 +106,11 @@ public class ManagedAttributeModel return _attributeMap.values().toArray(new AttributeData[0]); } + public AttributeData getAttribute(String name) + { + return _attributeMap.get(name); + } + public int getCount() { return _attributeMap.size(); diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java index 36e808a043..8bf4e30c64 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java @@ -126,7 +126,7 @@ public class AttributesTabControl extends TabControl _tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); _tableComposite.setLayout(new GridLayout()); _buttonsComposite = _toolkit.createComposite(_form.getBody()); - _tableComposite.setLayoutData(new GridData()); + _buttonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true)); _buttonsComposite.setLayout(new GridLayout()); image = Display.getCurrent().getSystemImage(SWT.ICON_INFORMATION); @@ -175,7 +175,6 @@ public class AttributesTabControl extends TabControl /** * Creates tableviewer for the attribute's table - * */ private void createTableViewer() { @@ -200,7 +199,7 @@ public class AttributesTabControl extends TabControl // Create and configure the button for attribute details _detailsButton = _toolkit.createButton(_buttonsComposite, Constants.BUTTON_DETAILS, SWT.PUSH | SWT.CENTER); _detailsButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); - GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false); + GridData gridData = new GridData(SWT.CENTER, SWT.TOP, false, false); gridData.widthHint = 80; _detailsButton.setLayoutData(gridData); _detailsButton.addSelectionListener(new SelectionAdapter() @@ -225,7 +224,7 @@ public class AttributesTabControl extends TabControl // Create and configure the button for editing attribute _editButton = _toolkit.createButton(_buttonsComposite, Constants.BUTTON_EDIT_ATTRIBUTE, SWT.PUSH | SWT.CENTER); _editButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); - GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false); + GridData gridData = new GridData(SWT.CENTER, SWT.TOP, false, false); gridData.widthHint = 80; _editButton.setLayoutData(gridData); _editButton.addSelectionListener(new SelectionAdapter() @@ -247,7 +246,7 @@ public class AttributesTabControl extends TabControl { _graphButton = _toolkit.createButton(_buttonsComposite, Constants.BUTTON_GRAPH, SWT.PUSH | SWT.CENTER); _graphButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); - GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false); + GridData gridData = new GridData(SWT.CENTER, SWT.TOP, false, false); gridData.widthHint = 80; _graphButton.setLayoutData(gridData); _graphButton.addSelectionListener(new SelectionAdapter() @@ -270,7 +269,7 @@ public class AttributesTabControl extends TabControl _refreshButton = _toolkit.createButton(_buttonsComposite, Constants.BUTTON_REFRESH, SWT.PUSH | SWT.CENTER); _refreshButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); - GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false); + GridData gridData = new GridData(SWT.CENTER, SWT.TOP, false, false); gridData.widthHint = 80; _refreshButton.setLayoutData(gridData); _refreshButton.addSelectionListener(new SelectionAdapter() @@ -429,12 +428,14 @@ public class AttributesTabControl extends TabControl } Display display = Display.getCurrent(); - Shell shell = ViewUtility.createPopupShell("Attribute", width, height); + Shell shell = ViewUtility.createPopupShell(Constants.ATTRIBUTE, width, height); createDetailsPopupContents(shell, data); shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { + while (!shell.isDisposed()) + { + if (!display.readAndDispatch()) + { display.sleep(); } } @@ -818,7 +819,8 @@ public class AttributesTabControl extends TabControl private void animate(Canvas canvas, AttributeData data) throws Exception { String attribute = data.getName(); - int value = MBeanUtility.refreshAttribute(_mbean, attribute); + Object valueObj = MBeanUtility.refreshAttribute(_mbean, attribute); + int value = Integer.parseInt(String.valueOf(valueObj)); Object canvasData = canvas.getData(GRAPH_VALUES); long[] graphValues = (long[]) canvasData; diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java new file mode 100644 index 0000000000..73d56634ec --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java @@ -0,0 +1,327 @@ +package org.apache.qpid.management.ui.views; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ServerRegistry; +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.apache.qpid.management.ui.model.AttributeData; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.forms.widgets.Form; +import org.eclipse.ui.forms.widgets.FormToolkit; + +/** + * Class to create widgets and control display for mbeantype(eg Connection, Queue, Exchange) selection + * on the navigation view. + * @author Bhupendra Bhardwaj + * + */ +public class MBeanTypeTabControl +{ + private FormToolkit _toolkit = null; + private Form _form = null; + private TabFolder _tabFolder = null; + private Composite _composite = null; + private Composite _listComposite = null; + private Composite _buttonsComposite = null; + private Label _labelName = null; + private Label _labelDesc = null; + private Label _labelList = null; + + private org.eclipse.swt.widgets.List _list = null; + private Button _refreshButton = null; + private Button _addButton = null; + private Button _sortBySizeButton = null; + + private String _type = null; + + // maps an mbean name with the mbean object. Required to get mbean object when an mbean + // is to be added to the navigation view. + private HashMap<String, ManagedBean> _objectsMap = new HashMap<String, ManagedBean>(); + // Map required for sorting queues based on attribute values + private Map<AttributeData, ManagedBean> _queueMap = new LinkedHashMap<AttributeData, ManagedBean>(); + + private Sorter _sorterByName = new Sorter(); + private ComparatorImpl _sorterByQueueDepth = new ComparatorImpl(); + + public MBeanTypeTabControl(TabFolder tabFolder) + { + _tabFolder = tabFolder; + _toolkit = new FormToolkit(_tabFolder.getDisplay()); + _form = _toolkit.createForm(_tabFolder); + createWidgets(); + addListeners(); + } + + public Control getControl() + { + return _form; + } + + /** + * Adds listeners to all the buttons + */ + private void addListeners() + { + _addButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e) + { + if (_list.getSelectionCount() == 0) + return; + + String[] selectedItems = _list.getSelection(); + for (int i = 0; i < selectedItems.length; i++) + { + String name = selectedItems[i];; + if (Constants.QUEUE.equals(_type)) + { + int endIndex = name.lastIndexOf("("); + name = name.substring(0, endIndex -1); + } + // pass the ManagedBean to the navigation view to be added + ManagedBean mbean = _objectsMap.get(name); + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + NavigationView view = (NavigationView)window.getActivePage().findView(NavigationView.ID); + try + { + view.addManagedBean(mbean); + } + catch (Exception ex) + { + MBeanUtility.handleException(mbean, ex); + } + } + } + }); + + _refreshButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e) + { + try + { + refresh(_type); + } + catch (Exception ex) + { + MBeanUtility.handleException(ex); + } + } + }); + + _sortBySizeButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e) + { + try + { + sortQueueByQueueDepth(); + } + catch (Exception ex) + { + MBeanUtility.handleException(ex); + } + } + }); + } + + private void createWidgets() + { + _form.getBody().setLayout(new GridLayout()); + _composite = _toolkit.createComposite(_form.getBody(), SWT.NONE); + _composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout layout = new GridLayout(2, true); + layout.verticalSpacing = 10; + layout.horizontalSpacing = 0; + _composite.setLayout(layout); + + _labelName = _toolkit.createLabel(_composite, "Type:", SWT.NONE); + GridData gridData = new GridData(SWT.CENTER, SWT.TOP, true, false, 2, 1); + _labelName.setLayoutData(gridData); + _labelName.setFont(ApplicationRegistry.getFont(Constants.FONT_BOLD)); + + _labelDesc = _toolkit.createLabel(_composite, " ", SWT.NONE); + _labelDesc.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false, 2, 1)); + _labelDesc.setFont(ApplicationRegistry.getFont(Constants.FONT_ITALIC)); + + _addButton = _toolkit.createButton(_composite, "<- Add to Navigation", SWT.PUSH); + gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false); + _addButton.setLayoutData(gridData); + + _refreshButton = _toolkit.createButton(_composite, Constants.BUTTON_REFRESH, SWT.PUSH); + gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false); + gridData.widthHint = 80; + _refreshButton.setLayoutData(gridData); + + // Composite to contain the item list + _listComposite = _toolkit.createComposite(_composite); + gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + _listComposite.setLayoutData(gridData); + layout = new GridLayout(); + layout.verticalSpacing = 0; + _listComposite.setLayout(layout); + + // Label for item name + _labelList = _toolkit.createLabel(_listComposite, " ", SWT.NONE); + _labelList.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false)); + _labelList.setFont(ApplicationRegistry.getFont(Constants.FONT_NORMAL)); + + _list = new List(_listComposite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + _list.setLayoutData(gridData); + + + // Composite to contain buttons like - Sort by size + _buttonsComposite = _toolkit.createComposite(_composite); + gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + _buttonsComposite.setLayoutData(gridData); + _buttonsComposite.setLayout(new GridLayout()); + + _sortBySizeButton = _toolkit.createButton(_buttonsComposite, "Sort by Queue Depth", SWT.PUSH); + gridData = new GridData(SWT.CENTER, SWT.CENTER, true, false); + _sortBySizeButton.setLayoutData(gridData); + + } + + public void refresh(String typeName) throws Exception + { + _type = typeName; + setHeader(); + populateList(); + + _listComposite.layout(); + _composite.layout(); + _form.layout(); + } + + private void setHeader() + { + _labelName.setText("Type : " + _type); + _labelDesc.setText("Select the " + _type + "(s) to add in the Navigation View"); + _labelList.setText("-- List of " + _type + "s --"); + } + + /** + * populates the map with mbean name and the mbean object. + * @throws Exception + */ + private void populateList() throws Exception + { + // map should be cleared before populating it with new values + _objectsMap.clear(); + _queueMap.clear(); + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer()); + String[] items = null; + java.util.List<ManagedBean> list = null; + + // populate the map and list with appropriate mbeans + if (_type.equals(Constants.QUEUE)) + { + list = serverRegistry.getQueues(); + items = getQueueItems(list); + _sortBySizeButton.setVisible(true); + } + else if (_type.equals(Constants.EXCHANGE)) + { + list = serverRegistry.getExchanges(); + items = getItems(list); + _sortBySizeButton.setVisible(false); + } + else if (_type.equals(Constants.CONNECTION)) + { + list = serverRegistry.getConnections(); + items = getItems(list); + _sortBySizeButton.setVisible(false); + } + else + { + throw new Exception("Unknown mbean type " + _type); + } + + _list.setItems(items); + } + + // sets the map with appropriate mbean and name + private String[] getItems(java.util.List<ManagedBean> list) + { + Collections.sort(list, _sorterByName); + String[] items = new String[list.size()]; + int i = 0; + for (ManagedBean mbean : list) + { + items[i++] = mbean.getName(); + _objectsMap.put(mbean.getName(), mbean); + } + return items; + } + + private String[] getQueueItems(java.util.List<ManagedBean> list) throws Exception + { + // Sort the list. It will keep the mbeans in sorted order in the _queueMap, which is required for + // sorting the queue according to size etc + Collections.sort(list, _sorterByName); + String[] items = new String[list.size()]; + int i = 0; + for (ManagedBean mbean : list) + { + AttributeData data = MBeanUtility.getAttributeData(mbean, Constants.ATTRIBUTE_QUEUE_DEPTH); + String value = data.getValue().toString(); + items[i] = mbean.getName() + " (" + value + " KB)"; + _objectsMap.put(mbean.getName(), mbean); + _queueMap.put(data, mbean); + i++; + } + return items; + } + + private void sortQueueByQueueDepth() throws Exception + { + // Queues are already in the alphabetically sorted order in _queueMap, now sort for queueDepth + java.util.List<AttributeData> list = new ArrayList<AttributeData>(_queueMap.keySet()); + Collections.sort(list, _sorterByQueueDepth); + + String[] items = new String[list.size()]; + int i = 0; + for (AttributeData data : list) + { + ManagedBean mbean = _queueMap.get(data); + String value = data.getValue().toString(); + items[i++] = mbean.getName() + " (" + value + " KB)"; + } + _list.setItems(items); + } + + private class ComparatorImpl implements java.util.Comparator<AttributeData> + { + public int compare(AttributeData data1, AttributeData data2) + { + Integer int1 = Integer.parseInt(data1.getValue().toString()); + Integer int2 = Integer.parseInt(data2.getValue().toString()); + return int1.compareTo(int2) * -1; + } + } + + private class Sorter implements java.util.Comparator<ManagedBean> + { + public int compare(ManagedBean mbean1, ManagedBean mbean2) + { + return mbean1.getName().compareTo(mbean2.getName()); + } + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java index 4b044c2e13..62871c4c91 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java @@ -25,8 +25,9 @@ import java.util.HashMap; import org.apache.qpid.management.ui.ApplicationRegistry; import org.apache.qpid.management.ui.Constants; import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ManagedServer; +import org.apache.qpid.management.ui.ServerRegistry; import org.apache.qpid.management.ui.exceptions.InfoRequiredException; -import org.apache.qpid.management.ui.jmx.JMXServerRegistry; import org.apache.qpid.management.ui.jmx.MBeanUtility; import org.apache.qpid.management.ui.model.AttributeData; import org.apache.qpid.management.ui.model.OperationData; @@ -38,7 +39,6 @@ import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.TabFolder; @@ -49,14 +49,22 @@ import org.eclipse.ui.forms.widgets.Form; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.part.ViewPart; - +/** + * MBean View create appropriate view based on the user selection on the Navigation View. + * Create TabFolder for all MBeans and displays the attribtues and method tabs. + * @author Bhupendra Bhardwaj + * + */ public class MBeanView extends ViewPart { public static final String ID = "org.apache.qpid.management.ui.mbeanView"; private FormToolkit _toolkit = null; private Form _form = null; + private static ManagedServer _server = null; + private TreeObject _selectedNode = null; private ManagedBean _mbean = null; + // This map contains a TabFolder for each kind of MBean. TabFolder is mapped with mbeantype(eg Connection, Queue etc) private HashMap<String, TabFolder> tabFolderMap = new HashMap<String, TabFolder>(); private ISelectionListener selectionListener = new SelectionListenerImpl(); @@ -64,7 +72,8 @@ public class MBeanView extends ViewPart private static final String OPERATIONS_CONTROL = "OperationsTabControl"; private static final String NOTIFICATIONS_CONTROL = "NotificationsTabControl"; - + // TabFolder to list all the mbeans for a given mbeantype(eg Connection, Queue, Exchange) + private TabFolder typeTabFolder = null; /* * Listener for the selection events in the navigation view */ @@ -76,37 +85,89 @@ public class MBeanView extends ViewPart return; IStructuredSelection ss = (IStructuredSelection) sel; - TreeObject node = (TreeObject)ss.getFirstElement(); - showSelectedMBean(node); + _selectedNode = (TreeObject)ss.getFirstElement(); + + + // mbean should be set to null. A selection done on the navigation view can be either an mbean or + // an mbeantype. For mbeantype selection(eg Connection, Queue, Exchange) _mbean will remain null. + _mbean = null; + setInvisible(); + _form.setText(Constants.APPLICATION_NAME); + + // If a selected node(mbean) gets unregistered from mbena server, mbenaview should should + // make the tabfolber for that mbean invisible + if (_selectedNode == null) + return; + + setServer(); + try + { + if (Constants.TYPE.equals(_selectedNode.getType())) + { + refreshTypeTabFolder(_selectedNode.getName()); + } + else if (Constants.DOMAIN.equals(_selectedNode.getType())) + { + refreshTypeTabFolder(typeTabFolder.getItem(0)); + } + else + { + showSelectedMBean(); + } + _form.layout(); + } + catch(Exception ex) + { + MBeanUtility.handleException(_mbean, ex); + } } } - public void showSelectedMBean(TreeObject node) + /** + * Sets the managedServer based on the selection in the navigation view + * At any given time MBeanView will be displaying information for an mbean of mbeantype + * for a specifiv managed server. This server information will be used by the tab controllers + * to get server registry. + */ + private void setServer() { - _mbean = null; - setInvisible(); - - if (node == null) + if (Constants.SERVER.equals(_selectedNode.getType())) { - _form.setText(Constants.APPLICATION_NAME); - return; + _server = (ManagedServer)_selectedNode.getManagedObject(); } - - if (Constants.NOTIFICATION.equals(node.getType())) + else { - _mbean = (ManagedBean)node.getParent().getManagedObject(); + TreeObject parent = _selectedNode.getParent(); + while (parent != null && !parent.getType().equals(Constants.SERVER)) + { + parent = parent.getParent(); + } + + if (parent != null && parent.getType().equals(Constants.SERVER)) + _server = (ManagedServer)parent.getManagedObject(); } - else if (Constants.MBEAN.equals(node.getType())) + } + + public static ManagedServer getServer() + { + return _server; + } + + private void showSelectedMBean() throws Exception + { + if (Constants.NOTIFICATION.equals(_selectedNode.getType())) + { + _mbean = (ManagedBean)_selectedNode.getParent().getManagedObject(); + } + else if (Constants.MBEAN.equals(_selectedNode.getType())) { - _mbean = (ManagedBean)node.getManagedObject(); + _mbean = (ManagedBean)_selectedNode.getManagedObject(); } else { - _form.setText(Constants.APPLICATION_NAME); return; } - setFocus(); try { MBeanUtility.getMBeanInfo(_mbean); @@ -130,20 +191,17 @@ public class MBeanView extends ViewPart } _form.setText(text); int tabIndex = 0; - if (Constants.NOTIFICATION.equals(node.getType())) + if (Constants.NOTIFICATION.equals(_selectedNode.getType())) { tabIndex = tabFolder.getItemCount() -1; } TabItem tab = tabFolder.getItem(tabIndex); - // refreshTab(tab); // If folder is being set as visible after tab refresh, then the tab - // doesn't have the focus. - + // doesn't have the focus. tabFolder.setSelection(tabIndex); refreshTab(tab); setVisible(tabFolder); - _form.layout(); } public void createPartControl(Composite parent) @@ -156,23 +214,38 @@ public class MBeanView extends ViewPart // Add selection listener for selection events in the Navigation view getSite().getPage().addSelectionListener(NavigationView.ID, selectionListener); + + // Add mbeantype TabFolder. This will list all the mbeans under a mbeantype (eg Queue, Exchange). + // Using this list mbeans will be added in the navigation view + createTypeTabFolder(); } - public void refreshMBeanView() + public void refreshMBeanView() throws Exception { + int tabIndex = 0; + TabItem tab = null; if (_mbean == null) - return; - - TabFolder tabFolder = tabFolderMap.get(_mbean.getType()); - if (tabFolder == null) - return; - - int index = tabFolder.getSelectionIndex(); - TabItem tab = tabFolder.getItem(index); - if (tab == null) - return; - - refreshTab(tab); + { + tabIndex = typeTabFolder.getSelectionIndex(); + if (tabIndex == -1) + return; + + tab = typeTabFolder.getItem(tabIndex); + refreshTypeTabFolder(tab); + } + else + { + TabFolder tabFolder = tabFolderMap.get(_mbean.getType()); + if (tabFolder == null) + return; + + tabIndex = tabFolder.getSelectionIndex(); + tab = tabFolder.getItem(tabIndex); + if (tab == null) + return; + + refreshTab(tab); + } _form.layout(); } @@ -185,7 +258,6 @@ public class MBeanView extends ViewPart layoutData.right = new FormAttachment(100); layoutData.bottom = new FormAttachment(100); tabFolder.setLayoutData(layoutData); - tabFolder.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); tabFolder.setVisible(false); createAttributesTab(tabFolder); @@ -201,7 +273,7 @@ public class MBeanView extends ViewPart } }); - tabFolderMap.put(_mbean.getType(), tabFolder); + tabFolderMap.put(_mbean.getType(), tabFolder); return tabFolder; } @@ -209,7 +281,7 @@ public class MBeanView extends ViewPart { // We can avoid refreshing the attributes tab because it's control // already contains the required values. But it is added for now and - // will remove if there is any perfornce or any such issue. + // will remove if there is any performance issue or any other issue. // The operations control should be refreshed because there is only one // controller for all operations tab. // The Notifications control needs to refresh with latest set of notifications @@ -218,6 +290,7 @@ public class MBeanView extends ViewPart return; TabFolder tabFolder = tab.getParent(); + // If an operation tab is selected, the operation data is attached with the tab if (tab.getData() != null && (tab.getData() instanceof OperationData)) { // Refresh selected operation tab @@ -259,7 +332,7 @@ public class MBeanView extends ViewPart private void createAttributesTab(TabFolder tabFolder) { - JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_mbean); + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); if (serverRegistry.getAttributeModel(_mbean).getCount() == 0) { return; @@ -269,12 +342,12 @@ public class MBeanView extends ViewPart tab.setText(Constants.ATTRIBUTES); AttributesTabControl control = new AttributesTabControl(tabFolder); tab.setControl(control.getControl()); - tabFolder.setData(ATTRIBUTES_CONTROL, control); + tabFolder.setData(ATTRIBUTES_CONTROL, control); } private void createOperationTabs(TabFolder tabFolder) { - JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_mbean); + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); int operationsCount = serverRegistry.getOperationModel(_mbean).getCount(); if (operationsCount == 0) { @@ -314,7 +387,7 @@ public class MBeanView extends ViewPart throw new InfoRequiredException("Please select the managed object and then attribute to be edited"); String name = (_mbean.getName() != null) ? _mbean.getName() : _mbean.getType(); - JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_mbean); + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); if (serverRegistry.getAttributeModel(_mbean).getCount() == 0) { throw new InfoRequiredException("There are no attributes to be edited for " + name); @@ -336,6 +409,85 @@ public class MBeanView extends ViewPart tabControl.createDetailsPopup(attribute); } + /** + * Creates TabFolder and tabs for each mbeantype (eg Connection, Queue, Exchange) + */ + private void createTypeTabFolder() + { + typeTabFolder = new TabFolder(_form.getBody(), SWT.NONE); + FormData layoutData = new FormData(); + layoutData.left = new FormAttachment(0); + layoutData.top = new FormAttachment(0); + layoutData.right = new FormAttachment(100); + layoutData.bottom = new FormAttachment(100); + typeTabFolder.setLayoutData(layoutData); + typeTabFolder.setVisible(false); + + MBeanTypeTabControl controller = new MBeanTypeTabControl(typeTabFolder); + typeTabFolder.setData("CONTROLLER", controller); + + TabItem tab = new TabItem(typeTabFolder, SWT.NONE); + tab.setText(Constants.CONNECTION); + tab.setControl(controller.getControl()); + + tab = new TabItem(typeTabFolder, SWT.NONE); + tab.setText(Constants.EXCHANGE); + tab.setControl(controller.getControl()); + + tab = new TabItem(typeTabFolder, SWT.NONE); + tab.setText(Constants.QUEUE); + tab.setControl(controller.getControl()); + + typeTabFolder.addListener(SWT.Selection, new Listener() + { + public void handleEvent(Event evt) + { + TabItem tab = (TabItem)evt.item; + try + { + refreshTypeTabFolder(tab); + } + catch (Exception ex) + { + MBeanUtility.handleException(ex); + } + } + }); + } + + /** + * Refreshes the Selected mbeantype tab. The control lists all the available mbeans + * for an mbeantype(eg Queue, Exchange etc) + * @param tab + * @throws Exception + */ + private void refreshTypeTabFolder(TabItem tab) throws Exception + { + if (tab == null) + { + return; + } + typeTabFolder.setSelection(tab); + MBeanTypeTabControl controller = (MBeanTypeTabControl)typeTabFolder.getData("CONTROLLER"); + controller.refresh(tab.getText()); + typeTabFolder.setVisible(true); + } + + private void refreshTypeTabFolder(String type) throws Exception + { + if (Constants.CONNECTION.equals(type)) + { + refreshTypeTabFolder(typeTabFolder.getItem(0)); + } + else if (Constants.EXCHANGE.equals(type)) + { + refreshTypeTabFolder(typeTabFolder.getItem(1)); + } + else if (Constants.QUEUE.equals(type)) + { + refreshTypeTabFolder(typeTabFolder.getItem(2)); + } + } /** * hides other folders and makes the given one visible. @@ -358,6 +510,11 @@ public class MBeanView extends ViewPart { folder.setVisible(false); } + + if (typeTabFolder != null) + { + typeTabFolder.setVisible(false); + } } } diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java index 4319a4bd10..619aa06598 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java @@ -28,13 +28,7 @@ import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.List; -import java.util.Set; - -import javax.management.MBeanServerConnection; -import javax.management.ObjectInstance; -import javax.management.ObjectName; import org.apache.qpid.management.ui.ApplicationRegistry; import org.apache.qpid.management.ui.Constants; @@ -42,8 +36,9 @@ import org.apache.qpid.management.ui.ManagedBean; import org.apache.qpid.management.ui.ManagedServer; import org.apache.qpid.management.ui.ServerRegistry; import org.apache.qpid.management.ui.exceptions.InfoRequiredException; -import org.apache.qpid.management.ui.jmx.JMXManagedObject; +import org.apache.qpid.management.ui.exceptions.ManagementConsoleException; import org.apache.qpid.management.ui.jmx.JMXServerRegistry; +import org.apache.qpid.management.ui.jmx.MBeanUtility; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IFontProvider; @@ -64,7 +59,11 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.part.ViewPart; - +/** + * Navigation View for navigating the managed servers and managed beans on + * those servers + * @author Bhupendra Bhardwaj + */ public class NavigationView extends ViewPart { public static final String ID = "org.apache.qpid.management.ui.navigationView"; @@ -73,8 +72,6 @@ public class NavigationView extends ViewPart private TreeViewer _treeViewer = null; private TreeObject _rootNode = null; private TreeObject _serversRootNode = null; - // List of all server nodes (connecged or removed) - //private List<TreeObject> _serverNodeList = new ArrayList<TreeObject>(); // Map of connected servers private HashMap<ManagedServer, TreeObject> _managedServerMap = new HashMap<ManagedServer, TreeObject>(); @@ -98,6 +95,9 @@ public class NavigationView extends ViewPart createListeners(); } + /** + * Creates listeners for the JFace treeviewer + */ private void createListeners() { _treeViewer.addDoubleClickListener(new IDoubleClickListener() @@ -132,12 +132,17 @@ public class NavigationView extends ViewPart }); } + /** + * Creates Qpid Server connection using JMX RMI protocol + * @param server + * @throws Exception + */ private void createRMIServerConnection(ManagedServer server) throws Exception { try { // Currently Qpid Management Console only supports JMX MBeanServer - JMXServerRegistry serverRegistry = new JMXServerRegistry(server); + ServerRegistry serverRegistry = new JMXServerRegistry(server); ApplicationRegistry.addServer(server, serverRegistry); } catch(Exception ex) @@ -151,14 +156,24 @@ public class NavigationView extends ViewPart return "service:jmx:rmi:///jndi/rmi://" + host + "/jmxrmi"; } - + /** + * Adds a new server node in the navigation view if server connection is successful. + * @param transportProtocol + * @param host + * @param port + * @param domain + * @throws Exception + */ public void addNewServer(String transportProtocol, String host, String port, String domain) throws Exception { + String serverAddress = host + ":" + port; + String url = null; + ManagedServer managedServer = null; + if ("RMI".equals(transportProtocol)) - { - String serverAddress = host + ":" + port; - String url = getRMIURL(serverAddress); + { + url = getRMIURL(serverAddress); List<TreeObject> list = _serversRootNode.getChildren(); for (TreeObject node : list) { @@ -166,30 +181,36 @@ public class NavigationView extends ViewPart throw new InfoRequiredException("Server " + serverAddress + " is already added"); } - ManagedServer managedServer = new ManagedServer(url, domain); + managedServer = new ManagedServer(url, domain); managedServer.setName(serverAddress); - createRMIServerConnection(managedServer); - - // RMI server connection is successful. Now add the server in the tree - TreeObject serverNode = new TreeObject(serverAddress, Constants.SERVER); - serverNode.setUrl(url); - serverNode.setManagedObject(managedServer); - _serversRootNode.addChild(serverNode); - - // Add server in the connected server map - _managedServerMap.put(managedServer, serverNode); - populateServer(serverNode); - _treeViewer.refresh(); - - // save server address in file - addServerAddressInFile(serverAddress); + createRMIServerConnection(managedServer); } else { throw new InfoRequiredException(transportProtocol + " transport is not supported"); } + + // Server connection is successful. Now add the server in the tree + TreeObject serverNode = new TreeObject(serverAddress, Constants.SERVER); + serverNode.setUrl(url); + serverNode.setManagedObject(managedServer); + _serversRootNode.addChild(serverNode); + + // Add server in the connected server map + _managedServerMap.put(managedServer, serverNode); + populateServer(serverNode); + _treeViewer.refresh(); + + // save server address in file + addServerAddressInFile(serverAddress); } + /** + * Server addresses are stored in a file. When user launches the application again, the + * server addresses are picked up from the file and shown in the navigfation view. This method + * adds the server address in a file, when a new server is added in the navigation view. + * @param serverAddress + */ private void addServerAddressInFile(String serverAddress) { File file = new File(INI_FILENAME); @@ -210,11 +231,14 @@ public class NavigationView extends ViewPart } } - + /** + * Queries the qpid server for MBeans and populates the navigation view with all MBeans for + * the given server node. + * @param serverNode + */ private void populateServer(TreeObject serverNode) { ManagedServer server = (ManagedServer)serverNode.getManagedObject(); - JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); String domain = server.getDomain(); try { @@ -228,11 +252,10 @@ public class NavigationView extends ViewPart else { List<TreeObject> domainList = new ArrayList<TreeObject>(); - MBeanServerConnection mbsc = serverRegistry.getServerConnection(); - String[] domains = mbsc.getDomains(); - for (int i = 0; i < domains.length; i++) + List<String> domains = MBeanUtility.getAllDomains(server);; + for (String domainName : domains) { - TreeObject domainNode = new TreeObject(domains[i], Constants.DOMAIN); + TreeObject domainNode = new TreeObject(domainName, Constants.DOMAIN); domainNode.setParent(serverNode); domainList.add(domainNode); @@ -247,80 +270,118 @@ public class NavigationView extends ViewPart } } + /** + * Queries the Qpid Server and populates the given domain node with all MBeans undser that domain. + * @param domain + * @throws IOException + * @throws Exception + */ @SuppressWarnings("unchecked") private void populateDomain(TreeObject domain) throws IOException, Exception { ManagedServer server = (ManagedServer)domain.getParent().getManagedObject(); - JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); - String domainName = domain.getName(); - MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + // Add these three types - Connection, Exchange, Queue + // By adding these, these will always be available, even if there are no mbeans under thse types + // This is required because, the mbeans will be added from mbeanview, by selecting from the list + TreeObject typeChild = new TreeObject(Constants.CONNECTION, Constants.TYPE); + typeChild.setParent(domain); + typeChild = new TreeObject(Constants.EXCHANGE, Constants.TYPE); + typeChild.setParent(domain); + typeChild = new TreeObject(Constants.QUEUE, Constants.TYPE); + typeChild.setParent(domain); - - ObjectName objName = new ObjectName(domainName + ":*"); - Set queryMBeans = mbsc.queryMBeans(objName, null); - final Set<ObjectInstance> objectInstances = queryMBeans; - - for (Iterator<ObjectInstance> itr = objectInstances.iterator(); itr.hasNext();) + + // Now populate the mbenas under those types + List<ManagedBean> mbeans = MBeanUtility.getManagedObjectsForDomain(server, domain.getName()); + for (ManagedBean mbean : mbeans) { - ObjectInstance instance = itr.next(); - ManagedBean obj = new JMXManagedObject(instance.getObjectName()); - obj.setServer(server); - addManagedBean(domain, obj); + mbean.setServer(server); + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(server); + serverRegistry.addManagedObject(mbean); + + // Add all mbeans other than Connections, Exchanges and Queues. Because these will be added + // manually by selecting from MBeanView + if (!(mbean.getType().equals(Constants.CONNECTION) || mbean.getType().equals(Constants.EXCHANGE) || mbean.getType().equals(Constants.QUEUE))) + { + addManagedBean(domain, mbean); + } } } - private TreeObject getIfTypeAlreadyExists(TreeObject domain, String type) + /** + * Checks if a particular mbeantype is already there in the navigation view for a domain. + * This is used while populating domain with mbeans. + * @param domain + * @param typeName + * @return Node if given mbeantype already exists, otherwise null + */ + private TreeObject getMBeanTypeNode(TreeObject domain, String typeName) { - List<TreeObject> types = domain.getChildren(); + List<TreeObject> childNodes = domain.getChildren(); - for (TreeObject child : types) + for (TreeObject child : childNodes) { - if (Constants.TYPE.equals(child.getType()) && type.equals(child.getName())) + if (Constants.TYPE.equals(child.getType()) && typeName.equals(child.getName())) return child; } return null; } - private void addManagedBean(TreeObject domain, ManagedBean obj) + private boolean doesMBeanNodeAlreadyExist(TreeObject typeNode, String mbeanName) { - ManagedServer server = (ManagedServer)domain.getParent().getManagedObject(); - JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); - serverRegistry.addManagedObject(obj); - - String type = obj.getType(); - String name = obj.getName(); + List<TreeObject> childNodes = typeNode.getChildren(); + for (TreeObject child : childNodes) + { + if (Constants.MBEAN.equals(child.getType()) && mbeanName.equals(child.getName())) + return true; + } + return false; + } + + /** + * Adds the given MBean to the given domain node. Creates Notification node for the MBean. + * @param domain + * @param mbean mbean + */ + private void addManagedBean(TreeObject domain, ManagedBean mbean) throws Exception + { + String type = mbean.getType(); + String name = mbean.getName(); + + TreeObject typeNode = getMBeanTypeNode(domain, type); + if (typeNode != null && doesMBeanNodeAlreadyExist(typeNode, name)) + return; - TreeObject typeChild = getIfTypeAlreadyExists(domain, type); TreeObject mbeanNode = null; - if (typeChild != null) // if type is already added as a TreeItem + if (typeNode != null) // type node already exists { if (name == null) { - System.out.println("Two mbeans can't exist without a name and with same type"); - return; + throw new ManagementConsoleException("Two mbeans can't exist without a name and with same type"); } - mbeanNode = new TreeObject(obj); - mbeanNode.setParent(typeChild); + mbeanNode = new TreeObject(mbean); + mbeanNode.setParent(typeNode); } else { - if (name != null) // An managedObject with type and name + // type node does not exist. Now check if node to be created as mbeantype or MBean + if (name != null) // A managedObject with type and name { - typeChild = new TreeObject(type, Constants.TYPE); - typeChild.setParent(domain); - mbeanNode = new TreeObject(obj); - mbeanNode.setParent(typeChild); + typeNode = new TreeObject(type, Constants.TYPE); + typeNode.setParent(domain); + mbeanNode = new TreeObject(mbean); + mbeanNode.setParent(typeNode); } - else // An managedObject with only type + else // A managedObject with only type { - mbeanNode = new TreeObject(obj); + mbeanNode = new TreeObject(mbean); mbeanNode.setParent(domain); } } // Add notification node - // TODO: show this only of the mbean sends any notification + // TODO: show this only if the mbean sends any notification TreeObject notificationNode = new TreeObject(Constants.NOTIFICATION, Constants.NOTIFICATION); notificationNode.setParent(mbeanNode); } @@ -373,6 +434,9 @@ public class NavigationView extends ViewPart } + /** + * Closes the Qpid server connection + */ public void disconnect() throws Exception { TreeObject selectedNode = getSelectedServerNode(); @@ -408,6 +472,11 @@ public class NavigationView extends ViewPart _treeViewer.refresh(); } + /** + * Closes the Qpid server connection if not already closed and removes the server node from the navigation view and + * also from the ini file stored in the system. + * @throws Exception + */ public void removeServer() throws Exception { disconnect(); @@ -430,7 +499,6 @@ public class NavigationView extends ViewPart list.remove(objectToRemove); } - //_serverNodeList.remove(objectToRemove); _treeViewer.refresh(); // Remove from the ini file @@ -445,6 +513,10 @@ public class NavigationView extends ViewPart out.close(); } + /** + * @return the server addresses from the ini file + * @throws Exception + */ private List<String> getServerListFromFile() throws Exception { BufferedReader in = new BufferedReader(new FileReader(INI_FILENAME)); @@ -538,6 +610,9 @@ public class NavigationView extends ViewPart _treeViewer.refresh(); } + /** + * Content provider class for the tree viewer + */ private class ContentProviderImpl implements ITreeContentProvider { public Object[] getElements(Object parent) @@ -574,6 +649,9 @@ public class NavigationView extends ViewPart } } + /** + * Label provider class for the tree viewer + */ private class LabelProviderImpl extends LabelProvider implements IFontProvider { public Image getImage(Object element) @@ -615,24 +693,6 @@ public class NavigationView extends ViewPart } return ApplicationRegistry.getFont(Constants.FONT_NORMAL); } - - /* - public Color getForeground(Object element) - { - TreeObject node = (TreeObject)element; - if (node.getType().equals(Constants.SERVER)) - { - if (!node.getChildren().isEmpty()) - return Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN); - else - return Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY); - } - return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK); - } - public Color getBackground(Object element) - { - return _treeViewer.getControl().getBackground(); - }*/ } // End of LabelProviderImpl @@ -641,12 +701,12 @@ public class NavigationView extends ViewPart public int category(Object element) { TreeObject node = (TreeObject)element; - if (node.getType().equals(Constants.MBEAN)) + if (node.getType().equals(Constants.MBEAN)) return 1; return 2; } } - + /** * Worker thread, which keeps looking for new ManagedObjects to be added and * unregistered objects to be removed from the tree. @@ -668,60 +728,36 @@ public class NavigationView extends ViewPart catch(Exception ex) { - } - refreshAddedObjects(); + } refreshRemovedObjects(); refreshClosedServerConnections(); }// end of while loop }// end of run method. }// end of Worker class - - private void refreshAddedObjects() + public void addManagedBean(ManagedBean mbean) throws Exception { - for (ManagedServer server : _managedServerMap.keySet()) + TreeObject treeServerObject = _managedServerMap.get(mbean.getServer()); + List<TreeObject> domains = treeServerObject.getChildren(); + TreeObject domain = null; + for (TreeObject child : domains) { - JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); - if (serverRegistry == null) // server connection is closed - continue; - - final List<ManagedBean> list = serverRegistry.getObjectsToBeAdded(); - if (list != null) + if (child.getName().equals(mbean.getDomain())) { - Display display = getSite().getShell().getDisplay(); - display.syncExec(new Runnable() - { - public void run() - { - for (ManagedBean obj : list) - { - System.out.println("adding " + obj.getName() + " " + obj.getType()); - TreeObject treeServerObject = _managedServerMap.get(obj.getServer()); - List<TreeObject> domains = treeServerObject.getChildren(); - TreeObject domain = null; - for (TreeObject child : domains) - { - if (child.getName().equals(obj.getDomain())) - { - domain = child; - break; - } - } - - addManagedBean(domain, obj); - } - _treeViewer.refresh(); - } - }); + domain = child; + break; } } + + addManagedBean(domain, mbean); + _treeViewer.refresh(); } private void refreshRemovedObjects() { for (ManagedServer server : _managedServerMap.keySet()) { - final JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + final ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(server); if (serverRegistry == null) // server connection is closed continue; @@ -758,8 +794,8 @@ public class NavigationView extends ViewPart } /** - * - * + * Gets the list of closed server connection from the ApplicationRegistry and then removes + * the closed server nodes from the navigation view */ private void refreshClosedServerConnections() { diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java index c1784d0bf1..3eb93f55d3 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java @@ -196,7 +196,7 @@ public class NotificationsTabControl extends TabControl formData = new FormData(); formData.top = new FormAttachment(notificationNameCombo, 5); formData.left = new FormAttachment(fixedLabel, 10); - formData.right = new FormAttachment(80); + formData.right = new FormAttachment(100); descriptionLabel.setLayoutData(formData); descriptionLabel.setText(" "); descriptionLabel.setFont(ApplicationRegistry.getFont(Constants.FONT_ITALIC)); diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java index ae3eef102d..ef3d6f0106 100644 --- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java @@ -388,10 +388,10 @@ public class ViewUtility return response; } - public static void popupError(String title, String message, Exception ex) + public static void popupError(String title, String message, Throwable ex) { IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID, - IStatus.ERROR, ex.getMessage(), ex); + IStatus.ERROR, ex.toString(), ex); ErrorDialog.openError(Display.getCurrent().getActiveShell(), title, message, status); } |