diff options
| author | Robert Gemmell <robbie@apache.org> | 2013-09-23 23:37:32 +0000 |
|---|---|---|
| committer | Robert Gemmell <robbie@apache.org> | 2013-09-23 23:37:32 +0000 |
| commit | 59710ea96cf37dc3859ada1dc5fb095b0b2bc6b4 (patch) | |
| tree | 9057f14c822133a506620251cd253a899b186564 /qpid/java/broker | |
| parent | efb5fc9fef693085e1eab22d84bd250f2bc241d6 (diff) | |
| download | qpid-python-59710ea96cf37dc3859ada1dc5fb095b0b2bc6b4.tar.gz | |
QPID-5159: fixups after previous directory rename of broker to broker-core
- Add new broker module build.xml
- Updates the other modules to rely on broker-core, make it all compile.
- 'Un-move' the bin, etc, scripts dirs and other non-core files to 'leave' them in the broker module.
- 'Un-move' the Main and MainTest classes to 'leave' them in the broker module.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1525736 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/broker')
| -rw-r--r-- | qpid/java/broker/bin/qpid-passwd | 35 | ||||
| -rw-r--r-- | qpid/java/broker/bin/qpid-server | 56 | ||||
| -rw-r--r-- | qpid/java/broker/bin/qpid-server.bat | 201 | ||||
| -rw-r--r-- | qpid/java/broker/bin/qpid.stop | 178 | ||||
| -rw-r--r-- | qpid/java/broker/bin/qpid.stopall | 27 | ||||
| -rw-r--r-- | qpid/java/broker/build.xml | 85 | ||||
| -rw-r--r-- | qpid/java/broker/etc/broker_example.acl | 131 | ||||
| -rw-r--r-- | qpid/java/broker/etc/groups | 29 | ||||
| -rw-r--r-- | qpid/java/broker/etc/log4j.xml | 123 | ||||
| -rw-r--r-- | qpid/java/broker/etc/md5passwd | 23 | ||||
| -rw-r--r-- | qpid/java/broker/etc/passwd | 25 | ||||
| -rw-r--r-- | qpid/java/broker/python-test.xml | 56 | ||||
| -rw-r--r-- | qpid/java/broker/scripts/resetAlerting.sh | 116 | ||||
| -rw-r--r-- | qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java | 381 | ||||
| -rw-r--r-- | qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java | 284 |
15 files changed, 1750 insertions, 0 deletions
diff --git a/qpid/java/broker/bin/qpid-passwd b/qpid/java/broker/bin/qpid-passwd new file mode 100644 index 0000000000..69246974fa --- /dev/null +++ b/qpid/java/broker/bin/qpid-passwd @@ -0,0 +1,35 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +if [ -z "$QPID_HOME" ]; then + WHEREAMI=`dirname "$0"` + export QPID_HOME=`cd "$WHEREAMI/../" && pwd` +fi + +# Set classpath to include Qpid jar with all required jars in manifest +QPID_LIBS=$QPID_HOME/lib/qpid-all.jar + +# Set other variables used by the qpid-run script before calling +export JAVA=java \ + JAVA_VM=-server \ + JAVA_MEM=-Xmx1024m \ + QPID_CLASSPATH=$QPID_LIBS + +. "${QPID_HOME}/bin/qpid-run" org.apache.qpid.tools.security.Passwd "$@" diff --git a/qpid/java/broker/bin/qpid-server b/qpid/java/broker/bin/qpid-server new file mode 100644 index 0000000000..206ae6a225 --- /dev/null +++ b/qpid/java/broker/bin/qpid-server @@ -0,0 +1,56 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +WHEREAMI=`dirname $0` +if [ -z "$QPID_HOME" ]; then + export QPID_HOME=`cd $WHEREAMI/../ && pwd` +fi + +if [ -z "$QPID_WORK" ]; then + echo "Setting QPID_WORK to $HOME as default" + QPID_WORK=$HOME +fi + +# Set to help us get round the manifold problems of ps/pgrep on various +# platforms which gather up to prevent qpid_stop from working ..... +if [ -z "$QPID_PNAME" ]; then + export QPID_PNAME=" -DPNAME=QPBRKR" +fi + +# Set classpath to include the qpid-all manifest jar, plus jars in lib/plugins and lib/opt +QPID_LIBS="$QPID_HOME/lib/qpid-all.jar:$QPID_HOME/lib/plugins/*:$QPID_HOME/lib/opt/*" + +# Set other variables used by the qpid-run script before calling +export JAVA=java \ + JAVA_VM=-server \ + JAVA_MEM=-Xmx1024m \ + JAVA_GC="-XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError" \ + QPID_CLASSPATH=$QPID_LIBS \ + QPID_RUN_LOG=2 + +QPID_OPTS="$QPID_OPTS -Damqj.read_write_pool_size=32 -DQPID_LOG_APPEND=$QPID_LOG_APPEND" + +# Echo the PID to file. Since qpid-run is sourced and uses exec to +# launch the broker, this will give the brokers PID. +if [ -z "$QPID_PID_FILENAME" ]; then + export QPID_PID_FILENAME="qpid-server.pid" +fi +echo $$ > "${QPID_WORK}/${QPID_PID_FILENAME}" + +. "${QPID_HOME}/bin/qpid-run" org.apache.qpid.server.Main "$@" diff --git a/qpid/java/broker/bin/qpid-server.bat b/qpid/java/broker/bin/qpid-server.bat new file mode 100644 index 0000000000..96965b0b42 --- /dev/null +++ b/qpid/java/broker/bin/qpid-server.bat @@ -0,0 +1,201 @@ +@REM
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM
+
+@echo off
+REM Script to run the Qpid Java Broker
+
+rem Guess QPID_HOME if not defined
+set CURRENT_DIR=%cd%
+if not "%QPID_HOME%" == "" goto gotHome
+set QPID_HOME=%CURRENT_DIR%
+echo %QPID_HOME%
+if exist "%QPID_HOME%\bin\qpid-server.bat" goto okHome
+cd ..
+set QPID_HOME=%cd%
+cd %CURRENT_DIR%
+:gotHome
+if exist "%QPID_HOME%\bin\qpid-server.bat" goto okHome
+echo The QPID_HOME environment variable is not defined correctly
+echo This environment variable is needed to run this program
+goto end
+:okHome
+
+REM set QPID_WORK if not set
+if not "%QPID_WORK%" == "" goto okQpidWork
+if "%HOME%" == "" goto noHome
+set QPID_WOKR=%HOME%
+goto okQpidWork
+
+:noHome
+set QPID_WORK=c:\Temp
+if not exist %QPID_WORK% md %QPID_WORK%
+:okQpidWork
+
+if not "%JAVA_HOME%" == "" goto gotJavaHome
+echo The JAVA_HOME environment variable is not defined
+echo This environment variable is needed to run this program
+goto end
+:gotJavaHome
+if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome
+goto okJavaHome
+:noJavaHome
+echo The JAVA_HOME environment variable is not defined correctly
+echo This environment variable is needed to run this program.
+goto end
+:okJavaHome
+
+REM set loggin level if not set
+if "%AMQJ_LOGGING_LEVEL%" == "" set AMQJ_LOGGING_LEVEL=info
+
+REM Set the default system properties that we'll use now that they have
+REM all been initialised
+set SYSTEM_PROPS=-Damqj.logging.level=%AMQJ_LOGGING_LEVEL% -DQPID_HOME="%QPID_HOME%" -DQPID_WORK="%QPID_WORK%"
+
+if "%EXTERNAL_CLASSPATH%" == "" set EXTERNAL_CLASSPATH=%CLASSPATH%
+
+REM Use QPID_CLASSPATH if set
+if "%QPID_CLASSPATH%" == "" goto noQpidClasspath
+set CLASSPATH=%QPID_CLASSPATH%
+echo Using CLASSPATH: %CLASSPATH%
+goto afterQpidClasspath
+
+:noQpidClasspath
+echo Warning: Qpid classpath not set. CLASSPATH set to %QPID_HOME%\lib\qpid-all.jar;%QPID_HOME%\lib\plugins\*;%QPID_HOME%\lib\opt\*
+set CLASSPATH=%QPID_HOME%\lib\qpid-all.jar;%QPID_HOME%\lib\plugins\*;%QPID_HOME%\lib\opt\*
+:afterQpidClasspath
+
+REM start parsing -run arguments
+set QPID_ARGS=
+if "%1" == "" goto endRunArgs
+:runLoop
+set var=%~1
+if "%var:~0,5%" == "-run:" goto runFound
+set QPID_ARGS=%QPID_ARGS% %1
+:beforeRunShift
+shift
+if "%~1" neq "" goto runLoop
+goto endRunArgs
+
+:runFound
+if "%var%" == "-run:debug" goto runDebug
+if "%var%" == "-run:jpda" goto runJdpa
+if "%var:~0,24%" == "-run:external-classpath-" goto runExternalClasspath
+if "%var%" == "-run:print-classpath" goto runPrintCP
+if "%var%" == "-run:help" goto runHelp
+echo "unrecognized -run option '%var%'. For using external classpaths use -run:external-classpath-option"
+goto end
+
+:runDebug
+REM USAGE: print the classpath and command before running it
+set debug=true
+goto beforeRunShift
+
+:runJdpa
+REM USAGE: adds debugging options to the java command, use
+REM USAGE: JPDA_TRANSPORT and JPDA_ADDRESS to customize the debugging
+REM USAGE: behavior and use JPDA_OPTS to override it entirely
+if not "%JPDA_OPTS%" == "" goto beforeRunShift
+if "%JPDA_TRANSPORT%" == "" set JPDA_TRANSPORT=dt_socket
+if "%JPDA_ADDRESS%" == "" set JPDA_ADDRESS=8000
+set JPDA_OPTS=-Xdebug -Xrunjdwp:transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=n
+REM set QPID_OPTS="%QPID_OPTS% %JPDA_OPTS%"
+goto beforeRunShift
+
+:runExternalClasspath
+echo Using external classpath %var%
+REM USAGE: Format is -run:external-classpath-first/last/ignore/only as equals special in DOS
+REM USAGE: controls how the CLASSPATH environment variable is used by
+REM USAGE: this script, value can be one of ignore (the default), first,
+REM USAGE: last, and only
+if "%var%" == "-run:external-classpath-ignore" goto beforeRunShift
+if "%var%" == "-run:external-classpath-first" goto extCPFirst
+if "%var%" == "-run:external-classpath-last" goto extCPLast
+if "%var%" == "-run:external-classpath-only" goto extCPOnly
+echo Invalid value provided for external classpath.
+goto end
+
+:extCPFirst
+set CLASSPATH=%EXTERNAL_CLASSPATH%;%CLASSPATH%
+goto beforeRunShift
+
+:extCPLast
+set CLASSPATH=%CLASSPATH%;%EXTERNAL_CLASSPATH%
+goto beforeRunShift
+
+:extCPonly
+set CLASSPATH=%EXTERNAL_CLASSPATH%
+goto beforeRunShift
+
+:runPrintCP
+REM USAGE: print the classpath
+echo %CLASSPATH%
+goto beforeRunShift
+
+:runHelp
+REM USAGE: print this message
+echo -------------------------------------------------------------------------------------------
+echo -run:option where option can be the following.
+echo debug : Prints classpath and command before running it
+echo jpda : Adds remote debugging info using JPDA_OPTS. Use JPDA_TRANSPORT and JPDA_ADDRESS to
+echo customize, JPDA_OPTS to override
+echo external-classpath : Valid values are: ignore, first, last and only.
+echo print-classpath : Prints classpath before running command
+echo help : Prints this message
+echo --------------------------------------------------------------------------------------------
+goto end
+
+REM end parsing -run arguments
+:endRunArgs
+
+set JAVA_VM=-server
+set JAVA_MEM=-Xmx1024m
+set JAVA_GC=-XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError
+
+REM Use QPID_JAVA_GC if set
+if "%QPID_JAVA_GC%" == "" goto noQpidJavaGC
+set JAVA_GC=%QPID_JAVA_GC%
+echo Using QPID_JAVA_GC setting: %QPID_JAVA_GC%
+goto afteQpidJavaGC
+
+:noQPidJavaGC
+echo Info: QPID_JAVA_GC not set. Defaulting to JAVA_GC %JAVA_GC%
+:afterQpidJavaGC
+
+REM Use QPID_JAVA_MEM if set
+if "%QPID_JAVA_MEM%" == "" goto noQpidJavaMem
+set JAVA_MEM=%QPID_JAVA_MEM%
+echo Using QPID_JAVA_MEM setting: %QPID_JAVA_MEM%
+goto afterQpidJavaMem
+
+:noQpidJavaMem
+echo Info: QPID_JAVA_MEM not set. Defaulting to JAVA_MEM %JAVA_MEM%
+:afterQpidJavaMem
+
+
+rem QPID_OPTS intended to hold any -D props for use
+rem user must enclose any value for QPID_OPTS in double quotes
+:runCommand
+set MODULE_JARS=%QPID_MODULE_JARS%
+set COMMAND="%JAVA_HOME%\bin\java" %JAVA_VM% %JAVA_MEM% %JAVA_GC% %QPID_OPTS% %JPDA_OPTS% %SYSTEM_PROPS% -cp "%CLASSPATH%;%MODULE_JARS%" org.apache.qpid.server.Main %QPID_ARGS%
+
+if "%debug%" == "true" echo %CLASSPATH%;%LAUNCH_JAR%;%MODULE_JARS%
+if "%debug%" == "true" echo %COMMAND%
+%COMMAND%
+
+:end
diff --git a/qpid/java/broker/bin/qpid.stop b/qpid/java/broker/bin/qpid.stop new file mode 100644 index 0000000000..316f8dff46 --- /dev/null +++ b/qpid/java/broker/bin/qpid.stop @@ -0,0 +1,178 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# qpid.stop Script +# +# Script checks for a given pid running DEFAULT_SEARCH and attempts to quit it +# + +MAX_ATTEMPTS=2 +SLEEP_DELAY=1 +DEFAULT_SEARCH="PNAME=QPBRKR" + +if [ -z "$QPID_STOP_SEARCH" ]; then + SEARCH=$DEFAULT_SEARCH; +else + SEARCH=$QPID_STOP_SEARCH; +fi + +# +# Forcably Quit the specified PID($1) +# +forceQuit() +{ +kill -9 $1 +} + +# +# Gracefully ask the PID($1) to quit +# +quit() +{ +kill $1 +} + +# +# grep for the session ID ($1) and return 0 for successful quit and 1 for process alive +# +lookup_pid() +{ +result=`ps -e | grep $1 | wc -l` +} + +# +# grep ps for all instances of $SEARCH for the current user and collect PIDs +# +lookup_all_pids() +{ +pids=`pgrep -f -U $USER $SEARCH` +result_all=`echo -n $pids | wc -w` +} + +# +# check that the PID passed in is for a Qpid broker owned by this user and alive +# +validate_pid() +{ +result=`pgrep -fl $SEARCH | grep $1 | wc -l` +} + +# +# Show the PS output for given set of pids +# +showPids() +{ +ps -o user,pid,args -p $pids +} + +# +# Sleep and then check then lookup the PID($1) to ensure it has quit +# +check() +{ +echo "Waiting $SLEEP_DELAY second for $1 to exit" +sleep $SLEEP_DELAY +lookup_pid $1 +} + +# +# Verify the PID($1) is available +# +verifyPid() +{ +validate_pid $1 +if [[ $[$result] == 1 ]] ; then + brokerspid=$1 +else + echo "Unable to locate Qpid Broker Process with PID $1. Check PID and try again." + exit -1 +fi +} + +# +# Stops all Qpid brokers for current user +# +qpid_stopall_brokers() +{ +for pid in $pids ; do + lookup_pid $pid; + brokerspid=$pid; + stop_broker $pid; +done +} + +# +# Stops Qpid broker with brokerspid id +# +stop_broker() +{ +# Attempt to quit the process MAX_ATTEMPTS Times +attempt=0 +while [[ $[$result] > 0 && $[$attempt] < $[$MAX_ATTEMPTS] ]] ; do + quit $brokerspid + check $brokerspid + attempt=$[$attempt + 1] +done + +# Check that it has quit +if [[ $[$result] == 0 ]] ; then + echo "Process quit" +else + + attempt=0 + # Now attempt to force quit the process + while [[ $[$result] > 0 && $[$attempt] < $[$MAX_ATTEMPTS] ]] ; do + forceQuit $brokerspid + check $brokerspid + attempt=$[$attempt + 1] + done + + # Output final status + if [[ $[$result] > 0 && $[$attempt] == $[$MAX_ATTEMPTS] ]] ; then + echo "Stopped trying to kill process: $brokerspid" + echo "Attempted to stop $attempt times" + else + echo "Done " + fi +fi + +} + +# +# Main Run +# + +# Check if we are killing all qpid pids or just one. +# Now uses local function qpid_stopall_brokers +if [[ $# == 0 ]] ; then + lookup_all_pids + if [[ $[$result_all] > 0 ]] ; then + echo "Killing All Qpid Brokers for user: '$USER'" + qpid_stopall_brokers + else + echo "No Qpid Brokers found running for user: " $USER + fi + exit $result +else + verifyPid $1 + stop_broker + exit $result +fi + diff --git a/qpid/java/broker/bin/qpid.stopall b/qpid/java/broker/bin/qpid.stopall new file mode 100644 index 0000000000..b0ad506629 --- /dev/null +++ b/qpid/java/broker/bin/qpid.stopall @@ -0,0 +1,27 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# qpid.stopall script +# +# Script attempts to stop all PROGRAMs running under the current user +# Utilises qpid.stop to perform the actual stopping +# + +qpid.stop $* diff --git a/qpid/java/broker/build.xml b/qpid/java/broker/build.xml new file mode 100644 index 0000000000..d0c976787a --- /dev/null +++ b/qpid/java/broker/build.xml @@ -0,0 +1,85 @@ +<!-- + - + - Licensed to the Apache Software Foundation (ASF) under one + - or more contributor license agreements. See the NOTICE file + - distributed with this work for additional information + - regarding copyright ownership. The ASF licenses this file + - to you under the Apache License, Version 2.0 (the + - "License"); you may not use this file except in compliance + - with the License. You may obtain a copy of the License at + - + - http://www.apache.org/licenses/LICENSE-2.0 + - + - Unless required by applicable law or agreed to in writing, + - software distributed under the License is distributed on an + - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + - KIND, either express or implied. See the License for the + - specific language governing permissions and limitations + - under the License. + - + --> +<project name="Broker" default="build"> + <property name="module.depends" value="broker-core common"/> + <property name="module.test.depends" value="common/tests" /> + <property name="module.main" value="org.apache.qpid.server.Main"/> + <property name="module.genpom" value="true"/> + + <!-- Add dependencies to the broker pom for the broker-core, broker-plugins and bdbstore modules --> + <property name="module.maven.depends" value="broker-core broker-plugins/access-control broker-plugins/amqp-0-8-protocol broker-plugins/amqp-0-10-protocol broker-plugins/amqp-1-0-protocol broker-plugins/amqp-msg-conv-0-8-to-0-10 broker-plugins/amqp-msg-conv-0-8-to-1-0 broker-plugins/amqp-msg-conv-0-10-to-1-0 broker-plugins/derby-store broker-plugins/jdbc-provider-bone broker-plugins/jdbc-store broker-plugins/management-http broker-plugins/management-jmx broker-plugins/memory-store bdbstore bdbstore/jmx"/> + <!-- Make the plugins runtime dependencies, make bdbstore modules optional --> + <property name="module.genpom.args" value="-Sqpid-broker-plugins-access-control=runtime -Sqpid-broker-plugins-amqp-0-8-protocol=runtime -Sqpid-broker-plugins-amqp-0-10-protocol=runtime -Sqpid-broker-plugins-amqp-1-0-protocol=runtime -Sqpid-broker-plugins-amqp-msg-conv-0-8-to-0-10=runtime -Sqpid-broker-plugins-amqp-msg-conv-0-8-to-1-0=runtime -Sqpid-broker-plugins-amqp-msg-conv-0-10-to-1-0=runtime -Sqpid-broker-plugins-derby-store=runtime -Sqpid-broker-plugins-jdbc-provider-bone=runtime -Sqpid-broker-plugins-jdbc-store=runtime -Sqpid-broker-plugins-management-http=runtime -Sqpid-broker-plugins-management-jmx=runtime -Sbroker-plugins-memory-store=runtime -Sqpid-bdbstore=runtime -Sqpid-bdbstore-jmx=runtime -Oqpid-bdbstore -Oqpid-bdbstore-jmx"/> + + <import file="../module.xml"/> + + + <target name="copy-etc-release" if="module.etc.exists" description="copy etc directory if it exists to build tree"> + <copy todir="${module.release}/etc" failonerror="false" flatten="true"> + <fileset dir="${module.etc}" excludes="*.conf,*.jpp"/> + </copy> + </target> + + <target name="copy-bin-release" description="copy dependencies into module release"> + <copy todir="${module.release}/bin" failonerror="true"> + <fileset dir="${module.bin}"/> + </copy> + <copy todir="${module.release}/bin" failonerror="true" flatten="true"> + <fileset dir="${basedir}/../common/bin"/> + </copy> + <chmod dir="${module.release}/bin" perm="ugo+rx" includes="**/*"/> + <fixcrlf srcdir="${module.release}/bin" fixlast="true" eol="unix"/> + <fixcrlf srcdir="${module.release}/bin" fixlast="true" eol="dos" includes="*.bat"/> + </target> + + <target name="release-bin-other" depends="release-bin-other-lib-opt,release-bin-other-bdbstore,release-bin-copy-broker-plugins"/> + + <target name="release-bin-other-lib-opt" depends="release-bin-other-bdbstore" description="make lib/opt dir in the module release"> + <mkdir dir="${module.release}/lib/opt"/> + </target> + + <target name="release-bin-copy-broker-plugins" description="copy broker-plugins into module release"> + <copy todir="${module.release}/lib/plugins" failonerror="true"> + <fileset dir="${build.scratch.broker.plugins.lib}"/> + </copy> + </target> + + <target name="release-bin-other-bdbstore" depends="check-bdbstore-requested" if="bdbstore-requested" + description="copy bdbstore items into module release"> + <copy todir="${module.release}/bin" failonerror="true" flatten="true"> + <fileset dir="${basedir}/../bdbstore/bin"/> + </copy> + </target> + + <target name="check-bdbstore-requested"> + <condition property="bdbstore-requested"> + <or> + <contains string="${modules.opt}" substring="bdbstore"/> + <istrue value="${optional}"/> + </or> + </condition> + </target> + + <target name="release-bin" depends="release-bin-tasks"/> + + <target name="bundle" depends="bundle-tasks"/> + +</project> diff --git a/qpid/java/broker/etc/broker_example.acl b/qpid/java/broker/etc/broker_example.acl new file mode 100644 index 0000000000..29dca90f15 --- /dev/null +++ b/qpid/java/broker/etc/broker_example.acl @@ -0,0 +1,131 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +### EXAMPLE ACL V2 FILE +### NOTE: Rules are considered from top to bottom, and the first matching rule governs the decision. +### Rules may refer to users or groups. Groups are currently defined in the etc/groups file. + +### JMX MANAGEMENT #### + +# To use JMX management, first give the user/group ACCESS MANAGEMENT permission +ACL ALLOW administrators ACCESS MANAGEMENT +ACL ALLOW guest ACCESS MANAGEMENT + +# Allow guest to perform read operations on the ServerInformation mbean +ACL ALLOW guest ACCESS METHOD component="ServerInformation" + +# Allow 'administrators' all management operations. To reduce log file noise, only non-read-only operations are logged. +ACL ALLOW administrators ACCESS METHOD +ACL ALLOW-LOG administrators ALL METHOD + +# Allow 'guest' to view logger levels, and use getter methods on LoggingManagement +ACL ALLOW guest ACCESS METHOD component="LoggingManagement" name="viewEffectiveRuntimeLoggerLevels" +ACL ALLOW guest ACCESS METHOD component="LoggingManagement" name="get*" + +# Deny access to Shutdown, UserManagement, ConfigurationManagement and LoggingManagement for all other users +# You could grant specific users access to these beans by adding rules above to allow them +ACL DENY-LOG ALL ACCESS METHOD component="Shutdown" +ACL DENY-LOG ALL ACCESS METHOD component="UserManagement" +ACL DENY-LOG ALL ACCESS METHOD component="ConfigurationManagement" +ACL DENY-LOG ALL ACCESS METHOD component="LoggingManagement" + +# Allow everyone to perform all read operations on the mbeans not listed in the DENY rules above +ACL ALLOW ALL ACCESS METHOD + +### WEB MANAGEMENT #### + +# To use web management, first give the user/group ACCESS MANAGEMENT permission +ACL ALLOW webadmins ACCESS MANAGEMENT + +# ACL for web management console admins +# All rules below are required for console admin users +# to perform create/update/delete operations +ACL ALLOW-LOG webadmins CREATE QUEUE +ACL ALLOW-LOG webadmins UPDATE QUEUE +ACL ALLOW-LOG webadmins DELETE QUEUE +ACL ALLOW-LOG webadmins PURGE QUEUE +ACL ALLOW-LOG webadmins CREATE EXCHANGE +ACL ALLOW-LOG webadmins DELETE EXCHANGE +ACL ALLOW-LOG webadmins BIND EXCHANGE +ACL ALLOW-LOG webadmins UNBIND EXCHANGE +ACL ALLOW-LOG webadmins CREATE GROUP +ACL ALLOW-LOG webadmins DELETE GROUP +ACL ALLOW-LOG webadmins UPDATE GROUP +ACL ALLOW-LOG webadmins CREATE USER +ACL ALLOW-LOG webadmins DELETE USER +ACL ALLOW-LOG webadmins UPDATE USER + +ACL ALLOW-LOG webadmins UPDATE METHOD + +# authorise operations changing broker model +ACL ALLOW-LOG webadmins CONFIGURE BROKER + +# authorise operations to view and download broker logs +ACL ALLOW webadmins ACCESS_LOGS BROKER + +# at the moment only the following UPDATE METHOD rules are supported by web management console +#ACL ALLOW-LOG webadmins UPDATE METHOD component="VirtualHost.Queue" name="moveMessages" +#ACL ALLOW-LOG webadmins UPDATE METHOD component="VirtualHost.Queue" name="copyMessages" +#ACL ALLOW-LOG webadmins UPDATE METHOD component="VirtualHost.Queue" name="deleteMessages" + +### MESSAGING ### +# The 'ACCESS VIRTUALHOST' rules below apply to messaging operations (as opposed to management operations) + +# Firewall examples + +# Deny access to all users from *.example.company1.com and *.example.company2.com +ACL DENY-LOG all ACCESS VIRTUALHOST from_hostname=".*\.example\.company1.com,.*\.example\.company2.com" + +# Deny access to all users in the IP ranges 192.168.1.0-192.168.1.255 and 192.168.2.0-192.168.2.255, +# using the notation specified in RFC 4632, "Classless Inter-domain Routing (CIDR)" +ACL DENY-LOG messaging-users ACCESS VIRTUALHOST from_network="192.168.1.0/24,192.168.2.0/24" + +# Deny access to all users in the IP ranges 192.169.1.0-192.169.1.255 and 192.169.2.0-192.169.2.255, +# using wildcard notation. +ACL DENY-LOG messaging-users ACCESS VIRTUALHOST from_network="192.169.1.*,192.169.2.*" + +# Allow 'messaging-users' group to connect to all virtualhosts +ACL ALLOW-LOG messaging-users ACCESS VIRTUALHOST + +# Deny messaging-users management +ACL DENY-LOG messaging-users ACCESS MANAGEMENT + + +# Client side +# Allow the 'client' user to publish requests to the request queue and create, consume from, and delete temporary reply queues. +ACL ALLOW-LOG client CREATE QUEUE temporary="true" +ACL ALLOW-LOG client CONSUME QUEUE temporary="true" +ACL ALLOW-LOG client DELETE QUEUE temporary="true" +ACL ALLOW-LOG client BIND EXCHANGE name="amq.direct" temporary="true" +ACL ALLOW-LOG client UNBIND EXCHANGE name="amq.direct" temporary="true" +ACL ALLOW-LOG client PUBLISH EXCHANGE name="amq.direct" routingKey="example.RequestQueue" + +# Server side +# Allow the 'server' user to create and consume from the request queue and publish a response to the temporary response queue created by +# client. +ACL ALLOW-LOG server CREATE QUEUE name="example.RequestQueue" +ACL ALLOW-LOG server CONSUME QUEUE name="example.RequestQueue" +ACL ALLOW-LOG server BIND EXCHANGE +ACL ALLOW-LOG server PUBLISH EXCHANGE name="amq.direct" routingKey="TempQueue*" + + +### DEFAULT ### + +# Deny all users from performing all operations +ACL DENY-LOG all all diff --git a/qpid/java/broker/etc/groups b/qpid/java/broker/etc/groups new file mode 100644 index 0000000000..e3912ece99 --- /dev/null +++ b/qpid/java/broker/etc/groups @@ -0,0 +1,29 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# +# To define a group, use the format: +# +# <groupname>.users=<user1>,<user2>,...,<usern> +# + +messaging-users.users=guest,client,server +administrators.users=admin +webadmins.users=webadmin + diff --git a/qpid/java/broker/etc/log4j.xml b/qpid/java/broker/etc/log4j.xml new file mode 100644 index 0000000000..71a13875a1 --- /dev/null +++ b/qpid/java/broker/etc/log4j.xml @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + - + - Licensed to the Apache Software Foundation (ASF) under one + - or more contributor license agreements. See the NOTICE file + - distributed with this work for additional information + - regarding copyright ownership. The ASF licenses this file + - to you under the Apache License, Version 2.0 (the + - "License"); you may not use this file except in compliance + - with the License. You may obtain a copy of the License at + - + - http://www.apache.org/licenses/LICENSE-2.0 + - + - Unless required by applicable law or agreed to in writing, + - software distributed under the License is distributed on an + - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + - KIND, either express or implied. See the License for the + - specific language governing permissions and limitations + - under the License. + - + --><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> + +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="null" threshold="null"> + <appender class="org.apache.log4j.QpidCompositeRollingAppender" name="ArchivingFileAppender"> + <!-- Ensure that logs always have the DatePattern appended to the filename. + DEFAULT IF NOT CONFIGURED: true --> + <param name="StaticLogFileName" value="true"/> + <param name="file" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/> + <!-- Style of rolling to use, by: + File Size(1) + Date(2) + Both(3) + + When Date (or Both) is enabled then the value of DatePattern will determine + when the new file is made. e.g. a DatePattern of "'.'yyyy-MM-dd-HH-mm" + which includes minutes will cause a new backup file to be made every minute. + + DEFAULT IF NOT CONFIGURED: 3 --> + <param name="RollingStyle" value="1"/> + <!-- Set the count direction: + Negative numbers mean backups are numbered <latest>, .0, .1, .2,..., .n + 0 means backup is DatePattern stamped and followed with a Positive number + if the DatePattern stamp clashes with other existing backups. + Positive numbers mean backups are numbered 0, 1, 2, ..., n, <latest> + + DEFAULT IF NOT CONFIGURED: -1 --> + <param name="CountDirection" value="0"/> + <!-- Maximum File Size: + DEFAULT IF NOT CONFIGURED: 10MB --> + <param name="MaxFileSize" value="1MB"/> + <!-- Date Pattern: + DEFAULT IF NOT CONFIGURED: "'.'yyyy-MM-dd" --> + <param name="DatePattern" value="'.'yyyy-MM-dd-HH-mm"/> + <!-- Maximum number of backup files: + 0 means no backups + -1 means infinite backups + + DEFAULT IF NOT CONFIGURED: 0 --> + <param name="MaxSizeRollBackups" value="-1"/> + <!-- Compress(gzip) the backup files to the backup location: + DEFAULT IF NOT CONFIGURED: FALSE --> + <param name="CompressBackupFiles" value="true"/> + <!-- Compress the backup files using a second thread: + DEFAULT IF NOT CONFIGURED: FALSE --> + <param name="CompressAsync" value="true"/> + <!-- Backup Location: + DEFAULT IF NOT CONFIGURED: same dir as log file --> + <param name="backupFilesToPath" value="${QPID_WORK}/backup/log"/> + + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d %-5p [%t] (%c{2}) - %m%n"/> + </layout> + </appender> + + <appender class="org.apache.log4j.FileAppender" name="FileAppender"> + <param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/> + <param name="Append" value="false"/> + + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d %-5p [%t] (%c{2}) - %m%n"/> + </layout> + </appender> + + <appender class="org.apache.log4j.ConsoleAppender" name="STDOUT"> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d %-5p [%t] (%c{2}) - %m%n"/> + </layout> + </appender> + + <!-- Provide warnings to standard output --> + <logger additivity="true" name="org.apache.qpid"> + <level value="warn"/> + </logger> + + <!-- Enable info messages for the status-logging hierarchy --> + <logger additivity="true" name="qpid.message"> + <level value="info"/> + </logger> + + <!-- Subscription state may toggle frequently for clients with low prefetch + so switch off this operational logging by default--> + <logger additivity="true" name="qpid.message.subscription.state"> + <level value="off"/> + </logger> + + <!-- Enable log messages for the queue notifications --> + <logger additivity="true" name="org.apache.qpid.server.queue.NotificationCheck"> + <level value="info"/> + </logger> + + <!-- Set the commons logging that the XML parser uses to WARN, it is very chatty at debug --> + <logger name="org.apache.commons"> + <level value="warn"/> + </logger> + + <!-- Log all info events to file --> + <root> + <level value="info"/> + <appender-ref ref="FileAppender"/> + <!--appender-ref ref="ArchivingFileAppender"/--> + </root> + +</log4j:configuration> diff --git a/qpid/java/broker/etc/md5passwd b/qpid/java/broker/etc/md5passwd new file mode 100644 index 0000000000..f7185c0e92 --- /dev/null +++ b/qpid/java/broker/etc/md5passwd @@ -0,0 +1,23 @@ +#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+guest:CE4DQ6BIb/BVMN9scFyLtA==
+client:CE4DQ6BIb/BVMN9scFyLtA==
+server:CE4DQ6BIb/BVMN9scFyLtA==
+admin:ISMvKXpXpadDiUoOSoAfww==
+webadmin:rda7WOE5vhAzJNBNgtj1RQ==
diff --git a/qpid/java/broker/etc/passwd b/qpid/java/broker/etc/passwd new file mode 100644 index 0000000000..f0dcb80f25 --- /dev/null +++ b/qpid/java/broker/etc/passwd @@ -0,0 +1,25 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +guest:guest +client:guest +server:guest +admin:admin + +webadmin:webadmin + diff --git a/qpid/java/broker/python-test.xml b/qpid/java/broker/python-test.xml new file mode 100644 index 0000000000..5c263e3169 --- /dev/null +++ b/qpid/java/broker/python-test.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + +<!-- ====================================================================== --> +<!-- Ant build file (http://ant.apache.org/) for Ant 1.6.2 or above. --> +<!-- ====================================================================== --> + +<project basedir="." default="default"> + + <target name="default" > + <echo message="Used via maven to run python tests."/> + </target> + + <dirname property="broker.dir" file="${ant.file.python-test}"/> + + <property name="pythondir" value="${broker.dir}/../../python"/> + + <target name="run-tests" unless="skip-python-tests"> + + <echo message="Starting Broker with command"/> + + <java classname="org.apache.qpid.server.RunBrokerWithCommand" + fork="true" + dir="${pythondir}" + failonerror="true" + > + <arg value="${command}"/> + <arg value="-p"/> + <arg value="2110"/> + <arg value="-m"/> + <arg value="2111"/> + + <classpath refid="maven.test.classpath"/> + <sysproperty key="QPID_HOME" value="${broker.dir}"/> + <sysproperty key="QPID_WORK" value="${broker.dir}${file.separator}target"/> + </java> + + </target> +</project> diff --git a/qpid/java/broker/scripts/resetAlerting.sh b/qpid/java/broker/scripts/resetAlerting.sh new file mode 100644 index 0000000000..18e8c64cb0 --- /dev/null +++ b/qpid/java/broker/scripts/resetAlerting.sh @@ -0,0 +1,116 @@ +#!/bin/bash +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# + +# +# Alerting Rest Scripts to renabled the alerts on the queue. +# +# Defaults to Localhost broker +# + +if [ -z "$QPID_ALERT_HOME" ]; then + export QPID_ALERT_HOME=$(dirname $(dirname $(readlink -f $0))) + export PATH=${PATH}:${QPID_ALERT_HOME}/bin +fi + +USERNAME=$1 +PASSWORD=$2 +HOSTNAME=$3 +PORT=$4 + +CLI="$QPID_ALERT_HOME/bin/qpid-cli -h ${HOSTNAME:-localhost} -p ${PORT:-8999}" +AUTH= +if [ -n $USERNAME ] ; then + if [ "$USERNAME" == "-h" ] ; then + echo "resetAlerting.sh: [<username> <password> [<hostname> [<port>]]]" + exit 0 + fi + if [ -n $PASSWORD ] ; then + AUTH="-u $USERNAME -w $PASSWORD" + else + echo "Password must be specified with username" + fi +fi + + +OUTPUT=0 + +runCommand() +{ + RET=`$CLI $1 $AUTH` +} + +resetQueue() +{ + vhost=$1 + queue=$2 + runCommand "get -o queue -v $vhost -n $queue -a MaximumQueueDepth" + rawQDepth=$RET + # Note that MaxQueueDepth is returned as Kb but set as b! + queueDepth=$[ $rawQDepth * 1024 ] + runCommand "get -o queue -v $vhost -n $queue -a MaximumMessageAge" + messageAge=$RET + runCommand "get -o queue -v $vhost -n $queue -a MaximumMessageCount" + messageCount=$RET + runCommand "get -o queue -v $vhost -n $queue -a MaximumMessageSize" + messageSize=$RET + + if [ $OUTPUT == 1 ] ; then + echo Current Values: + echo MaximumQueueDepth : $queueDepth + echo MaximumMessageAge : $messageAge + echo MaximumMessageCount : $messageCount + echo MaximumMessageSize : $messageSize + fi + + runCommand "set -o queue -v $vhost -n $queue -a MaximumMessageSize -s $messageSize" + runCommand "set -o queue -v $vhost -n $queue -a MaximumMessageAge -s $messageAge" + runCommand "set -o queue -v $vhost -n $queue -a MaximumMessageCount -s $messageCount" + runCommand "set -o queue -v $vhost -n $queue -a MaximumQueueDepth -s $queueDepth" +} + +resetVirtualHost() +{ + vhost=$1 + ignore=0 + for queue in `$CLI list -o queue -v $vhost $AUTH |grep '|' | cut -d '|' -f 1 ` ; do + + if [ $ignore == 0 ] ; then + ignore=1 + else + resetQueue $vhost $queue + fi + + done +} + +VHOST=`$CLI list -o virtualhost $AUTH` +COUNT=`echo $VHOST | grep -c VirtualHost` +if [ $COUNT -gt 0 ] ; then + for vhost in `echo $VHOST |grep VirtualHost|cut -d '=' -f 3` ; do + + echo "Resetting alert levels for $vhost"; + resetVirtualHost $vhost; + done + echo "Alerting levels reset" +else + echo $VHOST +fi diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java new file mode 100644 index 0000000000..20b73e965c --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java @@ -0,0 +1,381 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server; + +import java.io.File; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.PosixParser; +import org.apache.log4j.Logger; +import org.apache.qpid.common.QpidProperties; +import org.apache.qpid.framing.ProtocolVersion; +import org.apache.qpid.server.configuration.store.ConfigurationEntryStoreUtil; + +/** + * Main entry point for AMQPD. + * + */ +public class Main +{ + private static final Option OPTION_HELP = new Option("h", "help", false, "print this message"); + + private static final Option OPTION_VERSION = new Option("v", "version", false, "print the version information and exit"); + + private static final Option OPTION_CONFIGURATION_STORE_PATH = OptionBuilder.withArgName("path").hasArg() + .withDescription("use given configuration store location").withLongOpt("store-path").create("sp"); + + private static final Option OPTION_CONFIGURATION_STORE_TYPE = OptionBuilder.withArgName("type").hasArg() + .withDescription("use given broker configuration store type").withLongOpt("store-type").create("st"); + + private static final Option OPTION_INITIAL_CONFIGURATION_PATH = OptionBuilder.withArgName("path").hasArg() + .withDescription("set the location of initial JSON config to use when creating/overwriting a broker configuration store").withLongOpt("initial-config-path").create("icp"); + + private static final Option OPTION_OVERWRITE_CONFIGURATION_STORE = OptionBuilder.withDescription("overwrite the broker configuration store with the current initial configuration") + .withLongOpt("overwrite-store").create("os"); + + private static final Option OPTION_CREATE_INITIAL_CONFIG = OptionBuilder.withArgName("path").hasOptionalArg().withDescription("create a copy of the initial config file, either to an" + + " optionally specified file path, or as " + BrokerOptions.DEFAULT_INITIAL_CONFIG_NAME + " in the current directory") + .withLongOpt("create-initial-config").create("cic"); + + private static final Option OPTION_CONFIGURATION_PROPERTY = OptionBuilder.withArgName("name=value").hasArg() + .withDescription("set a configuration property to use when resolving variables in the broker configuration store, with format \"name=value\"") + .withLongOpt("config-property").create("prop"); + + private static final Option OPTION_LOG_CONFIG_FILE = + OptionBuilder.withArgName("file").hasArg() + .withDescription("use the specified log4j xml configuration file. By " + + "default looks for a file named " + BrokerOptions.DEFAULT_LOG_CONFIG_FILE + + " in the same directory as the configuration file").withLongOpt("logconfig").create("l"); + + private static final Option OPTION_LOG_WATCH = + OptionBuilder.withArgName("period").hasArg() + .withDescription("monitor the log file configuration file for changes. Units are seconds. " + + "Zero means do not check for changes.").withLongOpt("logwatch").create("w"); + + private static final Option OPTION_MANAGEMENT_MODE = OptionBuilder.withDescription("start broker in management mode, disabling the AMQP ports") + .withLongOpt("management-mode").create("mm"); + private static final Option OPTION_MM_QUIESCE_VHOST = OptionBuilder.withDescription("make virtualhosts stay in the quiesced state during management mode.") + .withLongOpt("management-mode-quiesce-virtualhosts").create("mmqv"); + private static final Option OPTION_MM_RMI_PORT = OptionBuilder.withArgName("port").hasArg() + .withDescription("override jmx rmi registry port in management mode").withLongOpt("management-mode-rmi-registry-port").create("mmrmi"); + private static final Option OPTION_MM_CONNECTOR_PORT = OptionBuilder.withArgName("port").hasArg() + .withDescription("override jmx connector port in management mode").withLongOpt("management-mode-jmx-connector-port").create("mmjmx"); + private static final Option OPTION_MM_HTTP_PORT = OptionBuilder.withArgName("port").hasArg() + .withDescription("override http management port in management mode").withLongOpt("management-mode-http-port").create("mmhttp"); + private static final Option OPTION_MM_PASSWORD = OptionBuilder.withArgName("password").hasArg() + .withDescription("Set the password for the management mode user " + BrokerOptions.MANAGEMENT_MODE_USER_NAME).withLongOpt("management-mode-password").create("mmpass"); + + private static final Options OPTIONS = new Options(); + + static + { + OPTIONS.addOption(OPTION_HELP); + OPTIONS.addOption(OPTION_VERSION); + OPTIONS.addOption(OPTION_CONFIGURATION_STORE_PATH); + OPTIONS.addOption(OPTION_CONFIGURATION_STORE_TYPE); + OPTIONS.addOption(OPTION_OVERWRITE_CONFIGURATION_STORE); + OPTIONS.addOption(OPTION_CREATE_INITIAL_CONFIG); + OPTIONS.addOption(OPTION_LOG_CONFIG_FILE); + OPTIONS.addOption(OPTION_LOG_WATCH); + OPTIONS.addOption(OPTION_INITIAL_CONFIGURATION_PATH); + OPTIONS.addOption(OPTION_MANAGEMENT_MODE); + OPTIONS.addOption(OPTION_MM_QUIESCE_VHOST); + OPTIONS.addOption(OPTION_MM_RMI_PORT); + OPTIONS.addOption(OPTION_MM_CONNECTOR_PORT); + OPTIONS.addOption(OPTION_MM_HTTP_PORT); + OPTIONS.addOption(OPTION_MM_PASSWORD); + OPTIONS.addOption(OPTION_CONFIGURATION_PROPERTY); + } + + protected CommandLine _commandLine; + + public static void main(String[] args) + { + //if the -Dlog4j.configuration property has not been set, enable the init override + //to stop Log4J wondering off and picking up the first log4j.xml/properties file it + //finds from the classpath when we get the first Loggers + if(System.getProperty("log4j.configuration") == null) + { + System.setProperty("log4j.defaultInitOverride", "true"); + } + + new Main(args); + } + + public Main(final String[] args) + { + if (parseCommandline(args)) + { + try + { + execute(); + } + catch(Throwable e) + { + System.err.println("Exception during startup: " + e); + e.printStackTrace(); + shutdown(1); + } + } + } + + protected boolean parseCommandline(final String[] args) + { + try + { + _commandLine = new PosixParser().parse(OPTIONS, args); + + return true; + } + catch (ParseException e) + { + System.err.println("Error: " + e.getMessage()); + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp("Qpid", OPTIONS, true); + + return false; + } + } + + protected void execute() throws Exception + { + BrokerOptions options = new BrokerOptions(); + String initialConfigLocation = _commandLine.getOptionValue(OPTION_INITIAL_CONFIGURATION_PATH.getOpt()); + if (initialConfigLocation != null) + { + options.setInitialConfigurationLocation(initialConfigLocation); + } + + //process the remaining options + if (_commandLine.hasOption(OPTION_HELP.getOpt())) + { + final HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp("Qpid", OPTIONS, true); + } + else if (_commandLine.hasOption(OPTION_CREATE_INITIAL_CONFIG.getOpt())) + { + File destinationFile = null; + + String destinationOption = _commandLine.getOptionValue(OPTION_CREATE_INITIAL_CONFIG.getOpt()); + if (destinationOption != null) + { + destinationFile = new File(destinationOption); + } + else + { + destinationFile = new File(System.getProperty("user.dir"), BrokerOptions.DEFAULT_INITIAL_CONFIG_NAME); + } + + ConfigurationEntryStoreUtil util = new ConfigurationEntryStoreUtil(); + util.copyInitialConfigFile(options.getInitialConfigurationLocation(), destinationFile); + + System.out.println("Initial config written to: " + destinationFile.getAbsolutePath()); + } + else if (_commandLine.hasOption(OPTION_VERSION.getOpt())) + { + final StringBuilder protocol = new StringBuilder("AMQP version(s) [major.minor]: "); + boolean first = true; + for (final ProtocolVersion pv : ProtocolVersion.getSupportedProtocolVersions()) + { + if (first) + { + first = false; + } + else + { + protocol.append(", "); + } + + protocol.append(pv.getMajorVersion()).append('-').append(pv.getMinorVersion()); + } + System.out.println(QpidProperties.getVersionString() + " (" + protocol + ")"); + } + else + { + String[] configPropPairs = _commandLine.getOptionValues(OPTION_CONFIGURATION_PROPERTY.getOpt()); + if(configPropPairs != null && configPropPairs.length > 0) + { + for(String s : configPropPairs) + { + int firstEquals = s.indexOf("="); + if(firstEquals == -1) + { + throw new IllegalArgumentException("Configuration property argument is not of the format name=value: " + s); + } + String name = s.substring(0, firstEquals); + String value = s.substring(firstEquals + 1); + + if(name.equals("")) + { + throw new IllegalArgumentException("Configuration property argument is not of the format name=value: " + s); + } + + options.setConfigProperty(name, value); + } + } + + String configurationStore = _commandLine.getOptionValue(OPTION_CONFIGURATION_STORE_PATH.getOpt()); + if (configurationStore != null) + { + options.setConfigurationStoreLocation(configurationStore); + } + + String configurationStoreType = _commandLine.getOptionValue(OPTION_CONFIGURATION_STORE_TYPE.getOpt()); + if (configurationStoreType != null) + { + options.setConfigurationStoreType(configurationStoreType); + } + + String logWatchConfig = _commandLine.getOptionValue(OPTION_LOG_WATCH.getOpt()); + if(logWatchConfig != null) + { + options.setLogWatchFrequency(Integer.parseInt(logWatchConfig)); + } + + String logConfig = _commandLine.getOptionValue(OPTION_LOG_CONFIG_FILE.getOpt()); + if(logConfig != null) + { + options.setLogConfigFileLocation(logConfig); + } + + boolean overwriteConfigurationStore = _commandLine.hasOption(OPTION_OVERWRITE_CONFIGURATION_STORE.getOpt()); + options.setOverwriteConfigurationStore(overwriteConfigurationStore); + + boolean managementMode = _commandLine.hasOption(OPTION_MANAGEMENT_MODE.getOpt()); + if (managementMode) + { + options.setManagementMode(true); + String rmiPort = _commandLine.getOptionValue(OPTION_MM_RMI_PORT.getOpt()); + if (rmiPort != null) + { + options.setManagementModeRmiPortOverride(Integer.parseInt(rmiPort)); + } + String connectorPort = _commandLine.getOptionValue(OPTION_MM_CONNECTOR_PORT.getOpt()); + if (connectorPort != null) + { + options.setManagementModeJmxPortOverride(Integer.parseInt(connectorPort)); + } + String httpPort = _commandLine.getOptionValue(OPTION_MM_HTTP_PORT.getOpt()); + if (httpPort != null) + { + options.setManagementModeHttpPortOverride(Integer.parseInt(httpPort)); + } + + boolean quiesceVhosts = _commandLine.hasOption(OPTION_MM_QUIESCE_VHOST.getOpt()); + options.setManagementModeQuiesceVirtualHosts(quiesceVhosts); + + String password = _commandLine.getOptionValue(OPTION_MM_PASSWORD.getOpt()); + if (password != null) + { + options.setManagementModePassword(password); + } + } + setExceptionHandler(); + + startBroker(options); + } + } + + protected void setExceptionHandler() + { + Thread.UncaughtExceptionHandler handler = null; + String handlerClass = System.getProperty("qpid.broker.exceptionHandler"); + if(handlerClass != null) + { + try + { + handler = (Thread.UncaughtExceptionHandler) Class.forName(handlerClass).newInstance(); + } + catch (ClassNotFoundException e) + { + + } + catch (InstantiationException e) + { + + } + catch (IllegalAccessException e) + { + + } + catch (ClassCastException e) + { + + } + } + + if(handler == null) + { + handler = + new Thread.UncaughtExceptionHandler() + { + public void uncaughtException(final Thread t, final Throwable e) + { + boolean continueOnError = Boolean.getBoolean("qpid.broker.exceptionHandler.continue"); + try + { + System.err.println("########################################################################"); + System.err.println("#"); + System.err.print("# Unhandled Exception "); + System.err.print(e.toString()); + System.err.print(" in Thread "); + System.err.println(t.getName()); + System.err.println("#"); + System.err.println(continueOnError ? "# Forced to continue by JVM setting 'qpid.broker.exceptionHandler.continue'" : "# Exiting"); + System.err.println("#"); + System.err.println("########################################################################"); + e.printStackTrace(System.err); + + Logger logger = Logger.getLogger("org.apache.qpid.server.Main"); + logger.error("Uncaught exception, " + (continueOnError ? "continuing." : "shutting down."), e); + } + finally + { + if (!continueOnError) + { + Runtime.getRuntime().halt(1); + } + } + + } + }; + + Thread.setDefaultUncaughtExceptionHandler(handler); + } + } + + protected void startBroker(final BrokerOptions options) throws Exception + { + Broker broker = new Broker(); + broker.startup(options); + } + + protected void shutdown(final int status) + { + System.exit(status); + } + +} diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java new file mode 100644 index 0000000000..f3b1749808 --- /dev/null +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java @@ -0,0 +1,284 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server; + +import java.io.File; +import java.util.Map; + +import org.apache.commons.cli.CommandLine; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.test.utils.QpidTestCase; + +/** + * Test to verify the command line parsing within the Main class, by + * providing it a series of command line arguments and verifying the + * BrokerOptions emerging for use in starting the Broker instance. + */ +public class MainTest extends QpidTestCase +{ + private Exception _startupException; + + public void testNoOptionsSpecified() + { + String qpidWork = "/qpid/work"; + setTestSystemProperty(BrokerProperties.PROPERTY_QPID_WORK, qpidWork); + String qpidHome = "/qpid/home"; + setTestSystemProperty(BrokerProperties.PROPERTY_QPID_HOME, qpidHome); + + String expectedStorePath = new File(qpidWork, BrokerOptions.DEFAULT_CONFIG_NAME_PREFIX + ".json").getAbsolutePath(); + String expectedLogConfigPath = new File(qpidHome, BrokerOptions.DEFAULT_LOG_CONFIG_FILE).getAbsolutePath(); + + BrokerOptions options = startDummyMain(""); + + assertEquals("json", options.getConfigurationStoreType()); + assertEquals(expectedStorePath, options.getConfigurationStoreLocation()); + assertEquals(expectedLogConfigPath, options.getLogConfigFileLocation()); + assertEquals(0, options.getLogWatchFrequency()); + assertEquals(BrokerOptions.DEFAULT_INITIAL_CONFIG_LOCATION, options.getInitialConfigurationLocation()); + assertFalse(options.isOverwriteConfigurationStore()); + assertFalse(options.isManagementMode()); + assertEquals(0, options.getManagementModeJmxPortOverride()); + assertEquals(0, options.getManagementModeRmiPortOverride()); + assertEquals(0, options.getManagementModeHttpPortOverride()); + } + + public void testConfigurationStoreLocation() + { + BrokerOptions options = startDummyMain("-sp abcd/config.xml"); + assertEquals("abcd/config.xml", options.getConfigurationStoreLocation()); + + options = startDummyMain("-store-path abcd/config2.xml"); + assertEquals("abcd/config2.xml", options.getConfigurationStoreLocation()); + } + + public void testConfigurationStoreType() + { + BrokerOptions options = startDummyMain("-st dby"); + assertEquals("dby", options.getConfigurationStoreType()); + + options = startDummyMain("-store-type bdb"); + assertEquals("bdb", options.getConfigurationStoreType()); + } + + public void testOverwriteConfigurationStore() + { + BrokerOptions options = startDummyMain("-os"); + assertTrue(options.isOverwriteConfigurationStore()); + + options = startDummyMain("-overwrite-store"); + assertTrue(options.isOverwriteConfigurationStore()); + } + + public void testLogConfig() + { + BrokerOptions options = startDummyMain("-l wxyz/log4j.xml"); + + assertEquals("wxyz/log4j.xml", options.getLogConfigFileLocation()); + } + + public void testLogWatch() + { + BrokerOptions options = startDummyMain("-w 9"); + + assertEquals(9, options.getLogWatchFrequency()); + } + + public void testVersion() + { + final TestMain main = new TestMain("-v".split("\\s")); + + assertNotNull("Command line not parsed correctly", main.getCommandLine()); + assertTrue("Parsed command line didnt pick up version option", main.getCommandLine().hasOption("v")); + } + + public void testHelp() + { + final TestMain main = new TestMain("-h".split("\\s")); + + assertNotNull("Command line not parsed correctly", main.getCommandLine()); + assertTrue("Parsed command line didnt pick up help option", main.getCommandLine().hasOption("h")); + } + + public void testInitailConfigurationLocation() + { + BrokerOptions options = startDummyMain("-icp abcd/initial-config.json"); + assertEquals("abcd/initial-config.json", options.getInitialConfigurationLocation()); + + options = startDummyMain("-initial-config-path abcd/initial-config.json"); + assertEquals("abcd/initial-config.json", options.getInitialConfigurationLocation()); + } + + public void testManagementMode() + { + BrokerOptions options = startDummyMain("-mm"); + assertTrue(options.isManagementMode()); + + options = startDummyMain("--management-mode"); + assertTrue(options.isManagementMode()); + } + + public void testManagementModeRmiPortOverride() + { + BrokerOptions options = startDummyMain("-mm -mmrmi 7777"); + assertTrue(options.isManagementMode()); + assertEquals(7777, options.getManagementModeRmiPortOverride()); + + options = startDummyMain("-mm --management-mode-rmi-registry-port 7777"); + assertTrue(options.isManagementMode()); + assertEquals(7777, options.getManagementModeRmiPortOverride()); + + options = startDummyMain("-mmrmi 7777"); + assertEquals(0, options.getManagementModeRmiPortOverride()); + } + + public void testManagementModeJmxPortOverride() + { + BrokerOptions options = startDummyMain("-mm -mmjmx 8888"); + assertTrue(options.isManagementMode()); + assertEquals(8888, options.getManagementModeJmxPortOverride()); + + options = startDummyMain("-mm --management-mode-jmx-connector-port 8888"); + assertTrue(options.isManagementMode()); + assertEquals(8888, options.getManagementModeJmxPortOverride()); + + options = startDummyMain("-mmjmx 8888"); + assertEquals(0, options.getManagementModeJmxPortOverride()); + } + + public void testManagementModeHttpPortOverride() + { + BrokerOptions options = startDummyMain("-mm -mmhttp 9999"); + assertTrue(options.isManagementMode()); + assertEquals(9999, options.getManagementModeHttpPortOverride()); + + options = startDummyMain("-mm --management-mode-http-port 9999"); + assertTrue(options.isManagementMode()); + assertEquals(9999, options.getManagementModeHttpPortOverride()); + + options = startDummyMain("-mmhttp 9999"); + assertEquals(0, options.getManagementModeHttpPortOverride()); + } + + public void testManagementModePassword() + { + String password = getTestName(); + BrokerOptions options = startDummyMain("-mm -mmpass " + password); + assertTrue(options.isManagementMode()); + assertEquals(password, options.getManagementModePassword()); + + options = startDummyMain("-mm --management-mode-password " + password); + assertTrue(options.isManagementMode()); + assertEquals(password, options.getManagementModePassword()); + + options = startDummyMain("-mmpass " + password); + assertNotNull(options.getManagementModePassword()); + } + + public void testDefaultManagementModePassword() + { + BrokerOptions options = startDummyMain("-mm"); + assertTrue(options.isManagementMode()); + assertNotNull(options.getManagementModePassword()); + } + + public void testSetConfigProperties() + { + //short name + String newPort = "12345"; + BrokerOptions options = startDummyMain("-prop name=value -prop " + BrokerOptions.QPID_AMQP_PORT + "=" + newPort); + + Map<String, String> props = options.getConfigProperties(); + + assertEquals(newPort, props.get(BrokerOptions.QPID_AMQP_PORT)); + assertEquals("value", props.get("name")); + + //long name + newPort = "678910"; + options = startDummyMain("--config-property name2=value2 --config-property " + BrokerOptions.QPID_AMQP_PORT + "=" + newPort); + + props = options.getConfigProperties(); + + assertEquals(newPort, props.get(BrokerOptions.QPID_AMQP_PORT)); + assertEquals("value2", props.get("name2")); + } + + public void testSetConfigPropertiesInvalidFormat() + { + //missing equals + startDummyMain("-prop namevalue"); + assertTrue("expected exception did not occur", + _startupException instanceof IllegalArgumentException); + + //no name specified + startDummyMain("-prop =value"); + assertTrue("expected exception did not occur", + _startupException instanceof IllegalArgumentException); + } + + private BrokerOptions startDummyMain(String commandLine) + { + return (new TestMain(commandLine.split("\\s"))).getOptions(); + } + + private class TestMain extends Main + { + private BrokerOptions _options; + + public TestMain(String[] args) + { + super(args); + } + + @Override + protected void execute() + { + try + { + super.execute(); + } + catch(Exception re) + { + MainTest.this._startupException = re; + } + } + + @Override + protected void startBroker(BrokerOptions options) + { + _options = options; + } + + @Override + protected void setExceptionHandler() + { + } + + public BrokerOptions getOptions() + { + return _options; + } + + public CommandLine getCommandLine() + { + return _commandLine; + } + } +} |
