diff options
author | Kim van der Riet <kpvdr@apache.org> | 2013-02-28 16:14:30 +0000 |
---|---|---|
committer | Kim van der Riet <kpvdr@apache.org> | 2013-02-28 16:14:30 +0000 |
commit | 9c73ef7a5ac10acd6a50d5d52bd721fc2faa5919 (patch) | |
tree | 2a890e1df09e5b896a9b4168a7b22648f559a1f2 /java/broker | |
parent | 172d9b2a16cfb817bbe632d050acba7e31401cd2 (diff) | |
download | qpid-python-asyncstore.tar.gz |
Update from trunk r1375509 through r1450773asyncstore
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/asyncstore@1451244 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/broker')
410 files changed, 18231 insertions, 25029 deletions
diff --git a/java/broker/bin/qpid-server b/java/broker/bin/qpid-server index 382004c9f5..206ae6a225 100755 --- a/java/broker/bin/qpid-server +++ b/java/broker/bin/qpid-server @@ -33,8 +33,8 @@ if [ -z "$QPID_PNAME" ]; then export QPID_PNAME=" -DPNAME=QPBRKR" fi -# Set classpath to include the qpid-all manifest jar, and any jars supplied in lib/opt -QPID_LIBS="$QPID_HOME/lib/qpid-all.jar:$QPID_HOME/lib/opt/*" +# 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 \ diff --git a/java/broker/bin/qpid-server.bat b/java/broker/bin/qpid-server.bat index 6b7bbcb96e..0d0355c44a 100644 --- a/java/broker/bin/qpid-server.bat +++ b/java/broker/bin/qpid-server.bat @@ -76,8 +76,8 @@ echo Using CLASSPATH: %CLASSPATH% goto afterQpidClasspath
:noQpidClasspath
-echo Warning: Qpid classpath not set. CLASSPATH set to %QPID_HOME%\lib\qpid-all.jar
-set CLASSPATH=%QPID_HOME%\lib\qpid-all.jar;%QPID_HOME%\lib\opt\*
+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
diff --git a/java/broker/build.xml b/java/broker/build.xml index 938066728e..8581b7c639 100644 --- a/java/broker/build.xml +++ b/java/broker/build.xml @@ -20,7 +20,7 @@ --> <project name="AMQ Broker" default="build"> <property name="module.depends" value="management/common common amqp-1-0-common"/> - <property name="module.test.depends" value="common/test" /> + <property name="module.test.depends" value="common/tests" /> <property name="module.main" value="org.apache.qpid.server.Main"/> <property name="module.genpom" value="true"/> @@ -28,23 +28,7 @@ <property name="output.dir" value="${module.precompiled}/org/apache/qpid/server/filter/jms/selector"/> - <property name="qmf.input.file" value="${project.root}/../specs/management-schema.xml"/> - <property name="qmf.xsl.file" value="${project.root}/broker/src/xsl/qmf.xsl"/> - <property name="qmf.output.dir" value="${module.precompiled}/org/apache/qpid/qmf/schema"/> - <property name="qmf.output.file" value="BrokerSchema.java"/> - - <target name="precompile" depends="gen_logging,gen_qmf"/> - - <target name="check_qmf_deps"> - <uptodate property="gen_qmf.notRequired" targetfile="${qmf.output.dir}/${qmf.output.file}"> - <srcfiles file="${qmf.input.file}"/> - <srcfiles file="${qmf.xsl.file}"/> - </uptodate> - </target> - - <target name="gen_qmf" depends="check_qmf_deps" unless="gen_qmf.notRequired"> - <xslt in="${qmf.input.file}" out="${qmf.output.dir}/${qmf.output.file}" style="${qmf.xsl.file}"/> - </target> + <target name="precompile" depends="gen_logging"/> <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"> @@ -64,9 +48,15 @@ <fixcrlf srcdir="${module.release}/bin" fixlast="true" eol="dos" includes="*.bat"/> </target> - <target name="release-bin-other" depends="release-bin-other-bdbstore" description="copy broker-plugins into module release"> + <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.lib}/plugins"/> + <fileset dir="${build.scratch.broker.plugins.lib}"/> </copy> </target> diff --git a/java/broker/etc/broker_example.acl b/java/broker/etc/broker_example.acl index 45a48bda09..fc650801c8 100644 --- a/java/broker/etc/broker_example.acl +++ b/java/broker/etc/broker_example.acl @@ -19,24 +19,20 @@ ### EXAMPLE ACL V2 FILE ### NOTE: Rules are considered from top to bottom, and the first matching rule governs the decision. - -### DEFINE GROUPS ### - -#Define a 'messaging-users' group with users 'client' and 'server' in it -GROUP messaging-users client server - -#Define a group for management web console users -GROUP webadmins webadmin +### Rules may refer to users or groups. Groups are currently defined in the etc/groups file. ### JMX MANAGEMENT #### -# Allow everyone to perform read operations on the ServerInformation mbean -# This is used for items such as querying the management API and broker release versions. -ACL ALLOW ALL ACCESS METHOD component="ServerInformation" +# To use JMX management, first give the user/group ACCESS MANAGEMENT permission +ACL ALLOW administrators ACCESS MANAGEMENT +ACL ALLOW guest ACCESS MANAGEMENT -# Allow 'admin' all management operations. To reduce log file noise, only non-read-only operations are logged. -ACL ALLOW admin ACCESS METHOD -ACL ALLOW-LOG admin ALL METHOD +# 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" @@ -49,17 +45,61 @@ 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 (using ALLOW rather than ALLOW-LOG to reduce log file noise) -# on the mbeans not listed in the DENY rules above +# 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 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 + +# 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" -#Example permissions for request-response based messaging. +# 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" -#Allow 'messaging-users' group to connect to the virtualhost +# 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" @@ -77,24 +117,8 @@ 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*" -# 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 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 UPDATE METHOD - -# 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" ### DEFAULT ### -#Deny all users from performing all operations +# Deny all users from performing all operations ACL DENY-LOG all all diff --git a/java/broker/etc/config.xml b/java/broker/etc/config.xml deleted file mode 100644 index 08c7c23d13..0000000000 --- a/java/broker/etc/config.xml +++ /dev/null @@ -1,106 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!-- - - - - 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. - - - --> -<broker> - <prefix>${QPID_HOME}</prefix> - <work>${QPID_WORK}</work> - <conf>${prefix}/etc</conf> - - <plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory> - <cache-directory>${QPID_WORK}/cache</cache-directory> - - <connector> - <!-- To enable SSL edit the keystorePath and keystorePassword - and set enabled to true. - To disable Non-SSL port set sslOnly to true --> - <ssl> - <enabled>false</enabled> - <port>5671</port> - <sslOnly>false</sslOnly> - <keyStorePath>/path/to/keystore.ks</keyStorePath> - <keyStorePassword>keystorepass</keyStorePassword> - </ssl> - <port>5672</port> - <socketReceiveBuffer>262144</socketReceiveBuffer> - <socketSendBuffer>262144</socketSendBuffer> - </connector> - <management> - <enabled>true</enabled> - <jmxport> - <registryServer>8999</registryServer> - <!-- - If unspecified, connectorServer defaults to 100 + registryServer port. - <connectorServer>9099</connectionServer> - --> - </jmxport> - <ssl> - <enabled>false</enabled> - <!-- Update below path to your keystore location. --> - <keyStorePath>${conf}/qpid.keystore</keyStorePath> - <keyStorePassword>password</keyStorePassword> - </ssl> - <https> - <enabled>false</enabled> - </https> - </management> - <advanced> - <framesize>65535</framesize> - <locale>en_US</locale> - </advanced> - - <security> - <pd-auth-manager> - <principal-database> - <class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class> - <attributes> - <attribute> - <name>passwordFile</name> - <value>${conf}/passwd</value> - </attribute> - </attributes> - </principal-database> - </pd-auth-manager> - - <!-- By default, all authenticated users have permissions to perform all actions --> - - <!-- ACL Example - This example illustrates securing the both Management (JMX) and Messaging. - <acl>${conf}/broker_example.acl</acl> - --> - - <msg-auth>false</msg-auth> - </security> - - <virtualhosts>${conf}/virtualhosts.xml</virtualhosts> - - <heartbeat> - <delay>0</delay> - <timeoutFactor>2.0</timeoutFactor> - </heartbeat> - <queue> - <auto_register>true</auto_register> - </queue> - - <status-updates>ON</status-updates> - -</broker> - - diff --git a/java/broker/etc/groups b/java/broker/etc/groups new file mode 100644 index 0000000000..e3912ece99 --- /dev/null +++ b/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/java/broker/etc/log4j.xml b/java/broker/etc/log4j.xml index b1b31248c1..71a13875a1 100644 --- a/java/broker/etc/log4j.xml +++ b/java/broker/etc/log4j.xml @@ -68,7 +68,7 @@ <param name="backupFilesToPath" value="${QPID_WORK}/backup/log"/> <layout class="org.apache.log4j.PatternLayout"> - <param name="ConversionPattern" value="%d %-5p [%t] (%F:%L) - %m%n"/> + <param name="ConversionPattern" value="%d %-5p [%t] (%c{2}) - %m%n"/> </layout> </appender> @@ -77,20 +77,20 @@ <param name="Append" value="false"/> <layout class="org.apache.log4j.PatternLayout"> - <param name="ConversionPattern" value="%d %-5p [%t] (%F:%L) - %m%n"/> + <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] (%F:%L) - %m%n"/> + <param name="ConversionPattern" value="%d %-5p [%t] (%c{2}) - %m%n"/> </layout> </appender> <!-- Provide warnings to standard output --> - <category additivity="true" name="org.apache.qpid"> - <priority value="warn"/> - </category> + <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"> @@ -108,21 +108,14 @@ <level value="info"/> </logger> - <!-- Examples of additional logging settings --> - <!-- Used to generate extra debug. See debug.log4j.xml --> - - <!--<category additivity="true" name="org.apache.qpid.server.store"> - <priority value="debug"/> - </category--> - <!-- 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"/> + <level value="warn"/> </logger> <!-- Log all info events to file --> <root> - <priority value="info"/> + <level value="info"/> <appender-ref ref="FileAppender"/> <!--appender-ref ref="ArchivingFileAppender"/--> </root> diff --git a/java/broker/src/main/java/broker.bnd b/java/broker/src/main/java/broker.bnd index 4e799a1609..bf338543f7 100755 --- a/java/broker/src/main/java/broker.bnd +++ b/java/broker/src/main/java/broker.bnd @@ -17,7 +17,7 @@ # under the License. # -ver: 0.19.0 +ver: 0.21.0 Bundle-SymbolicName: qpid-broker Bundle-Version: ${ver} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java b/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java deleted file mode 100644 index 27ab580642..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java +++ /dev/null @@ -1,586 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.ExchangeConfigType; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.exchange.ExchangeReferrer; -import org.apache.qpid.server.exchange.ExchangeType; -import org.apache.qpid.server.exchange.topic.TopicExchangeResult; -import org.apache.qpid.server.exchange.topic.TopicMatcherResult; -import org.apache.qpid.server.exchange.topic.TopicNormalizer; -import org.apache.qpid.server.exchange.topic.TopicParser; -import org.apache.qpid.server.message.InboundMessage; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.virtualhost.HouseKeepingTask; -import org.apache.qpid.server.virtualhost.VirtualHost; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.atomic.AtomicLong; - -public class ManagementExchange implements Exchange, QMFService.Listener -{ - private static final AMQShortString QPID_MANAGEMENT = new AMQShortString("qpid.management"); - private static final AMQShortString QPID_MANAGEMENT_TYPE = new AMQShortString("management"); - - private VirtualHost _virtualHost; - - private final TopicParser _parser = new TopicParser(); - - private final Map<AMQShortString, TopicExchangeResult> _topicExchangeResults = - new ConcurrentHashMap<AMQShortString, TopicExchangeResult>(); - - private final Set<Binding> _bindingSet = new CopyOnWriteArraySet<Binding>(); - private UUID _id; - private UUID _qmfId; - private static final String AGENT_BANK = "0"; - - private int _bindingCountHigh; - private final AtomicLong _msgReceived = new AtomicLong(); - private final AtomicLong _bytesReceived = new AtomicLong(); - - private final CopyOnWriteArrayList<BindingListener> _listeners = new CopyOnWriteArrayList<Exchange.BindingListener>(); - - //TODO : persist creation time - private long _createTime = System.currentTimeMillis(); - - - private class ManagementQueue implements BaseQueue - { - private final UUID QUEUE_ID = UUIDGenerator.generateRandomUUID(); - private final String NAME_AS_STRING = "##__mgmt_pseudo_queue__##" + QUEUE_ID.toString(); - private final AMQShortString NAME_AS_SHORT_STRING = new AMQShortString(NAME_AS_STRING); - - public void enqueue(ServerMessage message) throws AMQException - { - long size = message.getSize(); - - ByteBuffer buf = ByteBuffer.allocate((int) size); - - int offset = 0; - - while(offset < size) - { - offset += message.getContent(buf,offset); - } - - buf.flip(); - QMFCommandDecoder commandDecoder = new QMFCommandDecoder(getQMFService(),buf); - QMFCommand cmd; - while((cmd = commandDecoder.decode()) != null) - { - cmd.process(_virtualHost, message); - } - - } - - public void enqueue(ServerMessage message, boolean sync, PostEnqueueAction action) throws AMQException - { - enqueue(message); - } - - public void enqueue(ServerMessage message, PostEnqueueAction action) throws AMQException - { - enqueue(message); - } - - public boolean isDurable() - { - return false; - } - - public AMQShortString getNameShortString() - { - return NAME_AS_SHORT_STRING; - } - - @Override - public UUID getId() - { - return QUEUE_ID; - } - } - - - private final ManagementQueue _mgmtQueue = new ManagementQueue(); - - public ManagementExchange() - { - } - - public static final ExchangeType<ManagementExchange> TYPE = new ExchangeType<ManagementExchange>() - { - - public AMQShortString getName() - { - return QPID_MANAGEMENT_TYPE; - } - - public Class<ManagementExchange> getExchangeClass() - { - return ManagementExchange.class; - } - - public ManagementExchange newInstance(UUID id, VirtualHost host, - AMQShortString name, - boolean durable, - int ticket, - boolean autoDelete) throws AMQException - { - ManagementExchange exch = new ManagementExchange(); - exch.initialise(id, host, name, durable, ticket, autoDelete); - return exch; - } - - public AMQShortString getDefaultExchangeName() - { - return QPID_MANAGEMENT; - } - }; - - - public AMQShortString getNameShortString() - { - return QPID_MANAGEMENT; - } - - public AMQShortString getTypeShortString() - { - return QPID_MANAGEMENT_TYPE; - } - - public void initialise(UUID id, VirtualHost host, AMQShortString name, boolean durable, int ticket, boolean autoDelete) - throws AMQException - { - if(!QPID_MANAGEMENT.equals(name)) - { - throw new AMQException("Can't create more than one Management exchange"); - } - _virtualHost = host; - _id = id; - _virtualHost.scheduleHouseKeepingTask(_virtualHost.getBroker().getManagementPublishInterval(), new UpdateTask(_virtualHost)); - _qmfId = getConfigStore().createId(); - getConfigStore().addConfiguredObject(this); - getQMFService().addListener(this); - } - - public UUID getId() - { - return _id; - } - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public ExchangeConfigType getConfigType() - { - return ExchangeConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return _virtualHost; - } - - public boolean isDurable() - { - return true; - } - - public VirtualHost getVirtualHost() - { - return _virtualHost; - } - - public String getName() - { - return QPID_MANAGEMENT.toString(); - } - - public ExchangeType getType() - { - return TYPE; - } - - public boolean isAutoDelete() - { - return false; - } - - public int getTicket() - { - return 0; - } - - public void close() throws AMQException - { - getConfigStore().removeConfiguredObject(this); - } - - public ConfigStore getConfigStore() - { - return getVirtualHost().getConfigStore(); - } - - public synchronized void addBinding(final Binding b) - { - - if(_bindingSet.add(b)) - { - AMQShortString routingKey = TopicNormalizer.normalize(new AMQShortString(b.getBindingKey())); - - TopicExchangeResult result = _topicExchangeResults.get(routingKey); - if(result == null) - { - result = new TopicExchangeResult(); - result.addUnfilteredQueue(b.getQueue()); - _parser.addBinding(routingKey, result); - _topicExchangeResults.put(routingKey,result); - } - else - { - result.addUnfilteredQueue(b.getQueue()); - } - - result.addBinding(b); - } - - for(BindingListener listener : _listeners) - { - listener.bindingAdded(this, b); - } - - if(_bindingSet.size() > _bindingCountHigh) - { - _bindingCountHigh = _bindingSet.size(); - } - - String bindingKey = b.getBindingKey(); - - if(bindingKey.startsWith("schema.") || bindingKey.startsWith("*.") || bindingKey.startsWith("#.")) - { - publishAllSchema(); - } - if(bindingKey.startsWith("console.") || bindingKey.startsWith("*.") || bindingKey.startsWith("#.")) - { - publishAllConsole(); - } - - } - - void publishAllConsole() - { - QMFService qmfService = getQMFService(); - - long sampleTime = System.currentTimeMillis(); - - for(QMFPackage pkg : qmfService.getSupportedSchemas()) - { - for(QMFClass qmfClass : pkg.getClasses()) - { - Collection<QMFObject> qmfObjects = qmfService.getObjects(qmfClass); - - publishObjectsToConsole(sampleTime, qmfObjects); - } - - } - - } - - private QMFService getQMFService() - { - return _virtualHost.getApplicationRegistry().getQMFService(); - } - - void publishObjectsToConsole(final long sampleTime, - final Collection<QMFObject> qmfObjects) - { - if(!qmfObjects.isEmpty() && hasBindings()) - { - QMFClass qmfClass = qmfObjects.iterator().next().getQMFClass(); - ArrayList<QMFCommand> commands = new ArrayList<QMFCommand>(); - - - for(QMFObject obj : qmfObjects) - { - commands.add(obj.asConfigInfoCmd(sampleTime)); - commands.add(obj.asInstrumentInfoCmd(sampleTime)); - } - - publishToConsole(qmfClass, commands); - } - } - - private void publishToConsole(final QMFClass qmfClass, final ArrayList<QMFCommand> commands) - { - if(!commands.isEmpty() && hasBindings()) - { - String routingKey = "console.obj.1." + AGENT_BANK + "." + qmfClass.getPackage().getName() + "." + qmfClass.getName(); - QMFMessage message = new QMFMessage(routingKey,commands.toArray(new QMFCommand[commands.size()])); - - Collection<TopicMatcherResult> results = _parser.parse(new AMQShortString(routingKey)); - HashSet<AMQQueue> queues = new HashSet<AMQQueue>(); - for(TopicMatcherResult result : results) - { - TopicExchangeResult res = (TopicExchangeResult)result; - - for(Binding b : res.getBindings()) - { - b.incrementMatches(); - } - - queues.addAll(((TopicExchangeResult)result).getUnfilteredQueues()); - } - for(AMQQueue queue : queues) - { - try - { - queue.enqueue(message); - } - catch (AMQException e) - { - throw new RuntimeException(e); - } - } - } - } - - void publishAllSchema() - { - - } - - public synchronized void removeBinding(final Binding binding) - { - if(_bindingSet.remove(binding)) - { - AMQShortString bindingKey = TopicNormalizer.normalize(new AMQShortString(binding.getBindingKey())); - TopicExchangeResult result = _topicExchangeResults.get(bindingKey); - result.removeBinding(binding); - result.removeUnfilteredQueue(binding.getQueue()); - } - - for(BindingListener listener : _listeners) - { - listener.bindingRemoved(this, binding); - } - } - - public synchronized Collection<Binding> getBindings() - { - return new ArrayList<Binding>(_bindingSet); - } - - public ArrayList<BaseQueue> route(InboundMessage message) - { - ArrayList<BaseQueue> queues = new ArrayList<BaseQueue>(1); - _msgReceived.incrementAndGet(); - _bytesReceived.addAndGet(message.getSize()); - queues.add(_mgmtQueue); - return queues; - } - - public boolean isBound(String bindingKey, Map<String, Object> arguments, AMQQueue queue) - { - return false; //TODO - } - - public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue) - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean isBound(AMQShortString routingKey, AMQQueue queue) - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean isBound(AMQShortString routingKey) - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean isBound(AMQQueue queue) - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean hasBindings() - { - return !_bindingSet.isEmpty(); - } - - public boolean isBound(String bindingKey, AMQQueue queue) - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean isBound(String bindingKey) - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public void addCloseTask(final Task task) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public void removeCloseTask(final Task task) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - - - public Exchange getAlternateExchange() - { - return null; - } - - public Map<String, Object> getArguments() - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - public void setAlternateExchange(Exchange exchange) - { - - } - - public void removeReference(ExchangeReferrer exchange) - { - } - - public void addReference(ExchangeReferrer exchange) - { - } - - public boolean hasReferrers() - { - return true; - } - - - - private class UpdateTask extends HouseKeepingTask - { - public UpdateTask(VirtualHost vhost) - { - super(vhost); - } - - public void execute() - { - publishAllConsole(); - publishAllSchema(); - } - - } - - public void objectCreated(final QMFObject obj) - { - publishObjectsToConsole(System.currentTimeMillis(), Collections.singleton(obj)); - } - - public void objectDeleted(final QMFObject obj) - { - publishObjectsToConsole(System.currentTimeMillis(), Collections.singleton(obj)); - } - - public long getBindingCount() - { - return getBindings().size(); - } - - public long getBindingCountHigh() - { - return _bindingCountHigh; - } - - public long getMsgReceives() - { - return _msgReceived.get(); - } - - public long getMsgRoutes() - { - return getMsgReceives(); - } - - public long getMsgDrops() - { - return 0l; - } - - public long getByteReceives() - { - return _bytesReceived.get(); - } - - public long getByteRoutes() - { - return getByteReceives(); - } - - public long getByteDrops() - { - return 0l; - } - - public long getCreateTime() - { - return _createTime; - } - - public void addBindingListener(final BindingListener listener) - { - _listeners.add(listener); - } - - public void removeBindingListener(final BindingListener listener) - { - _listeners.remove(listener); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java deleted file mode 100644 index 69284abc48..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBDecoder; - -import java.util.List; - -public class QMFBrokerRequestCommand extends QMFCommand -{ - - private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf"); - - - public QMFBrokerRequestCommand(QMFCommandHeader header, BBDecoder buf) - { - super(header); - } - - public void process(VirtualHost virtualHost, ServerMessage message) - { - String exchangeName = message.getMessageHeader().getReplyToExchange(); - String queueName = message.getMessageHeader().getReplyToRoutingKey(); - - _qmfLogger.debug("Execute: " + this); - - QMFCommand[] commands = new QMFCommand[2]; - commands[0] = new QMFBrokerResponseCommand(this, virtualHost); - commands[1] = new QMFCommandCompletionCommand(this); - - Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName); - - for(QMFCommand cmd : commands) - { - QMFMessage responseMessage = new QMFMessage(queueName, cmd); - - - List<? extends BaseQueue> queues = exchange.route(responseMessage); - - - for(BaseQueue q : queues) - { - try - { - q.enqueue(responseMessage); - } - catch (AMQException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - } - } - - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java deleted file mode 100644 index 7d566567a1..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * - * 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.qmf; - -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -abstract public class QMFClass -{ - - - public enum Type - { - OBJECT((byte)1), - EVENT((byte)2); - - private final byte _value; - - Type(byte value) - { - _value = value; - } - - public byte getValue() - { - return _value; - } - } - - private final Type _type; - private QMFPackage _package; - private final String _name; - private byte[] _schemaHash; - - private Map<String, QMFProperty> _properties = new LinkedHashMap<String, QMFProperty>(); - private Map<String, QMFStatistic> _statistics = new LinkedHashMap<String, QMFStatistic>(); - private Map<String, QMFMethod> _methods = new LinkedHashMap<String, QMFMethod>(); - - - - public QMFClass(Type type, String name, byte[] schemaHash, List<QMFProperty> properties, - List<QMFStatistic> statistics, List<QMFMethod> methods) - { - this(type, name, schemaHash); - setProperties(properties); - setStatistics(statistics); - setMethods(methods); - } - - - public QMFClass(Type type, String name, byte[] schemaHash) - - { - _type = type; - _name = name; - _schemaHash = schemaHash; - - } - - protected void setProperties(List<QMFProperty> properties) - { - for(QMFProperty prop : properties) - { - _properties.put(prop.getName(), prop); - } - } - - protected void setStatistics(List<QMFStatistic> statistics) - { - for(QMFStatistic stat : statistics) - { - _statistics.put(stat.getName(), stat); - } - } - - - protected void setMethods(List<QMFMethod> methods) - { - for(QMFMethod method : methods) - { - _methods.put(method.getName(), method); - } - } - - public void setPackage(QMFPackage aPackage) - { - _package = aPackage; - for(QMFProperty prop : _properties.values()) - { - prop.setQMFClass(this); - } - // TODO Statisics, Methods - } - - public Type getType() - { - return _type; - } - - public QMFPackage getPackage() - { - return _package; - } - - public String getName() - { - return _name; - } - - public byte[] getSchemaHash() - { - return _schemaHash; - } - - public Collection<QMFProperty> getProperties() - { - return _properties.values(); - } - - public Collection<QMFStatistic> getStatistics() - { - return _statistics.values(); - } - - public Collection<QMFMethod> getMethods() - { - return _methods.values(); - } - - public QMFMethod getMethod(String methodName) - { - return _methods.get(methodName); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java deleted file mode 100644 index 5676bb7306..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBDecoder; - -import java.util.Collection; -import java.util.List; - -public class QMFClassQueryCommand extends QMFCommand -{ - private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf"); - - - private final String _package; - - public QMFClassQueryCommand(QMFCommandHeader header, BBDecoder decoder) - { - super(header); - _package = decoder.readStr8(); - } - - public void process(VirtualHost virtualHost, ServerMessage message) - { - String exchangeName = message.getMessageHeader().getReplyToExchange(); - String routingKey = message.getMessageHeader().getReplyToRoutingKey(); - - _qmfLogger.debug("Execute: " + this); - - IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry(); - QMFService service = appRegistry.getQMFService(); - - QMFPackage qmfPackage = service.getPackage(_package); - Collection<QMFClass> qmfClasses = qmfPackage.getClasses(); - - QMFCommand[] commands = new QMFCommand[ qmfClasses.size() + 1 ]; - - int i = 0; - for(QMFClass qmfClass : qmfClasses) - { - commands[i++] = new QMFClassIndicationCommand(this, qmfClass); - } - commands[ commands.length - 1 ] = new QMFCommandCompletionCommand(this); - - - for(QMFCommand cmd : commands) - { - - - QMFMessage responseMessage = new QMFMessage(routingKey, cmd); - - Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName); - - List<? extends BaseQueue> queues = exchange.route(responseMessage); - - for(BaseQueue q : queues) - { - try - { - q.enqueue(responseMessage); - } - catch (AMQException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - } - } - - - @Override - public String toString() - { - return "QMFClassQueryCommand{" + - "package='" + _package + '\'' + - '}'; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java deleted file mode 100644 index 397ad4090e..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.qpid.transport.codec.BBEncoder; - -public class QMFCommandCompletionCommand extends QMFCommand -{ - - private final CompletionCode _status; - private final String _text; - - public QMFCommandCompletionCommand(QMFCommand command) - { - this(command, CompletionCode.OK, ""); - } - public QMFCommandCompletionCommand(QMFCommand command, CompletionCode status, String text) - { - super( new QMFCommandHeader(command.getHeader().getVersion(), - command.getHeader().getSeq(), - QMFOperation.COMMAND_COMPLETION)); - - _status = status; - _text = text; - } - - - @Override - public void encode(BBEncoder encoder) - { - super.encode(encoder); - encoder.writeInt32(_status.ordinal()); - encoder.writeStr8(_text); - } - - @Override - public String toString() - { - return "QMFCommandCompletionCommand{" + - "status=" + _status + - ",text='" + _text + '\'' + - '}'; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandDecoder.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandDecoder.java deleted file mode 100644 index ac036dfa19..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandDecoder.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.qpid.transport.codec.BBDecoder; - -import java.nio.ByteBuffer; - -public class QMFCommandDecoder -{ - private BBDecoder _decoder; - - - private static final QMFOperation[] OP_CODES = new QMFOperation[256]; - private final QMFService _qmfService; - - static - { - for(QMFOperation op : QMFOperation.values()) - { - OP_CODES[op.getOpcode()] = op; - } - } - - public QMFCommandDecoder(final QMFService qmfService, ByteBuffer buf) - { - _qmfService = qmfService; - _decoder = new BBDecoder(); - _decoder.init(buf); - } - - public QMFCommand decode() - { - if(_decoder.hasRemaining()) - { - QMFCommandHeader header = readQMFHeader(); - - switch(header.getOperation()) - { - case BROKER_REQUEST: - return new QMFBrokerRequestCommand(header, _decoder); - case PACKAGE_QUERY: - return new QMFPackageQueryCommand(header, _decoder); - case CLASS_QUERY: - return new QMFClassQueryCommand(header, _decoder); - case SCHEMA_REQUEST: - return new QMFSchemaRequestCommand(header, _decoder); - case METHOD_REQUEST: - return new QMFMethodRequestCommand(header, _decoder, _qmfService); - case GET_QUERY: - return new QMFGetQueryCommand(header, _decoder); - default: - System.out.println("Unknown command"); - - } - - return null; - } - else - { - return null; - } - } - - private QMFCommandHeader readQMFHeader() - { - if(_decoder.readInt8() == (byte) 'A' - && _decoder.readInt8() == (byte) 'M') - { - byte version = _decoder.readInt8(); - short opCode = _decoder.readUint8(); - int seq = _decoder.readInt32(); - - return new QMFCommandHeader(version, seq, OP_CODES[opCode]); - - } - return null; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandHeader.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandHeader.java deleted file mode 100644 index c4d771317f..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandHeader.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.qpid.transport.codec.BBEncoder; - -public class QMFCommandHeader -{ - private final byte _version; - private final int _seq; - - private final QMFOperation _operation; - - public QMFCommandHeader(byte version, int seq, QMFOperation operation) - { - _version = version; - _seq = seq; - _operation = operation; - } - - public byte getVersion() - { - return _version; - } - - public int getSeq() - { - return _seq; - } - - public QMFOperation getOperation() - { - return _operation; - } - - public void encode(BBEncoder encoder) - { - encoder.writeUint8((short)'A'); - encoder.writeUint8((short)'M'); - encoder.writeInt8(_version); - encoder.writeUint8((short)_operation.getOpcode()); - encoder.writeInt32(_seq); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java deleted file mode 100644 index b1f958d4ba..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBDecoder; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -public class QMFGetQueryCommand extends QMFCommand -{ - - private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf"); - - private String _className; - private String _packageName; - private UUID _objectId; - - public QMFGetQueryCommand(QMFCommandHeader header, BBDecoder decoder) - { - super(header); - - Map<String, Object> _map = decoder.readMap(); - _className = (String) _map.get("_class"); - _packageName = (String) _map.get("_package"); - byte[] objectIdBytes = (byte[]) _map.get("_objectId"); - - if(objectIdBytes != null) - { - long msb = 0; - long lsb = 0; - - for (int i = 0; i != 8; i++) - { - msb = (msb << 8) | (objectIdBytes[i] & 0xff); - } - for (int i = 8; i != 16; i++) - { - lsb = (lsb << 8) | (objectIdBytes[i] & 0xff); - } - _objectId = new UUID(msb, lsb); - } - else - { - _objectId = null; - } - - - } - - public void process(VirtualHost virtualHost, ServerMessage message) - { - String exchangeName = message.getMessageHeader().getReplyToExchange(); - String routingKey = message.getMessageHeader().getReplyToRoutingKey(); - - IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry(); - QMFService service = appRegistry.getQMFService(); - - _qmfLogger.debug("Execute: " + this); - - List<QMFCommand> commands = new ArrayList<QMFCommand>(); - final long sampleTime = System.currentTimeMillis() * 1000000l; - - Collection<QMFPackage> packages; - - if(_packageName != null && _packageName.length() != 0) - { - QMFPackage qmfPackage = service.getPackage(_packageName); - if(qmfPackage == null) - { - packages = Collections.EMPTY_LIST; - } - else - { - packages = Collections.singleton(qmfPackage); - } - } - else - { - packages = service.getSupportedSchemas(); - } - - for(QMFPackage qmfPackage : packages) - { - - Collection<QMFClass> qmfClasses; - - if(_className != null && _className.length() != 0) - { - QMFClass qmfClass = qmfPackage.getQMFClass(_className); - if(qmfClass == null) - { - qmfClasses = Collections.EMPTY_LIST; - } - else - { - qmfClasses = Collections.singleton(qmfClass); - } - } - else - { - qmfClasses = qmfPackage.getClasses(); - } - - - for(QMFClass qmfClass : qmfClasses) - { - Collection<QMFObject> objects; - - if(_objectId != null) - { - QMFObject obj = service.getObjectById(qmfClass, _objectId); - if(obj == null) - { - objects = Collections.EMPTY_LIST; - } - else - { - objects = Collections.singleton(obj); - } - } - else - { - objects = service.getObjects(qmfClass); - } - - for(QMFObject object : objects) - { - - commands.add(object.asGetQueryResponseCmd(this, sampleTime)); - } - } - - - } - - - commands.add( new QMFCommandCompletionCommand(this)); - - - for(QMFCommand cmd : commands) - { - - _qmfLogger.debug("Respond: " + cmd); - QMFMessage responseMessage = new QMFMessage(routingKey, cmd); - - Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName); - - List<? extends BaseQueue> queues = exchange.route(responseMessage); - - for(BaseQueue q : queues) - { - try - { - q.enqueue(responseMessage); - } - catch (AMQException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - } - } - - @Override - public String toString() - { - return "QMFGetQueryCommand{" + - "packageName='" + _packageName + '\'' + - ", className='" + _className + '\'' + - ", objectId=" + _objectId + - '}'; - } -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java deleted file mode 100644 index 1b173c7e11..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * - * 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.qmf; - -import java.util.Collection; -import java.util.Collections; -import org.apache.commons.lang.NotImplementedException; - -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.configuration.SessionConfig; -import org.apache.qpid.server.message.AMQMessageHeader; -import org.apache.qpid.server.message.InboundMessage; -import org.apache.qpid.server.message.MessageReference; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.store.StoredMessage; -import org.apache.qpid.transport.codec.BBEncoder; - -import java.nio.ByteBuffer; -import java.util.Set; - -public class QMFMessage implements ServerMessage, InboundMessage, AMQMessageHeader -{ - - private ByteBuffer _content; - private String _routingKey; - - public QMFMessage(String routingKey, QMFCommand command) - { - this(routingKey, new QMFCommand[] { command }); - } - - - public QMFMessage(String routingKey, QMFCommand[] commands) - { - _routingKey = routingKey; - BBEncoder encoder = new BBEncoder(256); - - for(QMFCommand cmd : commands) - { - cmd.encode(encoder); - } - - - _content = encoder.buffer(); - } - - public String getRoutingKey() - { - return _routingKey; - } - - public AMQShortString getRoutingKeyShortString() - { - return AMQShortString.valueOf(_routingKey); - } - - public AMQMessageHeader getMessageHeader() - { - return this; - } - - public StoredMessage getStoredMessage() - { - throw new NotImplementedException(); - } - - public boolean isPersistent() - { - return false; - } - - public boolean isRedelivered() - { - return false; - } - - public long getSize() - { - return _content.limit(); - } - - public boolean isImmediate() - { - return false; - } - - public String getCorrelationId() - { - return null; - } - - public long getExpiration() - { - return 0; - } - - public String getUserId() - { - return null; - } - - public String getAppId() - { - return null; - } - - public String getMessageId() - { - return null; - } - - public String getMimeType() - { - return null; - } - - public String getEncoding() - { - return null; - } - - public byte getPriority() - { - return 4; - } - - public long getTimestamp() - { - return 0; - } - - public String getType() - { - return null; - } - - public String getReplyTo() - { - return null; - } - - public String getReplyToExchange() - { - return null; - } - - public String getReplyToRoutingKey() - { - return null; - } - - public Object getHeader(String name) - { - return null; - } - - public boolean containsHeaders(Set<String> names) - { - return false; - } - - @Override - public Collection<String> getHeaderNames() - { - return Collections.EMPTY_SET; - } - - public boolean containsHeader(String name) - { - return false; - } - - public MessageReference newReference() - { - return new QMFMessageReference(this); - } - - public long getMessageNumber() - { - return 0l; - } - - public long getArrivalTime() - { - return 0; - } - - public int getContent(ByteBuffer buf, int offset) - { - ByteBuffer src = _content.duplicate(); - src.position(offset); - src = src.slice(); - int len = src.remaining(); - if(len > buf.remaining()) - { - len = buf.remaining(); - } - - buf.put(src); - - return len; - } - - - public ByteBuffer getContent(int offset, int size) - { - ByteBuffer src = _content.duplicate(); - src.position(offset); - src = src.slice(); - src.limit(size); - return src; - } - - private static class QMFMessageReference extends MessageReference<QMFMessage> - { - public QMFMessageReference(QMFMessage message) - { - super(message); - } - - protected void onReference(QMFMessage message) - { - - } - - protected void onRelease(QMFMessage message) - { - - } - } - - public SessionConfig getSessionConfig() - { - return null; - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java deleted file mode 100644 index 1d1cd24724..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.qpid.transport.codec.BBDecoder; -import org.apache.qpid.transport.codec.Encoder; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; - -public abstract class QMFMethod<T extends QMFObject> -{ - private final LinkedHashMap<String,Object> _map = new LinkedHashMap<String,Object>(); - private final List<Argument> _arguments = new ArrayList<Argument>(); - - private static final String NAME = "name"; - private static final String TYPE = "type"; - private static final String REF_PACKAGE = "refPackage"; - private static final String REF_CLASS = "refClass"; - private static final String UNIT = "unit"; - private static final String MIN = "min"; - private static final String MAX = "max"; - private static final String MAX_LENGTH = "maxlen"; - private static final String DESCRIPTION = "desc"; - private static final String DEFAULT = "default"; - private static final String DIRECTION = "dir"; - private static final String ARG_COUNT = "argCount"; - - - - public enum Direction - { - I, - O, - IO; - } - - public class Argument - { - private final LinkedHashMap<String,Object> _map = new LinkedHashMap<String,Object>(); - - public Argument(String name, QMFType type) - { - _map.put(NAME, name); - _map.put(TYPE, type.codeValue()); - } - - public void setRefPackage(String refPackage) - { - _map.put(REF_PACKAGE, refPackage); - } - - public void setRefClass(String refClass) - { - _map.put(REF_CLASS, refClass); - } - - public void setUnit(String unit) - { - _map.put(UNIT, unit); - } - - public void setMax(Number max) - { - _map.put(MAX, max); - } - - public void setMin(Number min) - { - _map.put(MIN, min); - } - - public void setMaxLength(int len) - { - _map.put(MAX_LENGTH, len); - } - - public void setDefault(Object dflt) - { - _map.put(DEFAULT, dflt); - } - - public void setDescription(String desc) - { - _map.put(DESCRIPTION, desc); - } - - public void setDirection(Direction direction) - { - _map.put(DIRECTION, direction.toString()); - } - - public void encode(Encoder encoder) - { - encoder.writeMap(_map); - } - - public String getName() - { - return (String) _map.get(NAME); - } - } - - public QMFMethod(String name, String description) - { - _map.put(NAME, name); - _map.put(ARG_COUNT, 0); - if(description != null) - { - _map.put(DESCRIPTION, description); - } - - } - - abstract public QMFMethodInvocation<T> parse(final BBDecoder decoder); - - protected void addArgument(Argument arg) - { - _arguments.add(arg); - _map.put(ARG_COUNT, _arguments.size()); - } - - - public void encode(Encoder encoder) - { - encoder.writeMap(_map); - for(Argument arg : _arguments) - { - arg.encode(encoder); - } - } - - public String getName() - { - return (String) _map.get(NAME); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodInvocation.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodInvocation.java deleted file mode 100644 index 5348c2783f..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodInvocation.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * - * 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.qmf; - -public interface QMFMethodInvocation<T extends QMFObject> -{ - QMFMethodResponseCommand execute(T obj, QMFMethodRequestCommand cmd); -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java deleted file mode 100644 index 1a4ce228b5..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBDecoder; - -import java.util.List; -import java.util.UUID; - -public class QMFMethodRequestCommand extends QMFCommand -{ - private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf"); - - private QMFMethodInvocation _methodInstance; - private QMFObject _object; - - public QMFMethodRequestCommand(final QMFCommandHeader header, final BBDecoder decoder, final QMFService qmfService) - { - super(header); - UUID objectId = decoder.readUuid(); - String packageName = decoder.readStr8(); - String className = decoder.readStr8(); - byte[] hash = decoder.readBin128(); - String methodName = decoder.readStr8(); - - QMFPackage qmfPackage = qmfService.getPackage(packageName); - QMFClass qmfClass = qmfPackage.getQMFClass(className); - _object = qmfService.getObjectById(qmfClass, objectId); - QMFMethod method = qmfClass.getMethod(methodName); - _methodInstance = method.parse(decoder); - - } - - public void process(final VirtualHost virtualHost, final ServerMessage message) - { - String exchangeName = message.getMessageHeader().getReplyToExchange(); - String queueName = message.getMessageHeader().getReplyToRoutingKey(); - - QMFCommand[] commands = new QMFCommand[2]; - - _qmfLogger.debug("Execute: " + _methodInstance + " on " + _object); - - commands[0] = _methodInstance.execute(_object, this); - commands[1] = new QMFCommandCompletionCommand(this); - - Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName); - - for(QMFCommand cmd : commands) - { - QMFMessage responseMessage = new QMFMessage(queueName, cmd); - - - List<? extends BaseQueue> queues = exchange.route(responseMessage); - - - for(BaseQueue q : queues) - { - try - { - q.enqueue(responseMessage); - } - catch (AMQException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - } - - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodResponseCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodResponseCommand.java deleted file mode 100644 index 5fea014ad8..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodResponseCommand.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.qpid.transport.codec.BBEncoder; - -public class QMFMethodResponseCommand extends QMFCommand -{ - private CompletionCode _status = null; - private String _msg = null; - - public QMFMethodResponseCommand(final QMFMethodRequestCommand cmd, - CompletionCode status, - String msg) - { - super( new QMFCommandHeader(cmd.getHeader().getVersion(), - cmd.getHeader().getSeq(), - QMFOperation.METHOD_RESPONSE)); - - if(status == null) - { - _status = CompletionCode.OK; - } - else - { - _status = status; - } - - _msg = msg; - } - - public CompletionCode getStatus() - { - return _status; - } - - public String getStatusText() - { - return _msg; - } - - @Override - public void encode(final BBEncoder encoder) - { - super.encode(encoder); - - encoder.writeUint32(_status.ordinal()); - - if(_msg == null) - { - encoder.writeStr16(_status.toString()); - } - else - { - encoder.writeStr16(_msg); - } - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java deleted file mode 100644 index c3604dca44..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * 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.qmf; - -import java.util.UUID; - -public abstract class QMFObject<C extends QMFClass, D extends QMFObject.Delegate> -{ - private long _deleteTime; - - public interface Delegate - { - UUID getQMFId(); - long getCreateTime(); - } - - - private D _delegate; - - protected QMFObject(D delegate) - { - _delegate = delegate; - } - - public D getDelegate() - { - return _delegate; - } - - abstract public C getQMFClass(); - - public final UUID getId() - { - return _delegate.getQMFId(); - } - - public final long getCreateTime() - { - return _delegate.getCreateTime(); - } - - public final void setDeleteTime() - { - _deleteTime = System.currentTimeMillis(); - } - - public final long getDeleteTime() - { - return _deleteTime; - } - - - - abstract public QMFCommand asConfigInfoCmd(long sampleTime); - abstract public QMFCommand asInstrumentInfoCmd(long sampleTime); - abstract public QMFCommand asGetQueryResponseCmd(final QMFGetQueryCommand queryCommand, long sampleTime); - - @Override - public String toString() - { - return _delegate.toString(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFOperation.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFOperation.java deleted file mode 100644 index 6736b5d460..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFOperation.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * 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.qmf; - -public enum QMFOperation -{ - - - BROKER_REQUEST('B'), - BROKER_RESPONSE('b'), // This message contains a broker response, sent from the broker in response to a broker request message. - COMMAND_COMPLETION('z'), // This message is sent to indicate the completion of a request. - CLASS_QUERY('Q'), // Class query messages are used by a management console to request a list of schema classes that are known by the management broker. - CLASS_INDICATION('q'), // Sent by the management broker, a class indication notifies the peer of the existence of a schema class. - SCHEMA_REQUEST('S'), // Schema request messages are used to request the full schema details for a class. - SCHEMA_RESPONSE('s'), // Schema response message contain a full description of the schema for a class. - HEARTBEAT_INDEICATION('h'), // This message is published once per publish-interval. It can be used by a client to positively determine which objects did not change during the interval (since updates are not published for objects with no changes). - CONFIG_INDICATION('c'), - INSTRUMENTATION_INDICATION('i'), - GET_QUERY_RESPONSE('g'), // This message contains a content record. Content records contain the values of all properties or statistics in an object. Such records are broadcast on a periodic interval if 1) a change has been made in the value of one of the elements, or 2) if a new management client has bound a queue to the management exchange. - GET_QUERY('G'), // Sent by a management console, a get query requests that the management broker provide content indications for all objects that match the query criteria. - METHOD_REQUEST('M'), // This message contains a method request. - METHOD_RESPONSE('m'), // This message contains a method result. - PACKAGE_QUERY('P'), // This message contains a schema package query request, requesting that the broker dump the list of known packages - PACKAGE_INDICATION('p'), // This message contains a schema package indication, identifying a package known by the broker - AGENT_ATTACH_REUQEST('A'), // This message is sent by a remote agent when it wishes to attach to a management broker - AGENT_ATTACH_RESPONSE('a'), // The management broker sends this response if an attaching remote agent is permitted to join - CONSOLE_ADDED_INDICATION('x'), // This message is sent to all remote agents by the management broker when a new console binds to the management exchange - EVENT('e') - ; - - - private final char _opcode; - - private static final QMFOperation[] OP_CODES = new QMFOperation[256]; - - - QMFOperation(char opcode) - { - _opcode = opcode; - } - - - public char getOpcode() - { - return _opcode; - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java deleted file mode 100644 index 63b43475aa..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * 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.qmf; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -public class QMFPackage -{ - private final String _name; - private final Map<String, QMFClass> _classes = new HashMap<String, QMFClass>(); - - public QMFPackage(String name) - { - _name = name; - } - - public QMFPackage(String name, Collection<QMFClass> classes) - { - this(name); - setClasses(classes); - } - - protected void setClasses(Collection<QMFClass> classes) - { - for(QMFClass qmfClass : classes) - { - qmfClass.setPackage(this); - _classes.put(qmfClass.getName(), qmfClass); - } - } - - public String getName() - { - return _name; - } - - public Collection<QMFClass> getClasses() - { - return _classes.values(); - } - - public QMFClass getQMFClass(String className) - { - return _classes.get(className); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java deleted file mode 100644 index c74c7da252..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBDecoder; - -import java.util.Collection; -import java.util.List; - -public class QMFPackageQueryCommand extends QMFCommand -{ - - private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf"); - - public QMFPackageQueryCommand(QMFCommandHeader header, BBDecoder decoder) - { - super(header); - } - - public void process(VirtualHost virtualHost, ServerMessage message) - { - String exchangeName = message.getMessageHeader().getReplyToExchange(); - String routingKey = message.getMessageHeader().getReplyToRoutingKey(); - - - IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry(); - QMFService service = appRegistry.getQMFService(); - - Collection<QMFPackage> supportedSchemas = service.getSupportedSchemas(); - - QMFCommand[] commands = new QMFCommand[ supportedSchemas.size() + 1 ]; - - _qmfLogger.debug("Exectuting " + this); - - int i = 0; - for(QMFPackage p : supportedSchemas) - { - commands[i++] = new QMFPackageIndicationCommand(this, p.getName()); - } - commands[ commands.length - 1 ] = new QMFCommandCompletionCommand(this); - - - for(QMFCommand cmd : commands) - { - - QMFMessage responseMessage = new QMFMessage(routingKey, cmd); - - Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName); - - List<? extends BaseQueue> queues = exchange.route(responseMessage); - - - for(BaseQueue q : queues) - { - try - { - q.enqueue(responseMessage); - } - catch (AMQException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - } - } - - public String toString() - { - return "QMFPackageQueryCommand"; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java deleted file mode 100644 index 5314466e2a..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.qpid.transport.codec.Encoder; - -import java.util.LinkedHashMap; -import java.util.Map; - -public class QMFProperty -{ - private final Map<String, Object> _map = new LinkedHashMap<String, Object>(); - private static final String NAME = "name"; - private static final String TYPE = "type"; - private static final String ACCESS = "access"; - private static final String INDEX = "index"; - private static final String OPTIONAL = "optional"; - private static final String REF_PACKAGE = "refPackage"; - private static final String REF_CLASS = "refClass"; - private static final String UNIT = "unit"; - private static final String MIN = "min"; - private static final String MAX = "max"; - private static final String MAX_LENGTH = "maxlen"; - private static final String DESCRIPTION = "desc"; - - - public static enum AccessCode - { - RC, - RW, - RO; - - public int codeValue() - { - return ordinal()+1; - } - } - - public QMFProperty(String name, QMFType type, AccessCode accessCode, boolean index, boolean optional) - { - _map.put(NAME, name); - _map.put(TYPE, type.codeValue()); - _map.put(ACCESS, accessCode.codeValue()); - _map.put(INDEX, index ? 1 : 0); - _map.put(OPTIONAL, optional ? 1 :0); - } - - - public void setQMFClass(QMFClass qmfClass) - { - } - - public void setReferencedClass(String refClass) - { - _map.put(REF_CLASS, refClass); - } - - public void setReferencedPackage(String refPackage) - { - _map.put(REF_CLASS, refPackage); - } - - - public String getName() - { - return (String) _map.get(NAME); - } - - - public void setUnit(String unit) - { - _map.put(UNIT, unit); - } - - public void setMin(Number min) - { - _map.put(MIN, min); - } - - public void setMax(Number max) - { - _map.put(MAX, max); - } - - public void setMaxLength(int maxlen) - { - _map.put(MAX_LENGTH, maxlen); - } - - - public void setDescription(String description) - { - _map.put(DESCRIPTION, description); - } - - public void encode(Encoder encoder) - { - encoder.writeMap(_map); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java deleted file mode 100644 index 57c67fa7f6..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBDecoder; - -import java.util.List; - -public class QMFSchemaRequestCommand extends QMFCommand -{ - private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf"); - - private final String _packageName; - private final String _className; - private final byte[] _hash; - - public QMFSchemaRequestCommand(QMFCommandHeader header, BBDecoder decoder) - { - super(header); - _packageName = decoder.readStr8(); - _className = decoder.readStr8(); - _hash = decoder.readBin128(); - } - - public void process(VirtualHost virtualHost, ServerMessage message) - { - _qmfLogger.debug("Execute: " + this); - - String exchangeName = message.getMessageHeader().getReplyToExchange(); - String routingKey = message.getMessageHeader().getReplyToRoutingKey(); - - IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry(); - QMFService service = appRegistry.getQMFService(); - - QMFPackage qmfPackage = service.getPackage(_packageName); - QMFClass qmfClass = qmfPackage.getQMFClass( _className ); - - QMFCommand[] commands = new QMFCommand[2]; - commands[0] = new QMFSchemaResponseCommand(this, qmfClass); - commands[ 1 ] = new QMFCommandCompletionCommand(this); - - - - Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName); - - for(QMFCommand cmd : commands) - { - QMFMessage responseMessage = new QMFMessage(routingKey, cmd); - - - List<? extends BaseQueue> queues = exchange.route(responseMessage); - - for(BaseQueue q : queues) - { - try - { - q.enqueue(responseMessage); - } - catch (AMQException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - } - } - - @Override - public String toString() - { - return "QMFSchemaRequestCommand{" + - " packageName='" + _packageName + '\'' + - ", className='" + _className + '\'' + - '}'; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java deleted file mode 100644 index 4bd0e41989..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.qpid.transport.codec.BBEncoder; - -import java.util.Collection; - -public class QMFSchemaResponseCommand extends QMFCommand -{ - private final QMFClass _qmfClass; - - - public QMFSchemaResponseCommand(QMFSchemaRequestCommand qmfSchemaRequestCommand, QMFClass qmfClass) - { - super(new QMFCommandHeader(qmfSchemaRequestCommand.getHeader().getVersion(), - qmfSchemaRequestCommand.getHeader().getSeq(), - QMFOperation.SCHEMA_RESPONSE)); - _qmfClass = qmfClass; - } - - @Override - public void encode(BBEncoder encoder) - { - super.encode(encoder); - encoder.writeUint8(_qmfClass.getType().getValue()); - encoder.writeStr8(_qmfClass.getPackage().getName()); - encoder.writeStr8(_qmfClass.getName()); - encoder.writeBin128(_qmfClass.getSchemaHash()); - - Collection<QMFProperty> props = _qmfClass.getProperties(); - Collection<QMFStatistic> stats = _qmfClass.getStatistics(); - Collection<QMFMethod> methods = _qmfClass.getMethods(); - - encoder.writeUint16(props.size()); - if(_qmfClass.getType() == QMFClass.Type.OBJECT) - { - encoder.writeUint16(stats.size()); - encoder.writeUint16(methods.size()); - } - - for(QMFProperty prop : props) - { - prop.encode(encoder); - } - - if(_qmfClass.getType() == QMFClass.Type.OBJECT) - { - - for(QMFStatistic stat : stats) - { - stat.encode(encoder); - } - - for(QMFMethod method : methods) - { - method.encode(encoder); - } - } - - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java deleted file mode 100644 index d713976919..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java +++ /dev/null @@ -1,2086 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.qpid.AMQException; -import org.apache.qpid.common.Closeable; -import org.apache.qpid.qmf.schema.BrokerSchema; -import org.apache.qpid.server.configuration.*; -import org.apache.qpid.server.registry.IApplicationRegistry; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; - -public class QMFService implements ConfigStore.ConfigEventListener, Closeable -{ - - - private IApplicationRegistry _applicationRegistry; - private ConfigStore _configStore; - - - private final Map<String, QMFPackage> _supportedSchemas = new HashMap<String, QMFPackage>(); - private static final Map<String, ConfigObjectType> _qmfClassMapping = new HashMap<String, ConfigObjectType>(); - - static - { - _qmfClassMapping.put("system", SystemConfigType.getInstance()); - _qmfClassMapping.put("broker", BrokerConfigType.getInstance()); - _qmfClassMapping.put("vhost", VirtualHostConfigType.getInstance()); - _qmfClassMapping.put("exchange", ExchangeConfigType.getInstance()); - _qmfClassMapping.put("queue", QueueConfigType.getInstance()); - _qmfClassMapping.put("binding", BindingConfigType.getInstance()); - _qmfClassMapping.put("connection", ConnectionConfigType.getInstance()); - _qmfClassMapping.put("session", SessionConfigType.getInstance()); - _qmfClassMapping.put("subscription", SubscriptionConfigType.getInstance()); - _qmfClassMapping.put("link", LinkConfigType.getInstance()); - _qmfClassMapping.put("bridge", BridgeConfigType.getInstance()); - } - - private final Map<ConfigObjectType, ConfigObjectAdapter> _adapterMap = - new HashMap<ConfigObjectType, ConfigObjectAdapter>(); - private final Map<ConfigObjectType,QMFClass> _classMap = - new HashMap<ConfigObjectType,QMFClass>(); - - - private final ConcurrentHashMap<QMFClass,ConcurrentHashMap<ConfiguredObject, QMFObject>> _managedObjects = - new ConcurrentHashMap<QMFClass,ConcurrentHashMap<ConfiguredObject, QMFObject>>(); - - private final ConcurrentHashMap<QMFClass,ConcurrentHashMap<UUID, QMFObject>> _managedObjectsById = - new ConcurrentHashMap<QMFClass,ConcurrentHashMap<UUID, QMFObject>>(); - - private static final BrokerSchema PACKAGE = BrokerSchema.getPackage(); - - public static interface Listener - { - public void objectCreated(QMFObject obj); - public void objectDeleted(QMFObject obj); - } - - private final CopyOnWriteArrayList<Listener> _listeners = new CopyOnWriteArrayList<Listener>(); - - abstract class ConfigObjectAdapter<Q extends QMFObject<S,D>, S extends QMFObjectClass<Q,D>, D extends QMFObject.Delegate, T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>> - { - private final T _type; - private final S _qmfClass; - - - protected ConfigObjectAdapter(final T type, final S qmfClass) - { - _type = type; - _qmfClass = qmfClass; - _adapterMap.put(type,this); - _classMap.put(type,qmfClass); - } - - public T getType() - { - return _type; - } - - public S getQMFClass() - { - return _qmfClass; - } - - protected final Q newInstance(D delegate) - { - return _qmfClass.newInstance(delegate); - } - - public abstract Q createQMFObject(C configObject); - } - - private ConfigObjectAdapter<BrokerSchema.SystemObject, - BrokerSchema.SystemClass, - BrokerSchema.SystemDelegate, - SystemConfigType, - SystemConfig> _systemObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.SystemObject, - BrokerSchema.SystemClass, - BrokerSchema.SystemDelegate, - SystemConfigType, - SystemConfig>(SystemConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.SystemClass.class)) - { - - - public BrokerSchema.SystemObject createQMFObject( - final SystemConfig configObject) - { - return newInstance(new SystemDelegate(configObject)); - } - }; - - private ConfigObjectAdapter<BrokerSchema.BrokerObject, - BrokerSchema.BrokerClass, - BrokerSchema.BrokerDelegate, - BrokerConfigType, - BrokerConfig> _brokerObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.BrokerObject, - BrokerSchema.BrokerClass, - BrokerSchema.BrokerDelegate, - BrokerConfigType, - BrokerConfig>(BrokerConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.BrokerClass.class)) - { - - public BrokerSchema.BrokerObject createQMFObject( - final BrokerConfig configObject) - { - return newInstance(new BrokerDelegate(configObject)); - } - }; - - private ConfigObjectAdapter<BrokerSchema.VhostObject, - BrokerSchema.VhostClass, - BrokerSchema.VhostDelegate, - VirtualHostConfigType, - VirtualHostConfig> _vhostObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.VhostObject, - BrokerSchema.VhostClass, - BrokerSchema.VhostDelegate, - VirtualHostConfigType, - VirtualHostConfig>(VirtualHostConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.VhostClass.class)) - { - - public BrokerSchema.VhostObject createQMFObject( - final VirtualHostConfig configObject) - { - return newInstance(new VhostDelegate(configObject)); - } - }; - - - private ConfigObjectAdapter<BrokerSchema.ExchangeObject, - BrokerSchema.ExchangeClass, - BrokerSchema.ExchangeDelegate, - ExchangeConfigType, - ExchangeConfig> _exchangeObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.ExchangeObject, - BrokerSchema.ExchangeClass, - BrokerSchema.ExchangeDelegate, - ExchangeConfigType, - ExchangeConfig>(ExchangeConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.ExchangeClass.class)) - { - - public BrokerSchema.ExchangeObject createQMFObject( - final ExchangeConfig configObject) - { - return newInstance(new ExchangeDelegate(configObject)); - } - }; - - - private ConfigObjectAdapter<BrokerSchema.QueueObject, - BrokerSchema.QueueClass, - BrokerSchema.QueueDelegate, - QueueConfigType, - QueueConfig> _queueObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.QueueObject, - BrokerSchema.QueueClass, - BrokerSchema.QueueDelegate, - QueueConfigType, - QueueConfig>(QueueConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.QueueClass.class)) - { - - public BrokerSchema.QueueObject createQMFObject( - final QueueConfig configObject) - { - return newInstance(new QueueDelegate(configObject)); - } - }; - - - private ConfigObjectAdapter<BrokerSchema.BindingObject, - BrokerSchema.BindingClass, - BrokerSchema.BindingDelegate, - BindingConfigType, - BindingConfig> _bindingObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.BindingObject, - BrokerSchema.BindingClass, - BrokerSchema.BindingDelegate, - BindingConfigType, - BindingConfig>(BindingConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.BindingClass.class)) - { - - public BrokerSchema.BindingObject createQMFObject( - final BindingConfig configObject) - { - return newInstance(new BindingDelegate(configObject)); - } - }; - - - private ConfigObjectAdapter<BrokerSchema.ConnectionObject, - BrokerSchema.ConnectionClass, - BrokerSchema.ConnectionDelegate, - ConnectionConfigType, - ConnectionConfig> _connectionObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.ConnectionObject, - BrokerSchema.ConnectionClass, - BrokerSchema.ConnectionDelegate, - ConnectionConfigType, - ConnectionConfig>(ConnectionConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.ConnectionClass.class)) - { - - public BrokerSchema.ConnectionObject createQMFObject( - final ConnectionConfig configObject) - { - return newInstance(new ConnectionDelegate(configObject)); - } - }; - - - private ConfigObjectAdapter<BrokerSchema.SessionObject, - BrokerSchema.SessionClass, - BrokerSchema.SessionDelegate, - SessionConfigType, - SessionConfig> _sessionObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.SessionObject, - BrokerSchema.SessionClass, - BrokerSchema.SessionDelegate, - SessionConfigType, - SessionConfig>(SessionConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.SessionClass.class)) - { - - public BrokerSchema.SessionObject createQMFObject( - final SessionConfig configObject) - { - return newInstance(new SessionDelegate(configObject)); - } - }; - - private ConfigObjectAdapter<BrokerSchema.SubscriptionObject, - BrokerSchema.SubscriptionClass, - BrokerSchema.SubscriptionDelegate, - SubscriptionConfigType, - SubscriptionConfig> _subscriptionObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.SubscriptionObject, - BrokerSchema.SubscriptionClass, - BrokerSchema.SubscriptionDelegate, - SubscriptionConfigType, - SubscriptionConfig>(SubscriptionConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.SubscriptionClass.class)) - { - - public BrokerSchema.SubscriptionObject createQMFObject( - final SubscriptionConfig configObject) - { - return newInstance(new SubscriptionDelegate(configObject)); - } - }; - - - private ConfigObjectAdapter<BrokerSchema.LinkObject, - BrokerSchema.LinkClass, - BrokerSchema.LinkDelegate, - LinkConfigType, - LinkConfig> _linkObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.LinkObject, - BrokerSchema.LinkClass, - BrokerSchema.LinkDelegate, - LinkConfigType, - LinkConfig>(LinkConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.LinkClass.class)) - { - - public BrokerSchema.LinkObject createQMFObject( - final LinkConfig configObject) - { - return newInstance(new LinkDelegate(configObject)); - } - }; - - - private ConfigObjectAdapter<BrokerSchema.BridgeObject, - BrokerSchema.BridgeClass, - BrokerSchema.BridgeDelegate, - BridgeConfigType, - BridgeConfig> _bridgeObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.BridgeObject, - BrokerSchema.BridgeClass, - BrokerSchema.BridgeDelegate, - BridgeConfigType, - BridgeConfig>(BridgeConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.BridgeClass.class)) - { - - public BrokerSchema.BridgeObject createQMFObject( - final BridgeConfig configObject) - { - return newInstance(new BridgeDelegate(configObject)); - } - }; - - - - public QMFService(ConfigStore configStore, IApplicationRegistry applicationRegistry) - { - _configStore = configStore; - _applicationRegistry = applicationRegistry; - registerSchema(PACKAGE); - - for(ConfigObjectType v : _qmfClassMapping.values()) - { - configStore.addConfigEventListener(v, this); - } - init(); - } - - public void close() - { - for(ConfigObjectType v : _qmfClassMapping.values()) - { - _configStore.removeConfigEventListener(v, this); - } - _listeners.clear(); - - _managedObjects.clear(); - _managedObjectsById.clear(); - _classMap.clear(); - _adapterMap.clear(); - _supportedSchemas.clear(); - } - - - public void registerSchema(QMFPackage qmfPackage) - { - _supportedSchemas.put(qmfPackage.getName(), qmfPackage); - } - - - public Collection<QMFPackage> getSupportedSchemas() - { - return _supportedSchemas.values(); - } - - public QMFPackage getPackage(String aPackage) - { - return _supportedSchemas.get(aPackage); - } - - public void onEvent(final ConfiguredObject object, final ConfigStore.Event evt) - { - - switch (evt) - { - case CREATED: - manageObject(object); - break; - - case DELETED: - unmanageObject(object); - break; - } - } - - public QMFObject getObjectById(QMFClass qmfclass, UUID id) - { - ConcurrentHashMap<UUID, QMFObject> map = _managedObjectsById.get(qmfclass); - if(map != null) - { - - UUID key = new UUID(id.getMostSignificantBits() & (0xFFFl << 48), id.getLeastSignificantBits()); - return map.get(key); - - } - else - { - return null; - } - } - - private void unmanageObject(final ConfiguredObject object) - { - final QMFClass qmfClass = _classMap.get(object.getConfigType()); - - if(qmfClass == null) - { - return; - } - - ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass); - if(classObjects != null) - { - QMFObject qmfObject = classObjects.remove(object); - if(qmfObject != null) - { - _managedObjectsById.get(qmfClass).remove(object.getQMFId()); - objectRemoved(qmfObject); - } - } - } - - private void manageObject(final ConfiguredObject object) - { - ConfigObjectAdapter adapter = _adapterMap.get(object.getConfigType()); - QMFObject qmfObject = adapter.createQMFObject(object); - final QMFClass qmfClass = qmfObject.getQMFClass(); - ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass); - - if(classObjects == null) - { - classObjects = new ConcurrentHashMap<ConfiguredObject, QMFObject>(); - if(_managedObjects.putIfAbsent(qmfClass, classObjects) != null) - { - classObjects = _managedObjects.get(qmfClass); - } - } - - ConcurrentHashMap<UUID, QMFObject> classObjectsById = _managedObjectsById.get(qmfClass); - if(classObjectsById == null) - { - classObjectsById = new ConcurrentHashMap<UUID, QMFObject>(); - if(_managedObjectsById.putIfAbsent(qmfClass, classObjectsById) != null) - { - classObjectsById = _managedObjectsById.get(qmfClass); - } - } - - classObjectsById.put(object.getQMFId(),qmfObject); - - if(classObjects.putIfAbsent(object, qmfObject) == null) - { - objectAdded(qmfObject); - } - } - - private void objectRemoved(final QMFObject qmfObject) - { - qmfObject.setDeleteTime(); - for(Listener l : _listeners) - { - l.objectDeleted(qmfObject); - } - } - - private void objectAdded(final QMFObject qmfObject) - { - for(Listener l : _listeners) - { - l.objectCreated(qmfObject); - } - } - - public void addListener(Listener l) - { - _listeners.add(l); - } - - public void removeListener(Listener l) - { - _listeners.remove(l); - } - - - private void init() - { - for(QMFClass qmfClass : PACKAGE.getClasses()) - { - ConfigObjectType configType = getConfigType(qmfClass); - if(configType != null) - { - Collection<ConfiguredObject> objects = _configStore.getConfiguredObjects(configType); - for(ConfiguredObject object : objects) - { - manageObject(object); - } - } - } - } - - public Collection<QMFObject> getObjects(QMFClass qmfClass) - { - ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass); - if(classObjects != null) - { - return classObjects.values(); - } - else - { - return Collections.EMPTY_SET; - } - } - - private QMFObject adapt(final ConfiguredObject object) - { - if(object == null) - { - return null; - } - - QMFClass qmfClass = _classMap.get(object.getConfigType()); - ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass); - if(classObjects != null) - { - QMFObject qmfObject = classObjects.get(object); - if(qmfObject != null) - { - return qmfObject; - } - } - - return _adapterMap.get(object.getConfigType()).createQMFObject(object); - } - - private ConfigObjectType getConfigType(final QMFClass qmfClass) - { - return _qmfClassMapping.get(qmfClass.getName()); - } - - private static class SystemDelegate implements BrokerSchema.SystemDelegate - { - private final SystemConfig _obj; - - public SystemDelegate(final SystemConfig obj) - { - _obj = obj; - } - - public UUID getSystemId() - { - return _obj.getQMFId(); - } - - public String getOsName() - { - return _obj.getOperatingSystemName(); - } - - public String getNodeName() - { - return _obj.getNodeName(); - } - - public String getRelease() - { - return _obj.getOSRelease(); - } - - public String getVersion() - { - return _obj.getOSVersion(); - } - - public String getMachine() - { - return _obj.getOSArchitecture(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class BrokerDelegate implements BrokerSchema.BrokerDelegate - { - private final BrokerConfig _obj; - - public BrokerDelegate(final BrokerConfig obj) - { - _obj = obj; - } - - public BrokerSchema.SystemObject getSystemRef() - { - return (BrokerSchema.SystemObject) adapt(_obj.getSystem()); - } - - public String getName() - { - return "amqp-broker"; - } - - public Integer getPort() - { - return _obj.getPort(); - } - - public Integer getWorkerThreads() - { - return _obj.getWorkerThreads(); - } - - public Integer getMaxConns() - { - return _obj.getMaxConnections(); - } - - public Integer getConnBacklog() - { - return _obj.getConnectionBacklogLimit(); - } - - public Long getStagingThreshold() - { - return _obj.getStagingThreshold(); - } - - public Boolean getMgmtPublish() - { - return true; - } - - public Integer getMgmtPubInterval() - { - return _obj.getManagementPublishInterval(); - } - - public String getVersion() - { - return _obj.getVersion(); - } - - public String getDataDir() - { - return _obj.getDataDirectory(); - } - - public Long getUptime() - { - return (System.currentTimeMillis() - _obj.getCreateTime()) * 1000000L; - } - - public Long getQueueCount() - { - // TODO - return 0L; - } - - public Long getMsgTotalEnqueues() - { - // TODO - return 0L; - } - - public Long getMsgTotalDequeues() - { - // TODO - return 0L; - } - - public Long getByteTotalEnqueues() - { - // TODO - return 0L; - } - - public Long getByteTotalDequeues() - { - // TODO - return 0L; - } - - public Long getMsgDepth() - { - // TODO - return 0L; - } - - public Long getByteDepth() - { - // TODO - return 0L; - } - - public Long getMsgPersistEnqueues() - { - // TODO - return 0L; - } - - public Long getMsgPersistDequeues() - { - // TODO - return 0L; - } - - public Long getBytePersistEnqueues() - { - // TODO - return 0L; - } - - public Long getBytePersistDequeues() - { - // TODO - return 0L; - } - - public Long getMsgTxnEnqueues() - { - // TODO - return 0L; - } - - public Long getMsgTxnDequeues() - { - // TODO - return 0L; - } - - public Long getByteTxnEnqueues() - { - // TODO - return 0L; - } - - public Long getByteTxnDequeues() - { - // TODO - return 0L; - } - - public Long getMsgFtdEnqueues() - { - // TODO - return 0L; - } - - public Long getMsgFtdDequeues() - { - // TODO - return 0L; - } - - public Long getByteFtdEnqueues() - { - // TODO - return 0L; - } - - public Long getByteFtdDequeues() - { - // TODO - return 0L; - } - - public Long getMsgFtdDepth() - { - // TODO - return 0L; - } - - public Long getByteFtdDepth() - { - // TODO - return 0L; - } - - public Long getReleases() - { - // TODO - return 0L; - } - - public Long getAcquires() - { - // TODO - return 0L; - } - - public Long getDiscardsNoRoute() - { - // TODO - return 0L; - } - - public Long getDiscardsTtl() - { - // TODO - return 0L; - } - - public Long getDiscardsRing() - { - // TODO - return 0L; - } - - public Long getDiscardsLvq() - { - // TODO - return 0L; - } - - public Long getDiscardsOverflow() - { - // TODO - return 0L; - } - - public Long getDiscardsSubscriber() - { - // TODO - return 0L; - } - - public Long getDiscardsPurge() - { - // TODO - return 0L; - } - - public Long getReroutes() - { - // TODO - return 0L; - } - - public Long getAbandoned() - { - // TODO - return 0L; - } - - public Long getAbandonedViaAlt() - { - // TODO - return 0L; - } - - public BrokerSchema.BrokerClass.EchoMethodResponseCommand echo(final BrokerSchema.BrokerClass.EchoMethodResponseCommandFactory factory, - final Long sequence, - final String body) - { - return factory.createResponseCommand(sequence, body); - } - - public BrokerSchema.BrokerClass.ConnectMethodResponseCommand connect(final BrokerSchema.BrokerClass.ConnectMethodResponseCommandFactory factory, - final String host, - final Long port, - final Boolean durable, - final String authMechanism, - final String username, - final String password, - final String transport) - { - _obj.createBrokerConnection(transport, host, port.intValue(), durable, authMechanism, username, password); - - return factory.createResponseCommand(); - } - - public BrokerSchema.BrokerClass.QueueMoveMessagesMethodResponseCommand queueMoveMessages(final BrokerSchema.BrokerClass.QueueMoveMessagesMethodResponseCommandFactory factory, - final String srcQueue, - final String destQueue, - final Long qty, - final Map filter) // TODO: move based on group identifier - { - // TODO - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.BrokerClass.GetLogLevelMethodResponseCommand getLogLevel(final BrokerSchema.BrokerClass.GetLogLevelMethodResponseCommandFactory factory) - { - // TODO: The Java broker has numerous loggers, so we can't really implement this method properly. - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.BrokerClass.SetLogLevelMethodResponseCommand setLogLevel(final BrokerSchema.BrokerClass.SetLogLevelMethodResponseCommandFactory factory, String level) - { - // TODO: The Java broker has numerous loggers, so we can't really implement this method properly. - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.BrokerClass.GetTimestampConfigMethodResponseCommand getTimestampConfig(final BrokerSchema.BrokerClass.GetTimestampConfigMethodResponseCommandFactory factory) - { - // TODO: timestamp support - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.BrokerClass.SetTimestampConfigMethodResponseCommand setTimestampConfig(final BrokerSchema.BrokerClass.SetTimestampConfigMethodResponseCommandFactory factory, - final java.lang.Boolean receive) - { - // TODO: timestamp support - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.BrokerClass.CreateMethodResponseCommand create(final BrokerSchema.BrokerClass.CreateMethodResponseCommandFactory factory, - final String type, - final String name, - final Map properties, - final java.lang.Boolean lenient) - { - //TODO: - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.BrokerClass.DeleteMethodResponseCommand delete(final BrokerSchema.BrokerClass.DeleteMethodResponseCommandFactory factory, - final String type, - final String name, - final Map options) - { - //TODO: - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.BrokerClass.QueryMethodResponseCommand query(final BrokerSchema.BrokerClass.QueryMethodResponseCommandFactory factory, - final String type, - final String name) - { - //TODO: - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class VhostDelegate implements BrokerSchema.VhostDelegate - { - private final VirtualHostConfig _obj; - - public VhostDelegate(final VirtualHostConfig obj) - { - _obj = obj; - } - - public BrokerSchema.BrokerObject getBrokerRef() - { - return (BrokerSchema.BrokerObject) adapt(_obj.getBroker()); - } - - public String getName() - { - return _obj.getName(); - } - - public String getFederationTag() - { - return _obj.getFederationTag(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class ExchangeDelegate implements BrokerSchema.ExchangeDelegate - { - private final ExchangeConfig _obj; - - public ExchangeDelegate(final ExchangeConfig obj) - { - _obj = obj; - } - - public BrokerSchema.VhostObject getVhostRef() - { - return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost()); - } - - public String getName() - { - return _obj.getName(); - } - - public String getType() - { - return _obj.getType().getName().toString(); - } - - public Boolean getDurable() - { - return _obj.isDurable(); - } - - public Boolean getAutoDelete() - { - return _obj.isAutoDelete(); - } - - public BrokerSchema.ExchangeObject getAltExchange() - { - if(_obj.getAlternateExchange() != null) - { - return (BrokerSchema.ExchangeObject) adapt(_obj.getAlternateExchange()); - } - else - { - return null; - } - } - - public Map getArguments() - { - return _obj.getArguments(); - } - - public Long getProducerCount() - { - // TODO - return 0l; - } - - public Long getProducerCountHigh() - { - // TODO - return 0l; - } - - public Long getProducerCountLow() - { - // TODO - return 0l; - } - - public Long getBindingCount() - { - return _obj.getBindingCount(); - } - - public Long getBindingCountHigh() - { - return _obj.getBindingCountHigh(); - } - - public Long getBindingCountLow() - { - // TODO - return 0l; - } - - public Long getMsgReceives() - { - return _obj.getMsgReceives(); - } - - public Long getMsgDrops() - { - return getMsgReceives() - getMsgRoutes(); - } - - public Long getMsgRoutes() - { - return _obj.getMsgRoutes(); - } - - public Long getByteReceives() - { - return _obj.getByteReceives(); - } - - public Long getByteDrops() - { - return getByteReceives() - getByteRoutes(); - } - - public Long getByteRoutes() - { - return _obj.getByteRoutes(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class QueueDelegate implements BrokerSchema.QueueDelegate - { - private final QueueConfig _obj; - - public QueueDelegate(final QueueConfig obj) - { - _obj = obj; - } - - public BrokerSchema.VhostObject getVhostRef() - { - return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost()); - } - - public String getName() - { - return _obj.getName(); - } - - public Boolean getDurable() - { - return _obj.isDurable(); - } - - public Boolean getAutoDelete() - { - return _obj.isAutoDelete(); - } - - public Boolean getExclusive() - { - return _obj.isExclusive(); - } - - public BrokerSchema.ExchangeObject getAltExchange() - { - if(_obj.getAlternateExchange() != null) - { - return (BrokerSchema.ExchangeObject) adapt(_obj.getAlternateExchange()); - } - else - { - return null; - } - } - - public Long getMsgTotalEnqueues() - { - return _obj.getReceivedMessageCount(); - } - - public Long getMsgTotalDequeues() - { - return _obj.getMessageDequeueCount(); - } - - public Long getMsgTxnEnqueues() - { - return _obj.getMsgTxnEnqueues(); - } - - public Long getMsgTxnDequeues() - { - return _obj.getMsgTxnDequeues(); - } - - public Long getMsgPersistEnqueues() - { - return _obj.getPersistentMsgEnqueues(); - } - - public Long getMsgPersistDequeues() - { - return _obj.getPersistentMsgDequeues(); - } - - public Long getMsgDepth() - { - return (long) _obj.getMessageCount(); - } - - public Long getByteDepth() - { - return _obj.getQueueDepth(); - } - - public Long getByteTotalEnqueues() - { - return _obj.getTotalEnqueueSize(); - } - - public Long getByteTotalDequeues() - { - return _obj.getTotalDequeueSize(); - } - - public Long getByteTxnEnqueues() - { - return _obj.getByteTxnEnqueues(); - } - - public Long getByteTxnDequeues() - { - return _obj.getByteTxnDequeues(); - } - - public Long getBytePersistEnqueues() - { - return _obj.getPersistentByteEnqueues(); - } - - public Long getBytePersistDequeues() - { - return _obj.getPersistentByteDequeues(); - } - - public Long getMsgFtdEnqueues() - { - // TODO - return 0L; - } - - public Long getMsgFtdDequeues() - { - // TODO - return 0L; - } - - public Long getByteFtdEnqueues() - { - // TODO - return 0L; - } - - public Long getByteFtdDequeues() - { - // TODO - return 0L; - } - - public Long getMsgFtdDepth() - { - // TODO - return 0L; - } - - public Long getByteFtdDepth() - { - // TODO - return 0L; - } - - public Long getReleases() - { - // TODO - return 0L; - } - - public Long getAcquires() - { - // TODO - return 0L; - } - - public Long getDiscardsTtl() - { - // TODO - return 0L; - } - - public Long getDiscardsRing() - { - // TODO - return 0L; - } - - public Long getDiscardsLvq() - { - // TODO - return 0L; - } - - public Long getDiscardsOverflow() - { - // TODO - return 0L; - } - - public Long getDiscardsSubscriber() - { - // TODO - return 0L; - } - - public Long getDiscardsPurge() - { - // TODO - return 0L; - } - - public Long getReroutes() - { - // TODO - return 0L; - } - - public Long getConsumerCount() - { - return (long) _obj.getConsumerCount(); - } - - public Long getConsumerCountHigh() - { - return (long) _obj.getConsumerCountHigh(); - } - - public Long getConsumerCountLow() - { - // TODO - return 0l; - } - - public Long getBindingCount() - { - return (long) _obj.getBindingCount(); - } - - public Long getBindingCountHigh() - { - return (long) _obj.getBindingCountHigh(); - } - - public Long getBindingCountLow() - { - // TODO - return 0l; - } - - public Long getUnackedMessages() - { - return _obj.getUnackedMessageCount(); - } - - public Long getUnackedMessagesHigh() - { - return _obj.getUnackedMessageCountHigh(); - } - - public Long getUnackedMessagesLow() - { - // TODO - return 0l; - } - - public Long getMessageLatencySamples() - { - // TODO - return 0l; - } - - public Long getMessageLatencyMin() - { - // TODO - return 0l; - } - - public Long getMessageLatencyMax() - { - // TODO - return 0l; - } - - public Long getMessageLatencyAverage() - { - // TODO - return 0l; - } - - public Boolean getFlowStopped() - { - return Boolean.FALSE; - } - - public Long getFlowStoppedCount() - { - return 0L; - } - - public BrokerSchema.QueueClass.PurgeMethodResponseCommand purge(final BrokerSchema.QueueClass.PurgeMethodResponseCommandFactory factory, - final Long request, - final Map filter) // TODO: support for purge-by-group-identifier - { - try - { - _obj.purge(request); - } catch (AMQException e) - { - // TODO - throw new RuntimeException(); - } - return factory.createResponseCommand(); - } - - public BrokerSchema.QueueClass.RerouteMethodResponseCommand reroute(final BrokerSchema.QueueClass.RerouteMethodResponseCommandFactory factory, - final Long request, - final Boolean useAltExchange, - final String exchange, - final Map filter) // TODO: support for re-route-by-group-identifier - { - //TODO - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - - public Map getArguments() - { - return _obj.getArguments(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class BindingDelegate implements BrokerSchema.BindingDelegate - { - private final BindingConfig _obj; - - public BindingDelegate(final BindingConfig obj) - { - _obj = obj; - } - - public BrokerSchema.ExchangeObject getExchangeRef() - { - return (BrokerSchema.ExchangeObject) adapt(_obj.getExchange()); - } - - public BrokerSchema.QueueObject getQueueRef() - { - return (BrokerSchema.QueueObject) adapt(_obj.getQueue()); - } - - public String getBindingKey() - { - return _obj.getBindingKey(); - } - - public Map getArguments() - { - return _obj.getArguments(); - } - - public String getOrigin() - { - return _obj.getOrigin(); - } - - public Long getMsgMatched() - { - // TODO - return _obj.getMatches(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class ConnectionDelegate implements BrokerSchema.ConnectionDelegate - { - private final ConnectionConfig _obj; - - public ConnectionDelegate(final ConnectionConfig obj) - { - _obj = obj; - } - - public BrokerSchema.VhostObject getVhostRef() - { - return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost()); - } - - public String getAddress() - { - return _obj.getAddress(); - } - - public Boolean getIncoming() - { - return _obj.isIncoming(); - } - - public Boolean getSystemConnection() - { - return _obj.isSystemConnection(); - } - - public Boolean getFederationLink() - { - return _obj.isFederationLink(); - } - - public String getAuthIdentity() - { - return _obj.getAuthId(); - } - - public String getRemoteProcessName() - { - return _obj.getRemoteProcessName(); - } - - public Long getRemotePid() - { - Integer remotePID = _obj.getRemotePID(); - return remotePID == null ? null : (long) remotePID; - } - - public Long getRemoteParentPid() - { - Integer remotePPID = _obj.getRemoteParentPID(); - return remotePPID == null ? null : (long) remotePPID; - - } - - public Boolean getClosing() - { - return false; - } - - public Long getFramesFromClient() - { - // TODO - return 0l; - } - - public Long getFramesToClient() - { - // TODO - return 0l; - } - - public Long getBytesFromClient() - { - // TODO - return 0l; - } - - public Long getBytesToClient() - { - // TODO - return 0l; - } - - public Long getMsgsFromClient() - { - // TODO - return 0l; - } - - public Long getMsgsToClient() - { - // TODO - return 0l; - } - - public BrokerSchema.ConnectionClass.CloseMethodResponseCommand close(final BrokerSchema.ConnectionClass.CloseMethodResponseCommandFactory factory) - { - _obj.mgmtClose(); - - return factory.createResponseCommand(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public Boolean getShadow() - { - return _obj.isShadow(); - } - - public Boolean getUserProxyAuth() - { - // TODO - return false; - } - - public String getSaslMechanism() - { - // TODO - return null; - } - public Integer getSaslSsf() - { - // TODO - return 0; - } - - - public String toString() - { - return _obj.toString(); - } - } - - private class SessionDelegate implements BrokerSchema.SessionDelegate - { - private final SessionConfig _obj; - - public SessionDelegate(final SessionConfig obj) - { - _obj = obj; - } - - public BrokerSchema.VhostObject getVhostRef() - { - return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost()); - } - - public String getName() - { - return _obj.getSessionName(); - } - - public Integer getChannelId() - { - return _obj.getChannel(); - } - - public BrokerSchema.ConnectionObject getConnectionRef() - { - return (BrokerSchema.ConnectionObject) adapt(_obj.getConnectionConfig()); - } - - public Long getDetachedLifespan() - { - return _obj.getDetachedLifespan(); - } - - public Boolean getAttached() - { - return _obj.isAttached(); - } - - public Long getExpireTime() - { - return _obj.getExpiryTime(); - } - - public Long getMaxClientRate() - { - return _obj.getMaxClientRate(); - } - - public Long getFramesOutstanding() - { - // TODO - return 0l; - } - - public Long getUnackedMessages() - { - // TODO - return 0l; - } - - public Long getTxnStarts() - { - return _obj.getTxnStarts(); - } - - public Long getTxnCommits() - { - return _obj.getTxnCommits(); - } - - public Long getTxnRejects() - { - return _obj.getTxnRejects(); - } - - public Long getTxnCount() - { - return _obj.getTxnCount(); - } - - public Long getClientCredit() - { - // TODO - return 0l; - } - - public BrokerSchema.SessionClass.SolicitAckMethodResponseCommand solicitAck(final BrokerSchema.SessionClass.SolicitAckMethodResponseCommandFactory factory) - { - //TODO - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.SessionClass.DetachMethodResponseCommand detach(final BrokerSchema.SessionClass.DetachMethodResponseCommandFactory factory) - { - //TODO - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.SessionClass.ResetLifespanMethodResponseCommand resetLifespan(final BrokerSchema.SessionClass.ResetLifespanMethodResponseCommandFactory factory) - { - //TODO - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.SessionClass.CloseMethodResponseCommand close(final BrokerSchema.SessionClass.CloseMethodResponseCommandFactory factory) - { - try - { - _obj.mgmtClose(); - } - catch (AMQException e) - { - return factory.createResponseCommand(CompletionCode.EXCEPTION, e.getMessage()); - } - - return factory.createResponseCommand(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class SubscriptionDelegate implements BrokerSchema.SubscriptionDelegate - { - private final SubscriptionConfig _obj; - - private SubscriptionDelegate(final SubscriptionConfig obj) - { - _obj = obj; - } - - - public BrokerSchema.SessionObject getSessionRef() - { - return (BrokerSchema.SessionObject) adapt(_obj.getSessionConfig()); - } - - public BrokerSchema.QueueObject getQueueRef() - { - return (BrokerSchema.QueueObject) adapt(_obj.getQueue()); - } - - public String getName() - { - return _obj.getName(); - } - - public Boolean getBrowsing() - { - return _obj.isBrowsing(); - } - - public Boolean getAcknowledged() - { - return _obj.isExplicitAcknowledge(); - } - - public Boolean getExclusive() - { - return _obj.isExclusive(); - } - - public String getCreditMode() - { - return _obj.getCreditMode(); - } - - public Map getArguments() - { - return _obj.getArguments(); - } - - public Long getDelivered() - { - return _obj.getDelivered(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class BridgeDelegate implements BrokerSchema.BridgeDelegate - { - private final BridgeConfig _obj; - - private BridgeDelegate(final BridgeConfig obj) - { - _obj = obj; - } - - public BrokerSchema.LinkObject getLinkRef() - { - return (BrokerSchema.LinkObject) adapt(_obj.getLink()); - } - - public Integer getChannelId() - { - return _obj.getChannelId(); - } - - public Boolean getDurable() - { - return _obj.isDurable(); - } - - public String getSrc() - { - return _obj.getSource(); - } - - public String getDest() - { - return _obj.getDestination(); - } - - public String getKey() - { - return _obj.getKey(); - } - - public Boolean getSrcIsQueue() - { - return _obj.isQueueBridge(); - } - - public Boolean getSrcIsLocal() - { - return _obj.isLocalSource(); - } - - public String getTag() - { - return _obj.getTag(); - } - - public String getExcludes() - { - return _obj.getExcludes(); - } - - public Boolean getDynamic() - { - return _obj.isDynamic(); - } - - public Integer getSync() - { - return _obj.getAckBatching(); - } - - /* support TBD */ - public String getName() - { - return null; - } - - public BrokerSchema.BridgeClass.CloseMethodResponseCommand close(final BrokerSchema.BridgeClass.CloseMethodResponseCommandFactory factory) - { - return null; - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class LinkDelegate implements BrokerSchema.LinkDelegate - { - private final LinkConfig _obj; - - private LinkDelegate(final LinkConfig obj) - { - _obj = obj; - } - - public BrokerSchema.VhostObject getVhostRef() - { - return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost()); - } - - public String getHost() - { - return _obj.getHost(); - } - - public Integer getPort() - { - return _obj.getPort(); - } - - public String getTransport() - { - return _obj.getTransport(); - } - - public Boolean getDurable() - { - return _obj.isDurable(); - } - - public String getState() - { - return _obj.getState(); - } - - public String getLastError() - { - return _obj.getLastError(); - } - - /* support TBD */ - public String getName() - { - return null; - } - - /* support TBD */ - public BrokerSchema.ConnectionObject getConnectionRef() - { - return (BrokerSchema.ConnectionObject) null; - } - - public BrokerSchema.LinkClass.CloseMethodResponseCommand close(final BrokerSchema.LinkClass.CloseMethodResponseCommandFactory factory) - { - _obj.close(); - return factory.createResponseCommand(); - } - - public BrokerSchema.LinkClass.BridgeMethodResponseCommand bridge(final BrokerSchema.LinkClass.BridgeMethodResponseCommandFactory factory, - final Boolean durable, - final String src, - final String dest, - final String key, - final String tag, - final String excludes, - final Boolean srcIsQueue, - final Boolean srcIsLocal, - final Boolean dynamic, - final Integer sync) - { - _obj.createBridge(durable, dynamic, srcIsQueue, srcIsLocal, src, dest, key, tag, excludes); - return factory.createResponseCommand(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - @Override - public String toString() - { - return _obj.toString(); - } - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFStatistic.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFStatistic.java deleted file mode 100644 index 89d650e03b..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFStatistic.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * 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.qmf; - -import org.apache.qpid.transport.codec.Encoder; - -import java.util.LinkedHashMap; - -public class QMFStatistic -{ - private final LinkedHashMap<String,Object> _map = new LinkedHashMap<String,Object>(); - private static final String NAME = "name"; - private static final String TYPE = "type"; - private static final String UNIT = "unit"; - private static final String DESCRIPTION = "desc"; - - - public QMFStatistic(String name, QMFType type, String unit, String description) - { - _map.put(NAME, name); - _map.put(TYPE, type.codeValue()); - if(unit != null) - { - _map.put(UNIT, unit); - } - if(description != null) - { - _map.put(DESCRIPTION, description); - } - - } - - public void encode(Encoder encoder) - { - encoder.writeMap(_map); - } - - public String getName() - { - return (String) _map.get(NAME); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java index e197dddfde..ab4ca81d05 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java +++ b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java @@ -51,13 +51,10 @@ import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.framing.abstraction.ContentChunk; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.server.TransactionTimeoutHelper.CloseAction; import org.apache.qpid.server.ack.UnacknowledgedMessageMap; import org.apache.qpid.server.ack.UnacknowledgedMessageMapImpl; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.ConnectionConfig; -import org.apache.qpid.server.configuration.SessionConfig; -import org.apache.qpid.server.configuration.SessionConfigType; +import org.apache.qpid.server.configuration.BrokerProperties; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.flow.FlowCreditManager; import org.apache.qpid.server.flow.Pre0_10CreditManager; @@ -75,7 +72,6 @@ import org.apache.qpid.server.message.MessageReference; import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.server.output.ProtocolOutputConverter; import org.apache.qpid.server.protocol.AMQConnectionModel; -import org.apache.qpid.server.protocol.AMQProtocolEngine; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.queue.AMQQueue; @@ -83,7 +79,6 @@ import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.InboundMessageAdapter; import org.apache.qpid.server.queue.IncomingMessage; import org.apache.qpid.server.queue.QueueEntry; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.store.StoreFuture; import org.apache.qpid.server.store.StoredMessage; @@ -93,19 +88,19 @@ import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.subscription.SubscriptionFactoryImpl; import org.apache.qpid.server.txn.AsyncAutoCommitTransaction; import org.apache.qpid.server.txn.LocalTransaction; +import org.apache.qpid.server.txn.LocalTransaction.ActivityTimeAccessor; import org.apache.qpid.server.txn.ServerTransaction; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.TransportException; -public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoCommitTransaction.FutureRecorder +public class AMQChannel implements AMQSessionModel, AsyncAutoCommitTransaction.FutureRecorder { public static final int DEFAULT_PREFETCH = 4096; private static final Logger _logger = Logger.getLogger(AMQChannel.class); - private static final boolean MSG_AUTH = - ApplicationRegistry.getInstance().getConfiguration().getMsgAuth(); - + //TODO use Broker property to configure message authorization requirements + private boolean _messageAuthorizationRequired = Boolean.getBoolean(BrokerProperties.PROPERTY_MSG_AUTH); private final int _channelId; @@ -118,7 +113,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm */ private long _deliveryTag = 0; - /** A channel has a default queue (the last declared) that is used when no queue name is explictily set */ + /** A channel has a default queue (the last declared) that is used when no queue name is explicitly set */ private AMQQueue _defaultQueue; /** This tag is unique per subscription to a queue. The server returns this in response to a basic.consume request. */ @@ -151,7 +146,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm private final AtomicLong _txnCommits = new AtomicLong(0); private final AtomicLong _txnRejects = new AtomicLong(0); private final AtomicLong _txnCount = new AtomicLong(0); - private final AtomicLong _txnUpdateTime = new AtomicLong(0); private final AMQProtocolSession _session; private AtomicBoolean _closing = new AtomicBoolean(false); @@ -169,12 +163,12 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm private List<QueueEntry> _resendList = new ArrayList<QueueEntry>(); private static final AMQShortString IMMEDIATE_DELIVERY_REPLY_TEXT = new AMQShortString("Immediate delivery is not possible."); - private final UUID _qmfId; private long _createTime = System.currentTimeMillis(); private final ClientDeliveryMethod _clientDeliveryMethod; private final TransactionTimeoutHelper _transactionTimeoutHelper; + private final UUID _id = UUID.randomUUID(); public AMQChannel(AMQProtocolSession session, int channelId, MessageStore messageStore) throws AMQException @@ -184,30 +178,36 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm _actor = new AMQPChannelActor(this, session.getLogActor().getRootMessageLogger()); _logSubject = new ChannelLogSubject(this); - _qmfId = getConfigStore().createId(); _actor.message(ChannelMessages.CREATE()); - getConfigStore().addConfiguredObject(this); - _messageStore = messageStore; // by default the session is non-transactional _transaction = new AsyncAutoCommitTransaction(_messageStore, this); - _clientDeliveryMethod = session.createDeliveryMethod(_channelId); - - _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject); - } + _clientDeliveryMethod = session.createDeliveryMethod(_channelId); - public ConfigStore getConfigStore() - { - return getVirtualHost().getConfigStore(); + _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject, new CloseAction() + { + @Override + public void doTimeoutAction(String reason) throws AMQException + { + closeConnection(reason); + } + }); } /** Sets this channel to be part of a local transaction */ public void setLocalTransactional() { - _transaction = new LocalTransaction(_messageStore); + _transaction = new LocalTransaction(_messageStore, new ActivityTimeAccessor() + { + @Override + public long getActivityTime() + { + return _session.getLastReceivedTime(); + } + }); _txnStarts.incrementAndGet(); } @@ -221,12 +221,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm sync(); } - - public boolean inTransaction() - { - return isTransactional() && _txnUpdateTime.get() > 0 && _transaction.getTransactionStartTime() > 0; - } - private void incrementOutstandingTxnsIfNecessary() { if(isTransactional()) @@ -247,11 +241,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm } } - public Long getTxnStarts() - { - return _txnStarts.get(); - } - public Long getTxnCommits() { return _txnCommits.get(); @@ -369,9 +358,8 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm } }); - _transaction.enqueue(destinationQueues, _currentMessage, new MessageDeliveryAction(_currentMessage, destinationQueues), getProtocolSession().getLastReceivedTime()); + _transaction.enqueue(destinationQueues, _currentMessage, new MessageDeliveryAction(_currentMessage, destinationQueues)); incrementOutstandingTxnsIfNecessary(); - updateTransactionalActivity(); _currentMessage.getStoredMessage().flushToStore(); } } @@ -396,7 +384,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm if (_logger.isDebugEnabled()) { - _logger.debug(debugIdentity() + "Content body received on channel " + _channelId); + _logger.debug(debugIdentity() + " content body received on channel " + _channelId); } try @@ -556,9 +544,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm { _logger.error("Caught TransportException whilst attempting to requeue:" + e); } - - getConfigStore().removeConfiguredObject(this); - } private void unsubscribeAllConsumers() throws AMQException @@ -860,7 +845,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm { Collection<QueueEntry> ackedMessages = getAckedMessages(deliveryTag, multiple); _transaction.dequeue(ackedMessages, new MessageAcknowledgeAction(ackedMessages)); - updateTransactionalActivity(); } private Collection<QueueEntry> getAckedMessages(long deliveryTag, boolean multiple) @@ -1054,19 +1038,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm } } - - - } - - /** - * Update last transaction activity timestamp - */ - private void updateTransactionalActivity() - { - if (isTransactional()) - { - _txnUpdateTime.set(getProtocolSession().getLastReceivedTime()); - } } public String toString() @@ -1149,10 +1120,16 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm ? ((BasicContentHeaderProperties) header.getProperties()).getUserId() : null; - return (!MSG_AUTH || _session.getAuthorizedPrincipal().getName().equals(userID == null? "" : userID.toString())); + return (!_messageAuthorizationRequired || _session.getAuthorizedPrincipal().getName().equals(userID == null? "" : userID.toString())); } + @Override + public UUID getId() + { + return _id; + } + public AMQConnectionModel getConnectionModel() { return _session; @@ -1168,6 +1145,12 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm return _logSubject; } + @Override + public int compareTo(AMQSessionModel o) + { + return getId().compareTo(o.getId()); + } + private class MessageDeliveryAction implements ServerTransaction.Action { private IncomingMessage _incommingMessage; @@ -1221,11 +1204,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm // TODO throw new RuntimeException(e); } - - - - - } public void onRollback() @@ -1375,7 +1353,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm public void onRollback() { - //To change body of implemented methods use File | Settings | File Templates. } } @@ -1469,97 +1446,24 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm return getProtocolSession().getVirtualHost(); } - - public ConfiguredObject getParent() - { - return getVirtualHost(); - } - - public SessionConfigType getConfigType() - { - return SessionConfigType.getInstance(); - } - public int getChannel() { return getChannelId(); } - public boolean isAttached() - { - return true; - } - - public long getDetachedLifespan() - { - return 0; - } - - public ConnectionConfig getConnectionConfig() - { - return (AMQProtocolEngine)getProtocolSession(); - } - - public Long getExpiryTime() - { - return null; - } - - public Long getMaxClientRate() - { - return null; - } - public boolean isDurable() { return false; } - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public String getSessionName() - { - return getConnectionConfig().getAddress() + "/" + getChannelId(); - } - public long getCreateTime() { return _createTime; } - public void mgmtClose() throws AMQException - { - _session.mgmtCloseChannel(_channelId); - } - public void checkTransactionStatus(long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException { - if (inTransaction()) - { - long currentTime = System.currentTimeMillis(); - long openTime = currentTime - _transaction.getTransactionStartTime(); - long idleTime = currentTime - _txnUpdateTime.get(); - - _transactionTimeoutHelper.logIfNecessary(idleTime, idleWarn, ChannelMessages.IDLE_TXN(idleTime), - TransactionTimeoutHelper.IDLE_TRANSACTION_ALERT); - if (_transactionTimeoutHelper.isTimedOut(idleTime, idleClose)) - { - closeConnection("Idle transaction timed out"); - return; - } - - _transactionTimeoutHelper.logIfNecessary(openTime, openWarn, ChannelMessages.OPEN_TXN(openTime), - TransactionTimeoutHelper.OPEN_TRANSACTION_ALERT); - if (_transactionTimeoutHelper.isTimedOut(openTime, openClose)) - { - closeConnection("Open transaction timed out"); - return; - } - } + _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, openWarn, openClose, idleWarn, idleClose); } /** @@ -1637,6 +1541,11 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm public void sync() { + if(_logger.isDebugEnabled()) + { + _logger.debug("sync() called on channel " + debugIdentity()); + } + AsyncCommand cmd; while((cmd = _unfinishedCommandsQueue.poll()) != null) { @@ -1674,16 +1583,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm _action.postCommit(); _action = null; } - - boolean isReadyForCompletion() - { - return _future.isComplete(); - } - } - - public int compareTo(AMQSessionModel session) - { - return getQMFId().compareTo(session.getQMFId()); } @Override diff --git a/java/broker/src/main/java/org/apache/qpid/server/Broker.java b/java/broker/src/main/java/org/apache/qpid/server/Broker.java index d58a0d5bb4..54dcf0543d 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/Broker.java +++ b/java/broker/src/main/java/org/apache/qpid/server/Broker.java @@ -23,37 +23,31 @@ package org.apache.qpid.server; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.util.*; -import javax.net.ssl.SSLContext; +import java.util.List; +import java.util.Properties; +import java.util.Set; + import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.configuration.ServerNetworkTransportConfiguration; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.BrokerConfigurationStoreCreator; +import org.apache.qpid.server.configuration.store.ManagementModeStoreHandler; import org.apache.qpid.server.logging.SystemOutMessageLogger; import org.apache.qpid.server.logging.actors.BrokerActor; import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.logging.actors.GenericActor; -import org.apache.qpid.server.logging.log4j.LoggingFacade; +import org.apache.qpid.server.logging.log4j.LoggingManagementFacade; import org.apache.qpid.server.logging.messages.BrokerMessages; -import org.apache.qpid.server.protocol.AmqpProtocolVersion; -import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory; import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry; -import org.apache.qpid.server.transport.QpidAcceptor; -import org.apache.qpid.ssl.SSLContextFactory; -import org.apache.qpid.transport.NetworkTransportConfiguration; -import org.apache.qpid.transport.network.IncomingNetworkTransport; -import org.apache.qpid.transport.network.Transport; - -import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS; +import org.apache.qpid.server.registry.IApplicationRegistry; public class Broker { private static final Logger LOGGER = Logger.getLogger(Broker.class); private volatile Thread _shutdownHookThread; + private volatile IApplicationRegistry _applicationRegistry; protected static class InitException extends RuntimeException { @@ -73,7 +67,17 @@ public class Broker } finally { - ApplicationRegistry.remove(); + try + { + if (_applicationRegistry != null) + { + _applicationRegistry.close(); + } + } + finally + { + clearAMQShortStringCache(); + } } } @@ -84,274 +88,76 @@ public class Broker public void startup(final BrokerOptions options) throws Exception { + CurrentActor.set(new BrokerActor(new SystemOutMessageLogger())); try { - CurrentActor.set(new BrokerActor(new SystemOutMessageLogger())); startupImpl(options); addShutdownHook(); } finally { - CurrentActor.remove(); + try + { + CurrentActor.remove(); + } + finally + { + clearAMQShortStringCache(); + } } } private void startupImpl(final BrokerOptions options) throws Exception { - final String qpidHome = options.getQpidHome(); - final File configFile = getConfigFile(options.getConfigFile(), - BrokerOptions.DEFAULT_CONFIG_FILE, qpidHome, true); - - CurrentActor.get().message(BrokerMessages.CONFIG(configFile.getAbsolutePath())); - - File logConfigFile = getConfigFile(options.getLogConfigFile(), - BrokerOptions.DEFAULT_LOG_CONFIG_FILE, qpidHome, false); - - configureLogging(logConfigFile, options.getLogWatchFrequency()); + final String qpidHome = System.getProperty(BrokerProperties.PROPERTY_QPID_HOME); + String storeLocation = options.getConfigurationStoreLocation(); + String storeType = options.getConfigurationStoreType(); - ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(configFile, options.getBundleContext()); - ServerConfiguration serverConfig = config.getConfiguration(); - if (options.getQpidWork() != null) + if (storeLocation == null) { - serverConfig.setQpidWork(options.getQpidWork()); - } - if (options.getQpidHome() != null) - { - serverConfig.setQpidHome(options.getQpidHome()); - } - updateManagementPorts(serverConfig, options.getJmxPortRegistryServer(), options.getJmxPortConnectorServer()); - - ApplicationRegistry.initialise(config); - - // We have already loaded the BrokerMessages class by this point so we - // need to refresh the locale setting incase we had a different value in - // the configuration. - BrokerMessages.reload(); - - // AR.initialise() sets and removes its own actor so we now need to set the actor - // for the remainder of the startup, and the default actor if the stack is empty - CurrentActor.set(new BrokerActor(config.getCompositeStartupMessageLogger())); - CurrentActor.setDefault(new BrokerActor(config.getRootMessageLogger())); - GenericActor.setDefaultMessageLogger(config.getRootMessageLogger()); - - try - { - Set<Integer> ports = new HashSet<Integer>(options.getPorts()); - if(ports.isEmpty()) - { - parsePortList(ports, serverConfig.getPorts()); - } - - Set<Integer> sslPorts = new HashSet<Integer>(options.getSSLPorts()); - if(sslPorts.isEmpty()) - { - parsePortList(sslPorts, serverConfig.getSSLPorts()); - } - - //1-0 excludes and includes - Set<Integer> exclude_1_0 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v1_0)); - if(exclude_1_0.isEmpty()) - { - parsePortList(exclude_1_0, serverConfig.getPortExclude10()); - } - - Set<Integer> include_1_0 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v1_0)); - if(include_1_0.isEmpty()) - { - parsePortList(include_1_0, serverConfig.getPortInclude10()); - } - - //0-10 excludes and includes - Set<Integer> exclude_0_10 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_10)); - if(exclude_0_10.isEmpty()) - { - parsePortList(exclude_0_10, serverConfig.getPortExclude010()); - } - - Set<Integer> include_0_10 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v0_10)); - if(include_0_10.isEmpty()) - { - parsePortList(include_0_10, serverConfig.getPortInclude010()); - } - - //0-9-1 excludes and includes - Set<Integer> exclude_0_9_1 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_9_1)); - if(exclude_0_9_1.isEmpty()) - { - parsePortList(exclude_0_9_1, serverConfig.getPortExclude091()); - } - - Set<Integer> include_0_9_1 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v0_9_1)); - if(include_0_9_1.isEmpty()) - { - parsePortList(include_0_9_1, serverConfig.getPortInclude091()); - } - - //0-9 excludes and includes - Set<Integer> exclude_0_9 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_9)); - if(exclude_0_9.isEmpty()) - { - parsePortList(exclude_0_9, serverConfig.getPortExclude09()); - } - - Set<Integer> include_0_9 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v0_9)); - if(include_0_9.isEmpty()) - { - parsePortList(include_0_9, serverConfig.getPortInclude09()); - } - - //0-8 excludes and includes - Set<Integer> exclude_0_8 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_8)); - if(exclude_0_8.isEmpty()) - { - parsePortList(exclude_0_8, serverConfig.getPortExclude08()); - } - - Set<Integer> include_0_8 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v0_8)); - if(include_0_8.isEmpty()) - { - parsePortList(include_0_8, serverConfig.getPortInclude08()); - } - - String bindAddr = options.getBind(); - if (bindAddr == null) - { - bindAddr = serverConfig.getBind(); - } - - InetAddress bindAddress; - if (bindAddr.equals(WILDCARD_ADDRESS)) - { - bindAddress = null; - } - else - { - bindAddress = InetAddress.getByName(bindAddr); - } - - final AmqpProtocolVersion defaultSupportedProtocolReply = serverConfig.getDefaultSupportedProtocolReply(); - - if (!serverConfig.getSSLOnly()) - { - for(int port : ports) - { - final InetSocketAddress inetSocketAddress = new InetSocketAddress(bindAddress, port); - - final Set<AmqpProtocolVersion> supported = - getSupportedVersions(port, exclude_1_0, exclude_0_10, exclude_0_9_1, exclude_0_9, exclude_0_8, - include_1_0, include_0_10, include_0_9_1, include_0_9, include_0_8,serverConfig); - - final NetworkTransportConfiguration settings = - new ServerNetworkTransportConfiguration(serverConfig, inetSocketAddress, Transport.TCP); - - final IncomingNetworkTransport transport = Transport.getIncomingTransportInstance(); - final MultiVersionProtocolEngineFactory protocolEngineFactory = - new MultiVersionProtocolEngineFactory(supported, defaultSupportedProtocolReply); - - transport.accept(settings, protocolEngineFactory, null); - - ApplicationRegistry.getInstance().addAcceptor(inetSocketAddress, - new QpidAcceptor(transport,QpidAcceptor.Transport.TCP, supported)); - CurrentActor.get().message(BrokerMessages.LISTENING("TCP", port)); - } - } - - if (serverConfig.getEnableSSL()) + String qpidWork = System.getProperty(BrokerProperties.PROPERTY_QPID_WORK); + if (qpidWork == null) { - final String keystorePath = serverConfig.getConnectorKeyStorePath(); - final String keystorePassword = serverConfig.getConnectorKeyStorePassword(); - final String keystoreType = serverConfig.getConnectorKeyStoreType(); - final String keyManagerFactoryAlgorithm = serverConfig.getConnectorKeyManagerFactoryAlgorithm(); - final SSLContext sslContext; - if(serverConfig.getConnectorTrustStorePath()!=null) - { - sslContext = SSLContextFactory.buildClientContext(serverConfig.getConnectorTrustStorePath(), - serverConfig.getConnectorTrustStorePassword(), - serverConfig.getConnectorTrustStoreType(), - serverConfig.getConnectorTrustManagerFactoryAlgorithm(), - keystorePath, - keystorePassword, keystoreType, keyManagerFactoryAlgorithm, - serverConfig.getCertAlias()); - } - else - { - sslContext = SSLContextFactory.buildServerContext(keystorePath, keystorePassword, keystoreType, keyManagerFactoryAlgorithm); - } - - for(int sslPort : sslPorts) - { - final InetSocketAddress inetSocketAddress = new InetSocketAddress(bindAddress, sslPort); - - final Set<AmqpProtocolVersion> supported = - getSupportedVersions(sslPort, exclude_1_0, exclude_0_10, exclude_0_9_1, exclude_0_9, exclude_0_8, - include_1_0, include_0_10, include_0_9_1, include_0_9, include_0_8, serverConfig); - final NetworkTransportConfiguration settings = - new ServerNetworkTransportConfiguration(serverConfig, inetSocketAddress, Transport.TCP); - - final IncomingNetworkTransport transport = Transport.getIncomingTransportInstance(); - final MultiVersionProtocolEngineFactory protocolEngineFactory = - new MultiVersionProtocolEngineFactory(supported, defaultSupportedProtocolReply); - - transport.accept(settings, protocolEngineFactory, sslContext); - - ApplicationRegistry.getInstance().addAcceptor(inetSocketAddress, - new QpidAcceptor(transport,QpidAcceptor.Transport.SSL, supported)); - CurrentActor.get().message(BrokerMessages.LISTENING("TCP/SSL", sslPort)); - } + qpidWork = new File(System.getProperty("user.dir"), "work").getAbsolutePath(); } - - CurrentActor.get().message(BrokerMessages.READY()); - } - finally - { - // Startup is complete so remove the AR initialised Startup actor - CurrentActor.remove(); + storeLocation = new File(qpidWork, BrokerOptions.DEFAULT_CONFIG_FILE + "." + storeType).getAbsolutePath(); } - } - private static Set<AmqpProtocolVersion> getSupportedVersions(final int port, - final Set<Integer> exclude_1_0, - final Set<Integer> exclude_0_10, - final Set<Integer> exclude_0_9_1, - final Set<Integer> exclude_0_9, - final Set<Integer> exclude_0_8, - final Set<Integer> include_1_0, - final Set<Integer> include_0_10, - final Set<Integer> include_0_9_1, - final Set<Integer> include_0_9, - final Set<Integer> include_0_8, - final ServerConfiguration serverConfig) - { - final EnumSet<AmqpProtocolVersion> supported = EnumSet.allOf(AmqpProtocolVersion.class); + CurrentActor.get().message(BrokerMessages.CONFIG(storeLocation)); - if((exclude_1_0.contains(port) || !serverConfig.isAmqp10enabled()) && !include_1_0.contains(port)) - { - supported.remove(AmqpProtocolVersion.v1_0_0); - } + File logConfigFile = getConfigFile(options.getLogConfigFile(), BrokerOptions.DEFAULT_LOG_CONFIG_FILE, qpidHome, false); + configureLogging(logConfigFile, options.getLogWatchFrequency()); - if((exclude_0_10.contains(port) || !serverConfig.isAmqp010enabled()) && !include_0_10.contains(port)) - { - supported.remove(AmqpProtocolVersion.v0_10); - } + BrokerConfigurationStoreCreator storeCreator = new BrokerConfigurationStoreCreator(); + ConfigurationEntryStore store = storeCreator.createStore(storeLocation, storeType, + options.getInitialConfigurationStoreLocation(), options.getInitialConfigurationStoreLocation()); - if((exclude_0_9_1.contains(port) || !serverConfig.isAmqp091enabled()) && !include_0_9_1.contains(port)) + if (options.isManagementMode()) { - supported.remove(AmqpProtocolVersion.v0_9_1); + store = new ManagementModeStoreHandler(store, options); } - if((exclude_0_9.contains(port) || !serverConfig.isAmqp09enabled()) && !include_0_9.contains(port)) + _applicationRegistry = new ApplicationRegistry(store); + try { - supported.remove(AmqpProtocolVersion.v0_9); + _applicationRegistry.initialise(); } - - if((exclude_0_8.contains(port) || !serverConfig.isAmqp08enabled()) && !include_0_8.contains(port)) + catch(Exception e) { - supported.remove(AmqpProtocolVersion.v0_8); + try + { + _applicationRegistry.close(); + } + catch(Exception ce) + { + LOGGER.debug("An error occured when closing the registry following initialization failure", ce); + } + throw e; } - return supported; } + private File getConfigFile(final String fileName, final String defaultFileName, final String qpidHome, boolean throwOnFileNotFound) throws InitException @@ -368,11 +174,11 @@ public class Broker if (!configFile.exists() && throwOnFileNotFound) { - String error = "File " + fileName + " could not be found. Check the file exists and is readable."; + String error = "File " + configFile + " could not be found. Check the file exists and is readable."; if (qpidHome == null) { - error = error + "\nNote: " + BrokerOptions.QPID_HOME + " is not set."; + error = error + "\nNote: " + BrokerProperties.PROPERTY_QPID_HOME + " is not set."; } throw new InitException(error, null); @@ -399,37 +205,6 @@ public class Broker } } - /** - * Update the configuration data with the management port. - * @param configuration - * @param registryServerPort The string from the command line - */ - private void updateManagementPorts(ServerConfiguration configuration, Integer registryServerPort, Integer connectorServerPort) - { - if (registryServerPort != null) - { - try - { - configuration.setJMXPortRegistryServer(registryServerPort); - } - catch (NumberFormatException e) - { - throw new InitException("Invalid management (registry server) port: " + registryServerPort, null); - } - } - if (connectorServerPort != null) - { - try - { - configuration.setJMXPortConnectorServer(connectorServerPort); - } - catch (NumberFormatException e) - { - throw new InitException("Invalid management (connector server) port: " + connectorServerPort, null); - } - } - } - private void configureLogging(File logConfigFile, int logWatchTime) throws InitException, IOException { if (logConfigFile.exists() && logConfigFile.canRead()) @@ -443,7 +218,7 @@ public class Broker // log4j expects the watch interval in milliseconds try { - LoggingFacade.configureAndWatch(logConfigFile.getPath(), logWatchTime * 1000); + LoggingManagementFacade.configureAndWatch(logConfigFile.getPath(), logWatchTime * 1000); } catch (Exception e) { @@ -454,7 +229,7 @@ public class Broker { try { - LoggingFacade.configure(logConfigFile.getPath()); + LoggingManagementFacade.configure(logConfigFile.getPath()); } catch (Exception e) { @@ -531,6 +306,24 @@ public class Broker LOGGER.debug("Skipping shutdown hook removal as there either isnt one, or we are it."); } } + /** + * Workaround that prevents AMQShortStrings cache from being left in the thread local. This is important + * when embedding the Broker in containers where the starting thread may not belong to Qpid. + * The long term solution here is to stop our use of AMQShortString outside the AMQP transport layer. + */ + private void clearAMQShortStringCache() + { + AMQShortString.clearLocalCache(); + } + + public org.apache.qpid.server.model.Broker getBroker() + { + if (_applicationRegistry == null) + { + return null; + } + return _applicationRegistry.getBroker(); + } private class ShutdownService implements Runnable { @@ -540,4 +333,5 @@ public class Broker Broker.this.shutdown(); } } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java b/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java index 434d40d557..57e401e608 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java +++ b/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java @@ -20,66 +20,25 @@ */ package org.apache.qpid.server; -import org.osgi.framework.BundleContext; - -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - public class BrokerOptions { - public static final String DEFAULT_CONFIG_FILE = "etc/config.xml"; + public static final String DEFAULT_STORE_TYPE = "json"; + public static final String DEFAULT_CONFIG_FILE = "config"; public static final String DEFAULT_LOG_CONFIG_FILE = "etc/log4j.xml"; - public static final String QPID_HOME = "QPID_HOME"; - public static final String QPID_WORK = "QPID_WORK"; - - private final Set<Integer> _ports = new HashSet<Integer>(); - private final Set<Integer> _sslPorts = new HashSet<Integer>(); - private final Map<ProtocolExclusion,Set<Integer>> _exclusionMap = new HashMap<ProtocolExclusion, Set<Integer>>(); - private final Map<ProtocolInclusion,Set<Integer>> _inclusionMap = new HashMap<ProtocolInclusion, Set<Integer>>(); - private String _configFile; private String _logConfigFile; - private String _bind; - private Integer _jmxPortRegistryServer; - private Integer _jmxPortConnectorServer; - private BundleContext _bundleContext; - private Integer _logWatchFrequency = 0; - private String _qpidWorkFolder; - private String _qpidHomeFolder; - public void addPort(final int port) - { - _ports.add(port); - } + private String _configurationStoreLocation; + private String _configurationStoreType = DEFAULT_STORE_TYPE; - public void addSSLPort(final int sslPort) - { - _sslPorts.add(sslPort); - } + private String _initialConfigurationStoreLocation; + private String _initialConfigurationStoreType = DEFAULT_STORE_TYPE; - public Set<Integer> getPorts() - { - return Collections.unmodifiableSet(_ports); - } - - public Set<Integer> getSSLPorts() - { - return Collections.unmodifiableSet(_sslPorts); - } - - public String getConfigFile() - { - return _configFile; - } - - public void setConfigFile(final String configFile) - { - _configFile = configFile; - } + private boolean _managementMode; + private int _managementModeRmiPort; + private int _managementModeConnectorPort; + private int _managementModeHttpPort; public String getLogConfigFile() { @@ -91,110 +50,97 @@ public class BrokerOptions _logConfigFile = logConfigFile; } - public Integer getJmxPortRegistryServer() + public int getLogWatchFrequency() { - return _jmxPortRegistryServer; + return _logWatchFrequency; } - public void setJmxPortRegistryServer(final int jmxPortRegistryServer) + /** + * Set the frequency with which the log config file will be checked for updates. + * @param logWatchFrequency frequency in seconds + */ + public void setLogWatchFrequency(final int logWatchFrequency) { - _jmxPortRegistryServer = jmxPortRegistryServer; + _logWatchFrequency = logWatchFrequency; } - public Integer getJmxPortConnectorServer() + public String getConfigurationStoreLocation() { - return _jmxPortConnectorServer; + return _configurationStoreLocation; } - public void setJmxPortConnectorServer(final int jmxPortConnectorServer) + public void setConfigurationStoreLocation(String cofigurationStore) { - _jmxPortConnectorServer = jmxPortConnectorServer; + _configurationStoreLocation = cofigurationStore; } - public String getQpidHome() + + public String getConfigurationStoreType() { - return _qpidHomeFolder == null? System.getProperty(QPID_HOME): _qpidHomeFolder; + return _configurationStoreType; } - public Set<Integer> getExcludedPorts(final ProtocolExclusion excludeProtocol) + public void setConfigurationStoreType(String cofigurationStoreType) { - final Set<Integer> excludedPorts = _exclusionMap.get(excludeProtocol); - return excludedPorts == null ? Collections.<Integer>emptySet() : excludedPorts; + _configurationStoreType = cofigurationStoreType; } - public void addExcludedPort(final ProtocolExclusion excludeProtocol, final int port) + public void setInitialConfigurationStoreLocation(String initialConfigurationStore) { - if (!_exclusionMap.containsKey(excludeProtocol)) - { - _exclusionMap.put(excludeProtocol, new HashSet<Integer>()); - } - - Set<Integer> ports = _exclusionMap.get(excludeProtocol); - ports.add(port); + _initialConfigurationStoreLocation = initialConfigurationStore; } - public String getBind() + public void setInitialConfigurationStoreType(String initialConfigurationStoreType) { - return _bind; + _initialConfigurationStoreType = initialConfigurationStoreType; } - public void setBind(final String bind) + public String getInitialConfigurationStoreLocation() { - _bind = bind; + return _initialConfigurationStoreLocation; } - public int getLogWatchFrequency() + public String getInitialConfigurationStoreType() { - return _logWatchFrequency; + return _initialConfigurationStoreType; } - /** - * Set the frequency with which the log config file will be checked for updates. - * @param logWatchFrequency frequency in seconds - */ - public void setLogWatchFrequency(final int logWatchFrequency) + public boolean isManagementMode() { - _logWatchFrequency = logWatchFrequency; + return _managementMode; } - public BundleContext getBundleContext() + public void setManagementMode(boolean managementMode) { - return _bundleContext ; + _managementMode = managementMode; } - public void setBundleContext(final BundleContext bundleContext) + public int getManagementModeRmiPort() { - _bundleContext = bundleContext; + return _managementModeRmiPort; } - public Set<Integer> getIncludedPorts(final ProtocolInclusion includeProtocol) + public void setManagementModeRmiPort(int managementModeRmiPort) { - final Set<Integer> includedPorts = _inclusionMap.get(includeProtocol); - return includedPorts == null ? Collections.<Integer>emptySet() : includedPorts; + _managementModeRmiPort = managementModeRmiPort; } - public void addIncludedPort(final ProtocolInclusion includeProtocol, final int port) + public int getManagementModeConnectorPort() { - if (!_inclusionMap.containsKey(includeProtocol)) - { - _inclusionMap.put(includeProtocol, new HashSet<Integer>()); - } - - Set<Integer> ports = _inclusionMap.get(includeProtocol); - ports.add(port); + return _managementModeConnectorPort; } - public String getQpidWork() + public void setManagementModeConnectorPort(int managementModeConnectorPort) { - return _qpidWorkFolder; + _managementModeConnectorPort = managementModeConnectorPort; } - public void setQpidWork(String qpidWorkFolder) + public int getManagementModeHttpPort() { - _qpidWorkFolder = qpidWorkFolder; + return _managementModeHttpPort; } - public void setQpidHome(String qpidHomeFolder) + public void setManagementModeHttpPort(int managementModeHttpPort) { - _qpidHomeFolder = qpidHomeFolder; + _managementModeHttpPort = managementModeHttpPort; } }
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/Main.java b/java/broker/src/main/java/org/apache/qpid/server/Main.java index 9fe7a6619f..4927956c6c 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/Main.java +++ b/java/broker/src/main/java/org/apache/qpid/server/Main.java @@ -30,9 +30,6 @@ 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.Broker.InitException; -import org.apache.qpid.server.registry.ApplicationRegistry; - /** * Main entry point for AMQPD. @@ -45,86 +42,17 @@ public class Main private static final Option OPTION_VERSION = new Option("v", "version", false, "print the version information and exit"); - private static final Option OPTION_CONFIG_FILE = - OptionBuilder.withArgName("file").hasArg().withDescription("use given configuration file").withLongOpt("config") - .create("c"); - - private static final Option OPTION_PORT = - OptionBuilder.withArgName("port").hasArg() - .withDescription("listen on the specified port. Overrides any value in the config file") - .withLongOpt("port").create("p"); - - private static final Option OPTION_SSLPORT = - OptionBuilder.withArgName("port").hasArg() - .withDescription("SSL port. Overrides any value in the config file") - .withLongOpt("sslport").create("s"); - - - private static final Option OPTION_EXCLUDE_1_0 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("when listening on the specified port do not accept AMQP1-0 connections. The specified port must be one specified on the command line") - .withLongOpt("exclude-1-0").create(); - - private static final Option OPTION_EXCLUDE_0_10 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("when listening on the specified port do not accept AMQP0-10 connections. The specified port must be one specified on the command line") - .withLongOpt("exclude-0-10").create(); - - private static final Option OPTION_EXCLUDE_0_9_1 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("when listening on the specified port do not accept AMQP0-9-1 connections. The specified port must be one specified on the command line") - .withLongOpt("exclude-0-9-1").create(); - - private static final Option OPTION_EXCLUDE_0_9 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("when listening on the specified port do not accept AMQP0-9 connections. The specified port must be one specified on the command line") - .withLongOpt("exclude-0-9").create(); - - private static final Option OPTION_EXCLUDE_0_8 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("when listening on the specified port do not accept AMQP0-8 connections. The specified port must be one specified on the command line") - .withLongOpt("exclude-0-8").create(); - - private static final Option OPTION_INCLUDE_1_0 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("accept AMQP1-0 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line") - .withLongOpt("include-1-0").create(); - -private static final Option OPTION_INCLUDE_0_10 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("accept AMQP0-10 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line") - .withLongOpt("include-0-10").create(); - -private static final Option OPTION_INCLUDE_0_9_1 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("accept AMQP0-9-1 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line") - .withLongOpt("include-0-9-1").create(); - -private static final Option OPTION_INCLUDE_0_9 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("accept AMQP0-9 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line") - .withLongOpt("include-0-9").create(); - -private static final Option OPTION_INCLUDE_0_8 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("accept AMQP0-8 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line") - .withLongOpt("include-0-8").create(); - - - private static final Option OPTION_JMX_PORT_REGISTRY_SERVER = - OptionBuilder.withArgName("port").hasArg() - .withDescription("listen on the specified management (registry server) port. Overrides any value in the config file") - .withLongOpt("jmxregistryport").create("m"); - - private static final Option OPTION_JMX_PORT_CONNECTOR_SERVER = - OptionBuilder.withArgName("port").hasArg() - .withDescription("listen on the specified management (connector server) port. Overrides any value in the config file") - .withLongOpt("jmxconnectorport").create(); - - private static final Option OPTION_BIND = - OptionBuilder.withArgName("address").hasArg() - .withDescription("bind to the specified address. Overrides any value in the config file") - .withLongOpt("bind").create("b"); + 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 store type").withLongOpt("store-type").create("st"); + + private static final Option OPTION_INITIAL_CONFIGURATION_STORE_PATH = OptionBuilder.withArgName("path").hasArg() + .withDescription("pass the location of initial store to use to create a user store").withLongOpt("initial-store-path").create("isp"); + + private static final Option OPTION_INITIAL_CONFIGURATION_STORE_TYPE = OptionBuilder.withArgName("type").hasArg() + .withDescription("the type of initial store").withLongOpt("initial-store-type").create("ist"); private static final Option OPTION_LOG_CONFIG_FILE = OptionBuilder.withArgName("file").hasArg() @@ -137,31 +65,31 @@ private static final Option OPTION_INCLUDE_0_8 = .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 a management mode") + .withLongOpt("management-mode").create("mm"); + private static final Option OPTION_RMI_PORT = OptionBuilder.withArgName("port").hasArg() + .withDescription("override jmx rmi port in management mode").withLongOpt("jmxregistryport").create("rmi"); + private static final Option OPTION_CONNECTOR_PORT = OptionBuilder.withArgName("port").hasArg() + .withDescription("override jmx connector port in management mode").withLongOpt("jmxconnectorport").create("jmxrmi"); + private static final Option OPTION_HTTP_PORT = OptionBuilder.withArgName("port").hasArg() + .withDescription("override web management port in management mode").withLongOpt("httpport").create("http"); + private static final Options OPTIONS = new Options(); static { OPTIONS.addOption(OPTION_HELP); OPTIONS.addOption(OPTION_VERSION); - OPTIONS.addOption(OPTION_CONFIG_FILE); + OPTIONS.addOption(OPTION_CONFIGURATION_STORE_PATH); + OPTIONS.addOption(OPTION_CONFIGURATION_STORE_TYPE); OPTIONS.addOption(OPTION_LOG_CONFIG_FILE); OPTIONS.addOption(OPTION_LOG_WATCH); - OPTIONS.addOption(OPTION_PORT); - OPTIONS.addOption(OPTION_SSLPORT); - OPTIONS.addOption(OPTION_EXCLUDE_1_0); - OPTIONS.addOption(OPTION_EXCLUDE_0_10); - OPTIONS.addOption(OPTION_EXCLUDE_0_9_1); - OPTIONS.addOption(OPTION_EXCLUDE_0_9); - OPTIONS.addOption(OPTION_EXCLUDE_0_8); - OPTIONS.addOption(OPTION_INCLUDE_1_0); - OPTIONS.addOption(OPTION_INCLUDE_0_10); - OPTIONS.addOption(OPTION_INCLUDE_0_9_1); - OPTIONS.addOption(OPTION_INCLUDE_0_9); - OPTIONS.addOption(OPTION_INCLUDE_0_8); - OPTIONS.addOption(OPTION_BIND); - - OPTIONS.addOption(OPTION_JMX_PORT_REGISTRY_SERVER); - OPTIONS.addOption(OPTION_JMX_PORT_CONNECTOR_SERVER); + OPTIONS.addOption(OPTION_INITIAL_CONFIGURATION_STORE_PATH); + OPTIONS.addOption(OPTION_INITIAL_CONFIGURATION_STORE_TYPE); + OPTIONS.addOption(OPTION_MANAGEMENT_MODE); + OPTIONS.addOption(OPTION_RMI_PORT); + OPTIONS.addOption(OPTION_CONNECTOR_PORT); + OPTIONS.addOption(OPTION_HTTP_PORT); } protected CommandLine _commandLine; @@ -243,10 +171,15 @@ private static final Option OPTION_INCLUDE_0_8 = else { BrokerOptions options = new BrokerOptions(); - String configFile = _commandLine.getOptionValue(OPTION_CONFIG_FILE.getOpt()); - if(configFile != null) + 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.setConfigFile(configFile); + options.setConfigurationStoreType(configurationStoreType); } String logWatchConfig = _commandLine.getOptionValue(OPTION_LOG_WATCH.getOpt()); @@ -261,52 +194,37 @@ private static final Option OPTION_INCLUDE_0_8 = options.setLogConfigFile(logConfig); } - String jmxPortRegistryServer = _commandLine.getOptionValue(OPTION_JMX_PORT_REGISTRY_SERVER.getOpt()); - if(jmxPortRegistryServer != null) + String initialConfigurationStore = _commandLine.getOptionValue(OPTION_INITIAL_CONFIGURATION_STORE_PATH.getOpt()); + if (initialConfigurationStore != null) { - options.setJmxPortRegistryServer(Integer.parseInt(jmxPortRegistryServer)); + options.setInitialConfigurationStoreLocation(initialConfigurationStore); } - - String jmxPortConnectorServer = _commandLine.getOptionValue(OPTION_JMX_PORT_CONNECTOR_SERVER.getLongOpt()); - if(jmxPortConnectorServer != null) - { - options.setJmxPortConnectorServer(Integer.parseInt(jmxPortConnectorServer)); - } - - String bindAddr = _commandLine.getOptionValue(OPTION_BIND.getOpt()); - if (bindAddr != null) + String initailConfigurationStoreType = _commandLine.getOptionValue(OPTION_INITIAL_CONFIGURATION_STORE_TYPE.getOpt()); + if (initailConfigurationStoreType != null) { - options.setBind(bindAddr); + options.setInitialConfigurationStoreType(initailConfigurationStoreType); } - String[] portStr = _commandLine.getOptionValues(OPTION_PORT.getOpt()); - if(portStr != null) + boolean managmentMode = _commandLine.hasOption(OPTION_MANAGEMENT_MODE.getOpt()); + if (managmentMode) { - parsePortArray(options, portStr, false); - for(ProtocolExclusion pe : ProtocolExclusion.values()) + options.setManagementMode(true); + String rmiPort = _commandLine.getOptionValue(OPTION_RMI_PORT.getOpt()); + if (rmiPort != null) { - parsePortArray(options, _commandLine.getOptionValues(pe.getExcludeName()), pe); + options.setManagementModeRmiPort(Integer.parseInt(rmiPort)); } - for(ProtocolInclusion pe : ProtocolInclusion.values()) + String connectorPort = _commandLine.getOptionValue(OPTION_CONNECTOR_PORT.getOpt()); + if (connectorPort != null) { - parseProtocolInclusions(options, _commandLine.getOptionValues(pe.getIncludeName()), pe); + options.setManagementModeConnectorPort(Integer.parseInt(connectorPort)); } - } - - String[] sslPortStr = _commandLine.getOptionValues(OPTION_SSLPORT.getOpt()); - if(sslPortStr != null) - { - parsePortArray(options, sslPortStr, true); - for(ProtocolExclusion pe : ProtocolExclusion.values()) + String httpPort = _commandLine.getOptionValue(OPTION_HTTP_PORT.getOpt()); + if (httpPort != null) { - parsePortArray(options, _commandLine.getOptionValues(pe.getExcludeName()), pe); - } - for(ProtocolInclusion pe : ProtocolInclusion.values()) - { - parseProtocolInclusions(options, _commandLine.getOptionValues(pe.getIncludeName()), pe); + options.setManagementModeHttpPort(Integer.parseInt(httpPort)); } } - setExceptionHandler(); startBroker(options); @@ -389,72 +307,7 @@ private static final Option OPTION_INCLUDE_0_8 = protected void shutdown(final int status) { - ApplicationRegistry.remove(); System.exit(status); } - private static void parsePortArray(final BrokerOptions options,final Object[] ports, - final boolean ssl) throws InitException - { - if(ports != null) - { - for(int i = 0; i < ports.length; i++) - { - try - { - if(ssl) - { - options.addSSLPort(Integer.parseInt(String.valueOf(ports[i]))); - } - else - { - options.addPort(Integer.parseInt(String.valueOf(ports[i]))); - } - } - catch (NumberFormatException e) - { - throw new InitException("Invalid port: " + ports[i], e); - } - } - } - } - - private static void parsePortArray(final BrokerOptions options, final Object[] ports, - final ProtocolExclusion excludedProtocol) throws InitException - { - if(ports != null) - { - for(int i = 0; i < ports.length; i++) - { - try - { - options.addExcludedPort(excludedProtocol, - Integer.parseInt(String.valueOf(ports[i]))); - } - catch (NumberFormatException e) - { - throw new InitException("Invalid port for exclusion: " + ports[i], e); - } - } - } - } - - private static void parseProtocolInclusions(final BrokerOptions options, final Object[] ports, - final ProtocolInclusion includedProtocol) throws InitException - { - if(ports != null) - { - for(int i = 0; i < ports.length; i++) - { - try - { - options.addIncludedPort(includedProtocol, Integer.parseInt(String.valueOf(ports[i]))); - } - catch (NumberFormatException e) - { - throw new InitException("Invalid port for inclusion: " + ports[i], e); - } - } - } - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java b/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java deleted file mode 100644 index fe6e32173f..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * 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.util.HashMap; -import java.util.Map; - -public enum ProtocolExclusion -{ - v0_8("exclude-0-8","--exclude-0-8"), - v0_9("exclude-0-9", "--exclude-0-9"), - v0_9_1("exclude-0-9-1", "--exclude-0-9-1"), - v0_10("exclude-0-10", "--exclude-0-10"), - v1_0("exclude-1-0", "--exclude-1-0"); - - private static final Map<String, ProtocolExclusion> MAP = new HashMap<String,ProtocolExclusion>(); - - static - { - for(ProtocolExclusion pe : ProtocolExclusion.values()) - { - MAP.put(pe.getArg(), pe); - } - } - - private String _arg; - private String _excludeName; - - private ProtocolExclusion(final String excludeName, final String arg) - { - _excludeName = excludeName; - _arg = arg; - } - - public String getArg() - { - return _arg; - } - - public String getExcludeName() - { - return _excludeName; - } - - public static ProtocolExclusion lookup(final String arg) - { - ProtocolExclusion ex = MAP.get(arg); - - if(ex == null) - { - throw new IllegalArgumentException(arg + " is not a valid protocol exclusion"); - } - - return ex; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/ProtocolInclusion.java b/java/broker/src/main/java/org/apache/qpid/server/ProtocolInclusion.java deleted file mode 100644 index 85fbe2e02e..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/ProtocolInclusion.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * 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.util.HashMap; -import java.util.Map; - -public enum ProtocolInclusion -{ - v0_8("include-0-8","--include-0-8"), - v0_9("include-0-9", "--include-0-9"), - v0_9_1("include-0-9-1", "--include-0-9-1"), - v0_10("include-0-10", "--include-0-10"), - v1_0("include-1-0", "--include-1-0"); - - private static final Map<String, ProtocolInclusion> MAP = new HashMap<String,ProtocolInclusion>(); - - static - { - for(ProtocolInclusion pe : ProtocolInclusion.values()) - { - MAP.put(pe.getArg(), pe); - } - } - - private String _arg; - private String _includeName; - - private ProtocolInclusion(final String includeName, final String arg) - { - _includeName = includeName; - _arg = arg; - } - - public String getArg() - { - return _arg; - } - - public String getIncludeName() - { - return _includeName; - } - - public static ProtocolInclusion lookup(final String arg) - { - ProtocolInclusion ex = MAP.get(arg); - - if(ex == null) - { - throw new IllegalArgumentException(arg + " is not a valid protocol inclusion"); - } - - return ex; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/TransactionTimeoutHelper.java b/java/broker/src/main/java/org/apache/qpid/server/TransactionTimeoutHelper.java index 0c474cca13..b7007bf768 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/TransactionTimeoutHelper.java +++ b/java/broker/src/main/java/org/apache/qpid/server/TransactionTimeoutHelper.java @@ -18,46 +18,85 @@ */ package org.apache.qpid.server; -import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.LogMessage; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.messages.ChannelMessages; +import org.apache.qpid.server.txn.ServerTransaction; public class TransactionTimeoutHelper { - private static final Logger LOGGER = Logger.getLogger(TransactionTimeoutHelper.class); - - public static final String IDLE_TRANSACTION_ALERT = "IDLE TRANSACTION ALERT"; - public static final String OPEN_TRANSACTION_ALERT = "OPEN TRANSACTION ALERT"; + private static final String OPEN_TRANSACTION_TIMEOUT_ERROR = "Open transaction timed out"; + private static final String IDLE_TRANSACTION_TIMEOUT_ERROR = "Idle transaction timed out"; private final LogSubject _logSubject; - public TransactionTimeoutHelper(final LogSubject logSubject) + private final CloseAction _closeAction; + + public TransactionTimeoutHelper(final LogSubject logSubject, final CloseAction closeAction) { _logSubject = logSubject; + _closeAction = closeAction; } - public void logIfNecessary(final long timeSoFar, final long warnTimeout, - final LogMessage message, final String alternateLogPrefix) + public void checkIdleOrOpenTimes(ServerTransaction transaction, long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException { - if (isTimedOut(timeSoFar, warnTimeout)) + if (transaction.isTransactional()) { - LogActor logActor = CurrentActor.get(); - if(logActor.getRootMessageLogger().isMessageEnabled(logActor, _logSubject, message.getLogHierarchy())) + final long transactionUpdateTime = transaction.getTransactionUpdateTime(); + if(transactionUpdateTime > 0) { - logActor.message(_logSubject, message); + long idleTime = System.currentTimeMillis() - transactionUpdateTime; + boolean closed = logAndCloseIfNecessary(idleTime, idleWarn, idleClose, ChannelMessages.IDLE_TXN(idleTime), IDLE_TRANSACTION_TIMEOUT_ERROR); + if (closed) + { + return; // no point proceeding to check the open time + } } - else + + final long transactionStartTime = transaction.getTransactionStartTime(); + if(transactionStartTime > 0) { - LOGGER.warn(alternateLogPrefix + " " + _logSubject.toLogString() + " " + timeSoFar + " ms"); + long openTime = System.currentTimeMillis() - transactionStartTime; + logAndCloseIfNecessary(openTime, openWarn, openClose, ChannelMessages.OPEN_TXN(openTime), OPEN_TRANSACTION_TIMEOUT_ERROR); } } } - public boolean isTimedOut(long timeSoFar, long timeout) + /** + * @return true iff closeTimeout was exceeded + */ + private boolean logAndCloseIfNecessary(final long timeSoFar, + final long warnTimeout, final long closeTimeout, + final LogMessage warnMessage, final String closeMessage) throws AMQException + { + if (isTimedOut(timeSoFar, warnTimeout)) + { + LogActor logActor = CurrentActor.get(); + logActor.message(_logSubject, warnMessage); + } + + if(isTimedOut(timeSoFar, closeTimeout)) + { + _closeAction.doTimeoutAction(closeMessage); + return true; + } + else + { + return false; + } + } + + private boolean isTimedOut(long timeSoFar, long timeout) { return timeout > 0L && timeSoFar > timeout; } + + public interface CloseAction + { + void doTimeoutAction(String reason) throws AMQException; + } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java b/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java index 9b3be624e0..469a4bb9d0 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java +++ b/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java @@ -35,13 +35,15 @@ public class Binding private final Exchange _exchange; private final Map<String, Object> _arguments; private final UUID _id; - private final UUID _qmfId; private final AtomicLong _matches = new AtomicLong(); - public Binding(UUID id, UUID qmfId, final String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> arguments) + public Binding(UUID id, + final String bindingKey, + final AMQQueue queue, + final Exchange exchange, + final Map<String, Object> arguments) { _id = id; - _qmfId = qmfId; _bindingKey = bindingKey; _queue = queue; _exchange = exchange; @@ -53,11 +55,6 @@ public class Binding return _id; } - public UUID getQMFId() - { - return _qmfId; - } - public String getBindingKey() { return _bindingKey; diff --git a/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java b/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java index b805056311..69ff081528 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java +++ b/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java @@ -24,10 +24,6 @@ import org.apache.qpid.AMQException; import org.apache.qpid.AMQInternalException; import org.apache.qpid.AMQSecurityException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.configuration.BindingConfig; -import org.apache.qpid.server.configuration.BindingConfigType; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.messages.BindingMessages; @@ -52,7 +48,7 @@ public class BindingFactory _virtualHost = vhost; } - private final class BindingImpl extends Binding implements AMQQueue.Task, Exchange.Task, BindingConfig + private final class BindingImpl extends Binding implements AMQQueue.Task, Exchange.Task { private final BindingLogSubject _logSubject; //TODO : persist creation time @@ -60,7 +56,7 @@ public class BindingFactory private BindingImpl(UUID id, String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> arguments) { - super(id, queue.getVirtualHost().getConfigStore().createId(), bindingKey, queue, exchange, arguments); + super(id, bindingKey, queue, exchange, arguments); _logSubject = new BindingLogSubject(bindingKey,exchange,queue); } @@ -96,16 +92,6 @@ public class BindingFactory return _createTime; } - public BindingConfigType getConfigType() - { - return BindingConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return _virtualHost; - } - public boolean isDurable() { return getQueue().isDurable() && getExchange().isDurable(); @@ -186,7 +172,6 @@ public class BindingFactory exchange.addCloseTask(b); queue.addBinding(b); exchange.addBinding(b); - getConfigStore().addConfiguredObject(b); b.logCreation(); return true; @@ -197,11 +182,6 @@ public class BindingFactory } } - private ConfigStore getConfigStore() - { - return _virtualHost.getConfigStore(); - } - public void restoreBinding(final UUID id, final String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> argumentMap) throws AMQSecurityException, AMQInternalException { makeBinding(id, bindingKey,queue,exchange,argumentMap,true, false); @@ -257,7 +237,6 @@ public class BindingFactory _virtualHost.getMessageStore().unbindQueue(b); } b.logDestruction(); - getConfigStore().removeConfiguredObject(b); } return b; diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java deleted file mode 100644 index 1ed6b38758..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * - * 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.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public final class BindingConfigType extends ConfigObjectType<BindingConfigType, BindingConfig> -{ - private static final List<BindingProperty<?>> BINDING_PROPERTIES = new ArrayList<BindingProperty<?>>(); - - public static interface BindingProperty<S> extends ConfigProperty<BindingConfigType, BindingConfig, S> - { - } - - private abstract static class BindingReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<BindingConfigType, BindingConfig, S> implements BindingProperty<S> - { - public BindingReadWriteProperty(String name) - { - super(name); - BINDING_PROPERTIES.add(this); - } - } - - private abstract static class BindingReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<BindingConfigType, BindingConfig, S> implements BindingProperty<S> - { - public BindingReadOnlyProperty(String name) - { - super(name); - BINDING_PROPERTIES.add(this); - } - } - - public static final BindingReadOnlyProperty<ExchangeConfig> EXCHANGE_PROPERTY = new BindingReadOnlyProperty<ExchangeConfig>("exchange") - { - public ExchangeConfig getValue(BindingConfig object) - { - return object.getExchange(); - } - }; - - public static final BindingReadOnlyProperty<QueueConfig> QUEUE_PROPERTY = new BindingReadOnlyProperty<QueueConfig>("queue") - { - public QueueConfig getValue(BindingConfig object) - { - return object.getQueue(); - } - }; - - public static final BindingReadOnlyProperty<String> BINDING_KEY_PROPERTY = new BindingReadOnlyProperty<String>("bindingKey") - { - public String getValue(BindingConfig object) - { - return object.getBindingKey(); - } - }; - - public static final BindingReadOnlyProperty<Map<String,Object>> ARGUMENTS = new BindingReadOnlyProperty<Map<String,Object>>("arguments") - { - public Map<String,Object> getValue(BindingConfig object) - { - return object.getArguments(); - } - }; - - public static final BindingReadOnlyProperty<String> ORIGIN_PROPERTY = new BindingReadOnlyProperty<String>("origin") - { - public String getValue(BindingConfig object) - { - return object.getOrigin(); - } - }; - - private static final BindingConfigType INSTANCE = new BindingConfigType(); - - private BindingConfigType() - { - } - - public Collection<BindingProperty<?>> getProperties() - { - return Collections.unmodifiableList(BINDING_PROPERTIES); - } - - public static BindingConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfig.java deleted file mode 100644 index 00ed5fd0dd..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfig.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * 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.configuration; - -public interface BridgeConfig extends ConfiguredObject<BridgeConfigType, BridgeConfig> -{ - - boolean isDynamic(); - - boolean isQueueBridge(); - - boolean isLocalSource(); - - String getSource(); - - String getDestination(); - - String getKey(); - - String getTag(); - - String getExcludes(); - - LinkConfig getLink(); - - Integer getChannelId(); - - int getAckBatching(); -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java deleted file mode 100644 index 888feeff0c..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * - * 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.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public final class BridgeConfigType extends ConfigObjectType<BridgeConfigType, BridgeConfig> -{ - private static final List<BridgeProperty<?>> BRIDGE_PROPERTIES = new ArrayList<BridgeProperty<?>>(); - - public static interface BridgeProperty<S> extends ConfigProperty<BridgeConfigType, BridgeConfig, S> - { - } - - private abstract static class BridgeReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<BridgeConfigType, BridgeConfig, S> implements BridgeProperty<S> - { - public BridgeReadWriteProperty(String name) - { - super(name); - BRIDGE_PROPERTIES.add(this); - } - } - - private abstract static class BridgeReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<BridgeConfigType, BridgeConfig, S> implements BridgeProperty<S> - { - public BridgeReadOnlyProperty(String name) - { - super(name); - BRIDGE_PROPERTIES.add(this); - } - } - - public static final BridgeReadOnlyProperty<LinkConfig> LINK_PROPERTY = new BridgeReadOnlyProperty<LinkConfig>("link") - { - public LinkConfig getValue(BridgeConfig object) - { - return object.getLink(); - } - }; - - public static final BridgeReadOnlyProperty<Integer> CHANNEL_ID_PROPERTY = new BridgeReadOnlyProperty<Integer>("channelId") - { - public Integer getValue(BridgeConfig object) - { - return object.getChannelId(); - } - }; - - public static final BridgeReadOnlyProperty<Boolean> DURABLE_PROPERTY = new BridgeReadOnlyProperty<Boolean>("durable") - { - public Boolean getValue(BridgeConfig object) - { - return object.isDurable(); - } - }; - - public static final BridgeReadOnlyProperty<String> SOURCE_PROPERTY = new BridgeReadOnlyProperty<String>("source") - { - public String getValue(BridgeConfig object) - { - return object.getSource(); - } - }; - - public static final BridgeReadOnlyProperty<String> DESTINATION_PROPERTY = new BridgeReadOnlyProperty<String>("destination") - { - public String getValue(BridgeConfig object) - { - return object.getDestination(); - } - }; - - public static final BridgeReadOnlyProperty<String> KEY_PROPERTY = new BridgeReadOnlyProperty<String>("key") - { - public String getValue(BridgeConfig object) - { - return object.getKey(); - } - }; - - public static final BridgeReadOnlyProperty<Boolean> QUEUE_BRIDGE_PROPERTY = new BridgeReadOnlyProperty<Boolean>("queueBridge") - { - public Boolean getValue(BridgeConfig object) - { - return object.isQueueBridge(); - } - }; - - public static final BridgeReadOnlyProperty<Boolean> LOCAL_SOURCE_PROPERTY = new BridgeReadOnlyProperty<Boolean>("localSource") - { - public Boolean getValue(BridgeConfig object) - { - return object.isLocalSource(); - } - }; - - public static final BridgeReadOnlyProperty<String> TAG_PROPERTY = new BridgeReadOnlyProperty<String>("tag") - { - public String getValue(BridgeConfig object) - { - return object.getTag(); - } - }; - - public static final BridgeReadOnlyProperty<String> EXCLUDES_PROPERTY = new BridgeReadOnlyProperty<String>("excludes") - { - public String getValue(BridgeConfig object) - { - return object.getExcludes(); - } - }; - - public static final BridgeReadOnlyProperty<Boolean> DYNAMIC_PROPERTY = new BridgeReadOnlyProperty<Boolean>("dynamic") - { - public Boolean getValue(BridgeConfig object) - { - return object.isDynamic(); - } - }; - - public static final BridgeReadOnlyProperty<Integer> ACK_BATCHING_PROPERTY = new BridgeReadOnlyProperty<Integer>("ackBatching") - { - public Integer getValue(BridgeConfig object) - { - return object.getAckBatching(); - } - }; - - - private static final BridgeConfigType INSTANCE = new BridgeConfigType(); - - private BridgeConfigType() - { - } - - public Collection<BridgeProperty<?>> getProperties() - { - return Collections.unmodifiableList(BRIDGE_PROPERTIES); - } - - public static BridgeConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfig.java deleted file mode 100644 index 7dffc2d3c0..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfig.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * - * 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.configuration; - -import java.util.List; - - -public interface BrokerConfig extends ConfiguredObject<BrokerConfigType,BrokerConfig> -{ - void setSystem(SystemConfig system); - - SystemConfig getSystem(); - - Integer getPort(); - - Integer getWorkerThreads(); - - Integer getMaxConnections(); - - Integer getConnectionBacklogLimit(); - - Long getStagingThreshold(); - - Integer getManagementPublishInterval(); - - String getVersion(); - - String getDataDirectory(); - - String getFederationTag(); - - /** - * List of feature(s) to be advertised to clients on connection. - * Feature names are strings, beginning with qpid. followed by more or more - * words separated by minus signs e.g. qpid.jms-selector. - * - * If there are no features, this method must return an empty array. - * - * @return list of feature names - */ - List<String> getFeatures(); - - void addVirtualHost(VirtualHostConfig virtualHost); - - void createBrokerConnection(String transport, - String host, - int port, - boolean durable, - String authMechanism, - String username, String password); - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java deleted file mode 100644 index 64a59c3f61..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * - * 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.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public final class BrokerConfigType extends ConfigObjectType<BrokerConfigType, BrokerConfig> -{ - private static final List<BrokerProperty<?>> BROKER_PROPERTIES = new ArrayList<BrokerProperty<?>>(); - - public static interface BrokerProperty<S> extends ConfigProperty<BrokerConfigType, BrokerConfig, S> - { - } - - private abstract static class BrokerReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<BrokerConfigType, BrokerConfig, S> implements BrokerProperty<S> - { - public BrokerReadWriteProperty(String name) - { - super(name); - BROKER_PROPERTIES.add(this); - } - } - - private abstract static class BrokerReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<BrokerConfigType, BrokerConfig, S> implements BrokerProperty<S> - { - public BrokerReadOnlyProperty(String name) - { - super(name); - BROKER_PROPERTIES.add(this); - } - } - - public static final BrokerReadOnlyProperty<SystemConfig> SYSTEM_PROPERTY = new BrokerReadOnlyProperty<SystemConfig>("system") - { - public SystemConfig getValue(BrokerConfig object) - { - return object.getSystem(); - } - }; - - public static final BrokerReadOnlyProperty<Integer> PORT_PROPERTY = new BrokerReadOnlyProperty<Integer>("port") - { - public Integer getValue(BrokerConfig object) - { - return object.getPort(); - } - }; - - public static final BrokerReadOnlyProperty<Integer> WORKER_THREADS_PROPERTY = new BrokerReadOnlyProperty<Integer>("workerThreads") - { - public Integer getValue(BrokerConfig object) - { - return object.getWorkerThreads(); - } - }; - - public static final BrokerReadOnlyProperty<Integer> MAX_CONNECTIONS_PROPERTY = new BrokerReadOnlyProperty<Integer>("maxConnections") - { - public Integer getValue(BrokerConfig object) - { - return object.getMaxConnections(); - } - }; - - public static final BrokerReadOnlyProperty<Integer> CONNECTION_BACKLOG_LIMIT_PROPERTY = new BrokerReadOnlyProperty<Integer>("connectionBacklog") - { - public Integer getValue(BrokerConfig object) - { - return object.getConnectionBacklogLimit(); - } - }; - - public static final BrokerReadOnlyProperty<Long> STAGING_THRESHOLD_PROPERTY = new BrokerReadOnlyProperty<Long>("stagingThreshold") - { - public Long getValue(BrokerConfig object) - { - return object.getStagingThreshold(); - } - }; - - public static final BrokerReadOnlyProperty<Integer> MANAGEMENT_PUBLISH_INTERVAL_PROPERTY = new BrokerReadOnlyProperty<Integer>("mgmtPublishInterval") - { - public Integer getValue(BrokerConfig object) - { - return object.getManagementPublishInterval(); - } - }; - - public static final BrokerReadOnlyProperty<String> VERSION_PROPERTY = new BrokerReadOnlyProperty<String>("version") - { - public String getValue(BrokerConfig object) - { - return object.getVersion(); - } - }; - - public static final BrokerReadOnlyProperty<String> DATA_DIR_PROPERTY = new BrokerReadOnlyProperty<String>("dataDirectory") - { - public String getValue(BrokerConfig object) - { - return object.getDataDirectory(); - } - }; - - private static final BrokerConfigType INSTANCE = new BrokerConfigType(); - - private BrokerConfigType() - { - } - - public Collection<BrokerProperty<?>> getProperties() - { - return Collections.unmodifiableList(BROKER_PROPERTIES); - } - - public static BrokerConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreator.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreator.java new file mode 100644 index 0000000000..31e08ab88a --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreator.java @@ -0,0 +1,102 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore; +import org.apache.qpid.server.plugin.QpidServiceLoader; + +/** + * A helper class responsible for creation and opening of broker store. + */ +public class BrokerConfigurationStoreCreator +{ + /** + * URL to resource containing broker default configuration + */ + public static final String DEFAULT_INITIAL_STORE_LOCATION = BrokerConfigurationStoreCreator.class.getClassLoader() + .getResource("initial-store.json").toExternalForm(); + + private Map<String, ConfigurationStoreFactory> _factories = new HashMap<String, ConfigurationStoreFactory>(); + + public BrokerConfigurationStoreCreator() + { + QpidServiceLoader<ConfigurationStoreFactory> serviceLoader = new QpidServiceLoader<ConfigurationStoreFactory>(); + Iterable<ConfigurationStoreFactory> configurationStoreFactories = serviceLoader + .instancesOf(ConfigurationStoreFactory.class); + for (ConfigurationStoreFactory storeFactory : configurationStoreFactories) + { + String type = storeFactory.getStoreType(); + ConfigurationStoreFactory factory = _factories.put(type.toLowerCase(), storeFactory); + if (factory != null) + { + throw new IllegalStateException("ConfigurationStoreFactory with type name '" + type + + "' is already registered using class '" + factory.getClass().getName() + "', can not register class '" + + storeFactory.getClass().getName() + "'"); + } + } + } + + /** + * Create broker configuration store for a given store location, store type, initial store location and initial store type + * + * @param storeLocation store location + * @param storeType store type + * @param initialStoreLocation initial store location + * @param initialStoreType initial store type + * @return store instance opened at given store location + * @throws IllegalConfigurationException if store type is unknown + */ + public ConfigurationEntryStore createStore(String storeLocation, String storeType, String initialStoreLocation, + String initialStoreType) + { + ConfigurationEntryStore store = createStore(storeType); + if (initialStoreLocation == null) + { + initialStoreLocation = DEFAULT_INITIAL_STORE_LOCATION; + initialStoreType = JsonConfigurationEntryStore.STORE_TYPE; + } + if (storeType.equals(initialStoreType)) + { + store.open(storeLocation, initialStoreLocation); + } + else + { + ConfigurationEntryStore initialStore = createStore(initialStoreType); + initialStore.open(initialStoreLocation); + store.open(storeLocation, initialStore); + } + return store; + } + + private ConfigurationEntryStore createStore(String storeType) + { + ConfigurationStoreFactory factory = _factories.get(storeType.toLowerCase()); + if (factory == null) + { + throw new IllegalConfigurationException("Unknown store type: " + storeType); + } + return factory.createStore(); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerProperties.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerProperties.java new file mode 100644 index 0000000000..179d4a5640 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerProperties.java @@ -0,0 +1,54 @@ +package org.apache.qpid.server.configuration; + +import java.util.Locale; + +/** + * Declares broker system property names + */ +public class BrokerProperties +{ + public static final int DEFAULT_HEART_BEAT_TIMEOUT_FACTOR = 2; + + public static final String PROPERTY_DEAD_LETTER_EXCHANGE_SUFFIX = "qpid.dead_letter_exchange_suffix"; + public static final String PROPERTY_DEAD_LETTER_QUEUE_SUFFIX = "qpid.dead_letter_queue_suffix"; + + public static final String PROPERTY_FRAME_SIZE = "qpid.frame_size"; + public static final String PROPERTY_MSG_AUTH = "qpid.msg_auth"; + public static final String PROPERTY_STATUS_UPDATES = "qpid.status_updates"; + public static final String PROPERTY_LOCALE = "qpid.locale"; + public static final String PROPERTY_DEFAULT_SUPPORTED_PROTOCOL_REPLY = "qpid.default_supported_protocol_version_reply"; + public static final String PROPERTY_DISABLED_FEATURES = "qpid.broker_disabled_features"; + + public static final int DEFAULT_FRAME_SIZE = Integer.getInteger(PROPERTY_FRAME_SIZE, 65535); + public static final String PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES = "qpid.broker_default_amqp_protocol_excludes"; + public static final String PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES = "qpid.broker_default_amqp_protocol_includes"; + + public static final String PROPERTY_MANAGEMENT_RIGHTS_INFER_ALL_ACCESS = "qpid.broker_jmx_method_rights_infer_all_access"; + public static final String PROPERTY_USE_CUSTOM_RMI_SOCKET_FACTORY = "qpid.broker_jmx_use_custom_rmi_socket_factory"; + + public static final String PROPERTY_QPID_HOME = "QPID_HOME"; + public static final String PROPERTY_QPID_WORK = "QPID_WORK"; + + private BrokerProperties() + { + } + + public static Locale getLocale() + { + Locale locale = Locale.US; + String localeSetting = System.getProperty(BrokerProperties.PROPERTY_LOCALE); + if (localeSetting != null) + { + String[] localeParts = localeSetting.split("_"); + String language = (localeParts.length > 0 ? localeParts[0] : ""); + String country = (localeParts.length > 1 ? localeParts[1] : ""); + String variant = ""; + if (localeParts.length > 2) + { + variant = localeSetting.substring(language.length() + 1 + country.length() + 1); + } + locale = new Locale(language, country, variant); + } + return locale; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigProperty.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigProperty.java deleted file mode 100644 index 2d88ba00a0..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigProperty.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * 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.configuration; - -public interface ConfigProperty<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>, S> -{ - public String getName(); - - public S getValue(C object); - - public void setValue(C object, S value); - - public void clearValue(C object); - - public abstract static class ReadWriteConfigProperty<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>,S> implements ConfigProperty<T, C, S> - { - private final String _name; - - protected ReadWriteConfigProperty(String name) - { - _name = name; - } - - public final String getName() - { - return _name; - } - } - - public abstract static class ReadOnlyConfigProperty<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>, S> extends ReadWriteConfigProperty<T, C, S> - { - protected ReadOnlyConfigProperty(String name) - { - super(name); - } - - public final void setValue(C object, S value) - { - throw new UnsupportedOperationException("Cannot set value '"+getName()+"' as this property is read-only"); - } - - public final void clearValue(C object) - { - throw new UnsupportedOperationException("Cannot set value '"+getName()+"' as this property is read-only"); - } - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java deleted file mode 100644 index c519a0c0fa..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * - * 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.configuration; - -import java.util.Collection; -import java.util.Collections; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; - -public class ConfigStore -{ - private ConcurrentHashMap<ConfigObjectType, ConcurrentHashMap<UUID, ConfiguredObject>> _typeMap = - new ConcurrentHashMap<ConfigObjectType, ConcurrentHashMap<UUID, ConfiguredObject>>(); - - private ConcurrentHashMap<ConfigObjectType, CopyOnWriteArrayList<ConfigEventListener>> _listenerMap = - new ConcurrentHashMap<ConfigObjectType, CopyOnWriteArrayList<ConfigEventListener>>(); - - private AtomicReference<SystemConfig> _root = new AtomicReference<SystemConfig>(null); - - private final AtomicLong _objectIdSource = new AtomicLong(0l); - private final AtomicLong _persistentObjectIdSource = new AtomicLong(0l); - - // TODO - should load/increment this on broker startup - private long _sequenceNumber = 1L; - - public enum Event - { - CREATED, DELETED - } - - public interface ConfigEventListener<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T, C>> - { - void onEvent(C object, Event evt); - } - - private ConfigStore() - { - } - - public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> ConfiguredObject<T, C> getConfiguredObject(ConfigObjectType<T,C> type, UUID id) - { - ConcurrentHashMap<UUID, ConfiguredObject> typeMap = _typeMap.get(type); - if(typeMap != null) - { - return typeMap.get(id); - } - else - { - return null; - } - - } - - public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> Collection<? extends C> getConfiguredObjects(ConfigObjectType<T,C> type) - { - ConcurrentHashMap typeMap = _typeMap.get(type); - if(typeMap != null) - { - return typeMap.values(); - } - else - { - return Collections.EMPTY_LIST; - } - - } - - public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void addConfiguredObject(ConfiguredObject<T, C> object) - { - ConcurrentHashMap typeMap = _typeMap.get(object.getConfigType()); - if(typeMap == null) - { - typeMap = new ConcurrentHashMap(); - ConcurrentHashMap oldMap = _typeMap.putIfAbsent(object.getConfigType(), typeMap); - if(oldMap != null) - { - typeMap = oldMap; - } - - } - - typeMap.put(object.getQMFId(), object); - sendEvent(Event.CREATED, object); - } - - - public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void removeConfiguredObject(ConfiguredObject<T, C> object) - { - ConcurrentHashMap typeMap = _typeMap.get(object.getConfigType()); - if(typeMap != null) - { - typeMap.remove(object.getQMFId()); - sendEvent(Event.DELETED, object); - } - } - - public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void addConfigEventListener(T type, ConfigEventListener<T,C> listener) - { - CopyOnWriteArrayList listeners = _listenerMap.get(type); - if(listeners == null) - { - listeners = new CopyOnWriteArrayList(); - CopyOnWriteArrayList oldListeners = _listenerMap.putIfAbsent(type, listeners); - if(oldListeners != null) - { - listeners = oldListeners; - } - - } - - listeners.add(listener); - - } - - public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void removeConfigEventListener(T type, ConfigEventListener<T,C> listener) - { - CopyOnWriteArrayList listeners = _listenerMap.get(type); - if(listeners != null) - { - listeners.remove(listener); - } - } - - private void sendEvent(Event e, ConfiguredObject o) - { - CopyOnWriteArrayList<ConfigEventListener> listeners = _listenerMap.get(o.getConfigType()); - if(listeners != null) - { - for(ConfigEventListener listener : listeners) - { - listener.onEvent(o, e); - } - } - } - - public boolean setRoot(SystemConfig object) - { - if(_root.compareAndSet(null,object)) - { - addConfiguredObject(object); - return true; - } - else - { - return false; - } - } - - public UUID createId() - { - return new UUID(((_sequenceNumber & 0xFFFl)<<48), _objectIdSource.incrementAndGet()); - } - - public UUID createPersistentId() - { - return new UUID(0L, _persistentObjectIdSource.incrementAndGet()); - } - - public void persistentIdInUse(UUID id) - { - long lsb = id.getLeastSignificantBits(); - long currentId; - while((currentId = _persistentObjectIdSource.get()) < lsb) - { - _persistentObjectIdSource.compareAndSet(currentId, lsb); - } - } - - public SystemConfig getRoot() - { - return _root.get(); - } - - public static ConfigStore newInstance() - { - return new ConfigStore(); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntry.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntry.java new file mode 100644 index 0000000000..8afb1af24d --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntry.java @@ -0,0 +1,203 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +public class ConfigurationEntry +{ + public static final String ATTRIBUTE_NAME = "name"; + + private final UUID _id; + private final String _type; + private final Map<String, Object> _attributes; + private final Set<UUID> _childrenIds; + private final ConfigurationEntryStore _store; + + public ConfigurationEntry(UUID id, String type, Map<String, Object> attributes, Set<UUID> childrenIds, + ConfigurationEntryStore store) + { + super(); + _id = id; + _type = type; + _attributes = attributes; + _childrenIds = childrenIds; + _store = store; + } + + public UUID getId() + { + return _id; + } + + public String getType() + { + return _type; + } + + public Map<String, Object> getAttributes() + { + return _attributes; + } + + public Set<UUID> getChildrenIds() + { + return _childrenIds; + } + + public ConfigurationEntryStore getStore() + { + return _store; + } + + /** + * Returns this entry's children. The collection should not be modified. + */ + public Map<String, Collection<ConfigurationEntry>> getChildren() + { + Map<String, Collection<ConfigurationEntry>> children = null; + if (_childrenIds == null) + { + children = Collections.emptyMap(); + } + else + { + children = new HashMap<String, Collection<ConfigurationEntry>>(); + for (UUID childId : _childrenIds) + { + ConfigurationEntry entry = _store.getEntry(childId); + String type = entry.getType(); + Collection<ConfigurationEntry> childrenOfType = children.get(type); + if (childrenOfType == null) + { + childrenOfType = new ArrayList<ConfigurationEntry>(); + children.put(type, childrenOfType); + } + childrenOfType.add(entry); + } + } + return Collections.unmodifiableMap(children); + } + + public boolean hasChild(UUID id) + { + return _childrenIds.contains(id); + } + + @Override + public int hashCode() + { + return _id.hashCode(); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + + ConfigurationEntry other = (ConfigurationEntry) obj; + if (_id == null) + { + if (other._id != null) + { + return false; + } + } + else if (!_id.equals(other._id)) + { + return false; + } + + if (_type == null) + { + if (other._type != null) + { + return false; + } + } + else if (!_type.equals(other._type)) + { + return false; + } + + if (_store == null) + { + if (other._store != null) + { + return false; + } + } + else if (!_store.equals(other._store)) + { + return false; + } + + if (_childrenIds == null) + { + if (other._childrenIds != null) + { + return false; + } + } + else if (!_childrenIds.equals(other._childrenIds)) + { + return false; + } + + if (_attributes == null) + { + if (other._attributes != null) + { + return false; + } + } + else if (!_attributes.equals(other._attributes)) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return "ConfigurationEntry [id=" + _id + ", type=" + _type + ", attributes=" + _attributes + ", childrenIds=" + + _childrenIds + "]"; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java new file mode 100644 index 0000000000..8238d147bd --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java @@ -0,0 +1,98 @@ +/* + * + * 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.configuration; + +import java.util.UUID; + +public interface ConfigurationEntryStore +{ + /** + * Opens the store from a given location. + * <p> + * If location does not exists than a new empty store is created with a single root entry + * + * @param storeLocation store location + * @throws IllegalConfigurationException if store cannot be opened in the given location + */ + void open(String storeLocation); + + /** + * Opens the store from a given location. + * <p> + * If location does not exists than a new store is created either empty or from the initial store location if it is provided + * + * @param storeLocation store location + * @param initialStoreLocation initial store location + * @throws IllegalConfigurationException if store cannot be opened in the given location or initial store location does not + * exists or corrupted. + */ + void open(String storeLocation, String initialStoreLocation); + + /** + * Opens the store from a given location. + * <p> + * If location does not exists than a new store is created either empty or from the initial store if it is provided + * + * @param storeLocation store location + * @param initialStore initial store + * @throws IllegalConfigurationException if store cannot be opened in the given location + */ + void open(String storeLocation, ConfigurationEntryStore initialStore); + + /** + * Returns stored root configuration entry + * + * @return root entry + */ + ConfigurationEntry getRootEntry(); + + /** + * Returns the configuration entry with a given id. + * + * @return entry with a given id or null if entry does not exists + */ + ConfigurationEntry getEntry(UUID id); + + /** + * Saves given entries in the store. + * + * @param entries entries to store + * @throws IllegalConfigurationException if save operation fails + */ + void save(ConfigurationEntry... entries); + + /** + * Removes the entries with given IDs and all their children + * + * @param entryIds IDs of entries to remove + * @return IDs of removed entries + * @throws IllegalConfigurationException if remove operation fails + */ + UUID[] remove(UUID... entryIds); + + /** + * Copies the store into the given location + * + * @param target location to copy store into + * @throws IllegalConfigurationException if store cannot be copied into given location + */ + public void copyTo(String copyLocation); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationManager.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationManager.java deleted file mode 100644 index 06402fa646..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationManager.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * 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.configuration; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; -import org.apache.qpid.server.registry.ApplicationRegistry; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -public class ConfigurationManager -{ - public List<ConfigurationPlugin> getConfigurationPlugins(String configurationElement, Configuration configuration) throws ConfigurationException - { - List<ConfigurationPlugin> plugins = new ArrayList<ConfigurationPlugin>(); - Map<List<String>, ConfigurationPluginFactory> factories = - ApplicationRegistry.getInstance().getPluginManager().getConfigurationPlugins(); - - for (Entry<List<String>, ConfigurationPluginFactory> entry : factories.entrySet()) - { - if (entry.getKey().contains(configurationElement)) - { - ConfigurationPluginFactory factory = entry.getValue(); - plugins.add(factory.newInstance(configurationElement, configuration)); - } - } - - return plugins; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigurationPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationStoreFactory.java index bfb2de4235..dced38d260 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigurationPlugin.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationStoreFactory.java @@ -20,10 +20,16 @@ */ package org.apache.qpid.server.configuration; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.queue.AMQQueue; -public interface ExchangeConfigurationPlugin +public interface ConfigurationStoreFactory { - ConfigurationPlugin getConfiguration(AMQQueue queue); + /** + * Returns the type of the store this factory can create + */ + public String getStoreType(); + + /** + * Creates the store instance. + */ + public ConfigurationEntryStore createStore(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigObjectType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObjectRecoverer.java index c45aaaf1ee..65d97e6db1 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigObjectType.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObjectRecoverer.java @@ -18,13 +18,11 @@ * under the License. * */ - package org.apache.qpid.server.configuration; -import java.util.Collection; +import org.apache.qpid.server.model.ConfiguredObject; -public abstract class ConfigObjectType<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>> +public interface ConfiguredObjectRecoverer<T extends ConfiguredObject> { - public abstract Collection<? extends ConfigProperty<T, C, ?>> getProperties(); - + T create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfig.java deleted file mode 100644 index 0dd36fe1fe..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfig.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * 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.configuration; - -public interface ConnectionConfig extends ConfiguredObject<ConnectionConfigType, ConnectionConfig> -{ - VirtualHostConfig getVirtualHost(); - - String getAddress(); - - Boolean isIncoming(); - - Boolean isSystemConnection(); - - Boolean isFederationLink(); - - String getAuthId(); - - String getRemoteProcessName(); - - Integer getRemotePID(); - - Integer getRemoteParentPID(); - - ConfigStore getConfigStore(); - - Boolean isShadow(); - - void mgmtClose(); -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java deleted file mode 100644 index 5631fda37c..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * - * 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.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public final class ConnectionConfigType extends ConfigObjectType<ConnectionConfigType, ConnectionConfig> -{ - private static final List<ConnectionProperty<?>> CONNECTION_PROPERTIES = new ArrayList<ConnectionProperty<?>>(); - - public static interface ConnectionProperty<S> extends ConfigProperty<ConnectionConfigType, ConnectionConfig, S> - { - } - - private abstract static class ConnectionReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<ConnectionConfigType, ConnectionConfig, S> implements ConnectionProperty<S> - { - public ConnectionReadWriteProperty(String name) - { - super(name); - CONNECTION_PROPERTIES.add(this); - } - } - - private abstract static class ConnectionReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<ConnectionConfigType, ConnectionConfig, S> implements ConnectionProperty<S> - { - public ConnectionReadOnlyProperty(String name) - { - super(name); - CONNECTION_PROPERTIES.add(this); - } - } - - public static final ConnectionReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new ConnectionReadOnlyProperty<VirtualHostConfig>("virtualHost") - { - public VirtualHostConfig getValue(ConnectionConfig object) - { - return object.getVirtualHost(); - } - }; - - public static final ConnectionReadOnlyProperty<String> ADDRESS_PROPERTY = new ConnectionReadOnlyProperty<String>("address") - { - public String getValue(ConnectionConfig object) - { - return object.getAddress(); - } - }; - - public static final ConnectionReadOnlyProperty<Boolean> INCOMING_PROPERTY = new ConnectionReadOnlyProperty<Boolean>("incoming") - { - public Boolean getValue(ConnectionConfig object) - { - return object.isIncoming(); - } - }; - - public static final ConnectionReadOnlyProperty<Boolean> SYSTEM_CONNECTION_PROPERTY = new ConnectionReadOnlyProperty<Boolean>("systemConnection") - { - public Boolean getValue(ConnectionConfig object) - { - return object.isSystemConnection(); - } - }; - - public static final ConnectionReadOnlyProperty<Boolean> FEDERATION_LINK_PROPERTY = new ConnectionReadOnlyProperty<Boolean>("federationLink") - { - public Boolean getValue(ConnectionConfig object) - { - return object.isFederationLink(); - } - }; - - public static final ConnectionReadOnlyProperty<String> AUTH_ID_PROPERTY = new ConnectionReadOnlyProperty<String>("authId") - { - public String getValue(ConnectionConfig object) - { - return object.getAuthId(); - } - }; - - public static final ConnectionReadOnlyProperty<String> REMOTE_PROCESS_NAME_PROPERTY = new ConnectionReadOnlyProperty<String>("remoteProcessName") - { - public String getValue(ConnectionConfig object) - { - return object.getRemoteProcessName(); - } - }; - - - public static final ConnectionReadOnlyProperty<Integer> REMOTE_PID_PROPERTY = new ConnectionReadOnlyProperty<Integer>("remotePid") - { - public Integer getValue(ConnectionConfig object) - { - return object.getRemotePID(); - } - }; - - public static final ConnectionReadOnlyProperty<Integer> REMOTE_PARENT_PID_PROPERTY = new ConnectionReadOnlyProperty<Integer>("remoteParentPid") - { - public Integer getValue(ConnectionConfig object) - { - return object.getRemoteParentPID(); - } - }; - - private static final ConnectionConfigType INSTANCE = new ConnectionConfigType(); - - private ConnectionConfigType() - { - } - - public Collection<ConnectionProperty<?>> getProperties() - { - return Collections.unmodifiableList(CONNECTION_PROPERTIES); - } - - public static ConnectionConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java deleted file mode 100644 index 6633d93adf..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * 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.configuration; - -import org.apache.qpid.server.exchange.ExchangeType; - -import java.util.Map; - - -public interface ExchangeConfig extends ConfiguredObject<ExchangeConfigType, ExchangeConfig> -{ - VirtualHostConfig getVirtualHost(); - - String getName(); - - ExchangeType getType(); - - boolean isAutoDelete(); - - ExchangeConfig getAlternateExchange(); - - Map<String, Object> getArguments(); - - - long getBindingCount(); - - long getBindingCountHigh(); - - long getMsgReceives(); - - long getMsgRoutes(); - - long getMsgDrops(); - - long getByteReceives(); - - long getByteRoutes(); - - long getByteDrops(); - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java deleted file mode 100644 index c7744117c4..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * - * 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.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public final class ExchangeConfigType extends ConfigObjectType<ExchangeConfigType, ExchangeConfig> -{ - private static final List<ExchangeProperty<?>> EXCHANGE_PROPERTIES = new ArrayList<ExchangeProperty<?>>(); - - public static interface ExchangeProperty<S> extends ConfigProperty<ExchangeConfigType, ExchangeConfig, S> - { - } - - private abstract static class ExchangeReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<ExchangeConfigType, ExchangeConfig, S> implements ExchangeProperty<S> - { - public ExchangeReadWriteProperty(String name) - { - super(name); - EXCHANGE_PROPERTIES.add(this); - } - } - - private abstract static class ExchangeReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<ExchangeConfigType, ExchangeConfig, S> implements ExchangeProperty<S> - { - public ExchangeReadOnlyProperty(String name) - { - super(name); - EXCHANGE_PROPERTIES.add(this); - } - } - - public static final ExchangeReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new ExchangeReadOnlyProperty<VirtualHostConfig>("virtualHost") - { - public VirtualHostConfig getValue(ExchangeConfig object) - { - return object.getVirtualHost(); - } - }; - - public static final ExchangeReadOnlyProperty<String> NAME_PROPERTY = new ExchangeReadOnlyProperty<String>("name") - { - public String getValue(ExchangeConfig object) - { - return object.getName(); - } - }; - - public static final ExchangeReadOnlyProperty<Boolean> AUTODELETE_PROPERTY = new ExchangeReadOnlyProperty<Boolean>("autodelete") - { - public Boolean getValue(ExchangeConfig object) - { - return object.isAutoDelete(); - } - }; - - - public static final ExchangeReadOnlyProperty<ExchangeConfig> ALTERNATE_EXCHANGE_PROPERTY = new ExchangeReadOnlyProperty<ExchangeConfig>("alternateExchange") - { - public ExchangeConfig getValue(ExchangeConfig object) - { - return object.getAlternateExchange(); - } - }; - - public static final ExchangeReadOnlyProperty<Map<String,Object>> ARGUMENTS = new ExchangeReadOnlyProperty<Map<String,Object>>("arguments") - { - public Map<String,Object> getValue(ExchangeConfig object) - { - return object.getArguments(); - } - }; - - private static final ExchangeConfigType INSTANCE = new ExchangeConfigType(); - - private ExchangeConfigType() - { - } - - public Collection<ExchangeProperty<?>> getProperties() - { - return Collections.unmodifiableList(EXCHANGE_PROPERTIES); - } - - public static ExchangeConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/IllegalConfigurationException.java index 8a9029fbfd..bedd470ddf 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfig.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/IllegalConfigurationException.java @@ -18,25 +18,20 @@ * under the License. * */ - package org.apache.qpid.server.configuration; -public interface SystemConfig extends ConfiguredObject<SystemConfigType,SystemConfig> +public class IllegalConfigurationException extends RuntimeException { - String getName(); - - String getOperatingSystemName(); - - String getNodeName(); - - - String getOSRelease(); - - String getOSVersion(); + private static final long serialVersionUID = 1130064756291179812L; - String getOSArchitecture(); + public IllegalConfigurationException(String message) + { + super(message); + } - void addBroker(BrokerConfig broker); + public IllegalConfigurationException(String message, Throwable cause) + { + super(message, cause); + } - void removeBroker(BrokerConfig broker); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java deleted file mode 100644 index 2c37a94db0..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * - * 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.configuration; - -public interface LinkConfig extends ConfiguredObject<LinkConfigType, LinkConfig> -{ - VirtualHostConfig getVirtualHost(); - - - String getTransport(); - - String getHost(); - - int getPort(); - - String getRemoteVhost(); - - String getAuthMechanism(); - - String getUsername(); - - String getPassword(); - - void close(); - - void createBridge(boolean durable, - boolean dynamic, - boolean srcIsQueue, - boolean srcIsLocal, - String src, - String dest, - String key, String tag, String excludes); - - String getState(); - - String getLastError(); -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java deleted file mode 100644 index 847cae87f5..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * - * 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.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public final class LinkConfigType extends ConfigObjectType<LinkConfigType, LinkConfig> -{ - private static final List<LinkProperty<?>> LINK_PROPERTIES = new ArrayList<LinkProperty<?>>(); - - public static interface LinkProperty<S> extends ConfigProperty<LinkConfigType, LinkConfig, S> - { - } - - private abstract static class LinkReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<LinkConfigType, LinkConfig, S> implements LinkProperty<S> - { - public LinkReadWriteProperty(String name) - { - super(name); - LINK_PROPERTIES.add(this); - } - } - - private abstract static class LinkReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<LinkConfigType, LinkConfig, S> implements LinkProperty<S> - { - public LinkReadOnlyProperty(String name) - { - super(name); - LINK_PROPERTIES.add(this); - } - } - - public static final LinkReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new LinkReadOnlyProperty<VirtualHostConfig>("virtualHost") - { - public VirtualHostConfig getValue(LinkConfig object) - { - return object.getVirtualHost(); - } - }; - - public static final LinkReadOnlyProperty<String> TRANSPORT_PROPERTY = new LinkReadOnlyProperty<String>("transport") - { - public String getValue(LinkConfig object) - { - return object.getTransport(); - } - }; - - public static final LinkReadOnlyProperty<String> HOST_PROPERTY = new LinkReadOnlyProperty<String>("host") - { - public String getValue(LinkConfig object) - { - return object.getHost(); - } - }; - - public static final LinkReadOnlyProperty<Integer> PORT_PROPERTY = new LinkReadOnlyProperty<Integer>("port") - { - public Integer getValue(LinkConfig object) - { - return object.getPort(); - } - }; - - public static final LinkReadOnlyProperty<String> REMOTE_VHOST_PROPERTY = new LinkReadOnlyProperty<String>("remoteVhost") - { - public String getValue(LinkConfig object) - { - return object.getRemoteVhost(); - } - }; - - public static final LinkReadOnlyProperty<String> AUTH_MECHANISM_PROPERTY = new LinkReadOnlyProperty<String>("authMechanism") - { - public String getValue(LinkConfig object) - { - return object.getAuthMechanism(); - } - }; - - public static final LinkReadOnlyProperty<String> USERNAME_PROPERTY = new LinkReadOnlyProperty<String>("username") - { - public String getValue(LinkConfig object) - { - return object.getUsername(); - } - }; - - public static final LinkReadOnlyProperty<String> PASSWORD_PROPERTY = new LinkReadOnlyProperty<String>("password") - { - public String getValue(LinkConfig object) - { - return object.getPassword(); - } - }; - - private static final LinkConfigType INSTANCE = new LinkConfigType(); - - private LinkConfigType() - { - } - - public Collection<LinkProperty<?>> getProperties() - { - return Collections.unmodifiableList(LINK_PROPERTIES); - } - - public static LinkConfigType getInstance() - { - return INSTANCE; - } - - - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java deleted file mode 100644 index 1ef5edeb51..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * 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.configuration; - -import org.apache.qpid.AMQException; - -import java.util.Map; - - -public interface QueueConfig extends ConfiguredObject<QueueConfigType, QueueConfig> -{ - VirtualHostConfig getVirtualHost(); - - String getName(); - - boolean isExclusive(); - - boolean isAutoDelete(); - - ExchangeConfig getAlternateExchange(); - - Map<String, Object> getArguments(); - - long getReceivedMessageCount(); - - int getMessageCount(); - - long getQueueDepth(); - - int getConsumerCount(); - - int getConsumerCountHigh(); - - int getBindingCount(); - - int getBindingCountHigh(); - - ConfigStore getConfigStore(); - - long getMessageDequeueCount(); - - long getTotalEnqueueSize(); - - long getTotalDequeueSize(); - - long getByteTxnEnqueues(); - - long getByteTxnDequeues(); - - long getMsgTxnEnqueues(); - - long getMsgTxnDequeues(); - - long getPersistentByteEnqueues(); - - long getPersistentByteDequeues(); - - long getPersistentMsgEnqueues(); - - long getPersistentMsgDequeues(); - - long getUnackedMessageCount(); - - long getUnackedMessageCountHigh(); - - void purge(long request) throws AMQException; -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java deleted file mode 100644 index f958ef5350..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * - * 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.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public final class QueueConfigType extends ConfigObjectType<QueueConfigType, QueueConfig> -{ - private static final List<QueueProperty<?>> QUEUE_PROPERTIES = new ArrayList<QueueProperty<?>>(); - - public static interface QueueProperty<S> extends ConfigProperty<QueueConfigType, QueueConfig, S> - { - } - - private abstract static class QueueReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<QueueConfigType, QueueConfig, S> implements QueueProperty<S> - { - public QueueReadWriteProperty(String name) - { - super(name); - QUEUE_PROPERTIES.add(this); - } - } - - private abstract static class QueueReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<QueueConfigType, QueueConfig, S> implements QueueProperty<S> - { - public QueueReadOnlyProperty(String name) - { - super(name); - QUEUE_PROPERTIES.add(this); - } - } - - public static final QueueReadOnlyProperty<VirtualHostConfig> VISTUAL_HOST_PROPERTY = new QueueReadOnlyProperty<VirtualHostConfig>("virtualHost") - { - public VirtualHostConfig getValue(QueueConfig object) - { - return object.getVirtualHost(); - } - }; - - public static final QueueReadOnlyProperty<String> NAME_PROPERTY = new QueueReadOnlyProperty<String>("name") - { - public String getValue(QueueConfig object) - { - return object.getName(); - } - }; - - public static final QueueReadOnlyProperty<Boolean> AUTODELETE_PROPERTY = new QueueReadOnlyProperty<Boolean>("autodelete") - { - public Boolean getValue(QueueConfig object) - { - return object.isAutoDelete(); - } - }; - - public static final QueueReadOnlyProperty<Boolean> EXCLUSIVE_PROPERTY = new QueueReadOnlyProperty<Boolean>("exclusive") - { - public Boolean getValue(QueueConfig object) - { - return object.isExclusive(); - } - }; - - public static final QueueReadOnlyProperty<ExchangeConfig> ALTERNATE_EXCHANGE_PROPERTY = new QueueReadOnlyProperty<ExchangeConfig>("alternateExchange") - { - public ExchangeConfig getValue(QueueConfig object) - { - return object.getAlternateExchange(); - } - }; - - public static final QueueReadOnlyProperty<Map<String,Object>> ARGUMENTS = new QueueReadOnlyProperty<Map<String,Object>>("arguments") - { - public Map<String,Object> getValue(QueueConfig object) - { - return object.getArguments(); - } - }; - - - private static final QueueConfigType INSTANCE = new QueueConfigType(); - - private QueueConfigType() - { - } - - public Collection<QueueProperty<?>> getProperties() - { - return Collections.unmodifiableList(QUEUE_PROPERTIES); - } - - public static QueueConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java index 8f03383777..06691d8659 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java @@ -24,11 +24,11 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.ConfigurationException; import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; +import org.apache.qpid.server.configuration.plugins.AbstractConfiguration; import java.util.List; -public class QueueConfiguration extends ConfigurationPlugin +public class QueueConfiguration extends AbstractConfiguration { private String _name; private VirtualHostConfiguration _vHostConfig; @@ -39,7 +39,7 @@ public class QueueConfiguration extends ConfigurationPlugin _name = name; CompositeConfiguration mungedConf = new CompositeConfiguration(); - mungedConf.addConfiguration(_vHostConfig.getConfig().subset("queues.queue." + name)); + mungedConf.addConfiguration(_vHostConfig.getConfig().subset("queues.queue." + escapeTagName(name))); mungedConf.addConfiguration(_vHostConfig.getConfig().subset("queues")); setConfiguration("virtualhosts.virtualhost.queues.queue", mungedConf); @@ -193,43 +193,4 @@ public class QueueConfiguration extends ConfigurationPlugin { return getBooleanValue("deadLetterQueues", _vHostConfig.isDeadLetterQueueEnabled()); } - - public static class QueueConfig extends ConfigurationPlugin - { - @Override - public String[] getElementsProcessed() - { - return new String[]{"name"}; - } - - public String getName() - { - return getStringValue("name"); - } - - - public void validateConfiguration() throws ConfigurationException - { - if (getConfig().isEmpty()) - { - throw new ConfigurationException("Queue section cannot be empty."); - } - - if (getName() == null) - { - throw new ConfigurationException("Queue section must have a 'name' element."); - } - - } - - - @Override - public String formatToString() - { - return "Name:"+getName(); - } - - - } - } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/RecovererProvider.java index b96ddc56c6..963d019ec3 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfig.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/RecovererProvider.java @@ -18,15 +18,11 @@ * under the License. * */ - package org.apache.qpid.server.configuration; -public interface VirtualHostConfig extends ConfiguredObject<VirtualHostConfigType, VirtualHostConfig> -{ - String getName(); - - BrokerConfig getBroker(); - - String getFederationTag(); +import org.apache.qpid.server.model.ConfiguredObject; +public interface RecovererProvider +{ + ConfiguredObjectRecoverer<? extends ConfiguredObject> getRecoverer(String type); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java deleted file mode 100644 index f9e2d93cff..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java +++ /dev/null @@ -1,1031 +0,0 @@ -/* - * 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.configuration; - -import java.io.File; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.TrustManagerFactory; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.ConfigurationFactory; -import org.apache.commons.configuration.HierarchicalConfiguration; -import org.apache.commons.configuration.SystemConfiguration; -import org.apache.commons.configuration.XMLConfiguration; -import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.exchange.DefaultExchangeFactory; -import org.apache.qpid.server.protocol.AmqpProtocolVersion; -import org.apache.qpid.server.queue.AMQQueueFactory; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.signal.SignalHandlerTask; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.virtualhost.VirtualHostRegistry; - -import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS; - -public class ServerConfiguration extends ConfigurationPlugin -{ - protected static final Logger _logger = Logger.getLogger(ServerConfiguration.class); - - // Default Configuration values - public static final int DEFAULT_BUFFER_SIZE = 262144; - public static final String DEFAULT_STATUS_UPDATES = "on"; - public static final String SECURITY_CONFIG_RELOADED = "SECURITY CONFIGURATION RELOADED"; - - public static final int DEFAULT_FRAME_SIZE = 65536; - public static final int DEFAULT_PORT = 5672; - public static final int DEFAULT_SSL_PORT = 5671; - public static final long DEFAULT_HOUSEKEEPING_PERIOD = 30000L; - public static final int DEFAULT_JMXPORT_REGISTRYSERVER = 8999; - public static final int JMXPORT_CONNECTORSERVER_OFFSET = 100; - public static final int DEFAULT_HTTP_MANAGEMENT_PORT = 8080; - public static final int DEFAULT_HTTPS_MANAGEMENT_PORT = 8443; - public static final long DEFAULT_MINIMUM_ALERT_REPEAT_GAP = 30000l; - - public static final String QPID_HOME = "QPID_HOME"; - public static final String QPID_WORK = "QPID_WORK"; - public static final String LIB_DIR = "lib"; - public static final String PLUGIN_DIR = "plugins"; - public static final String CACHE_DIR = "cache"; - - private Map<String, VirtualHostConfiguration> _virtualHosts = new HashMap<String, VirtualHostConfiguration>(); - - private File _configFile; - private File _vhostsFile; - private String _qpidWork; - private String _qpidHome; - - // Map of environment variables to config items - private static final Map<String, String> envVarMap = new HashMap<String, String>(); - - // Configuration values to be read from the configuration file - //todo Move all properties to static values to ensure system testing can be performed. - public static final String MGMT_CUSTOM_REGISTRY_SOCKET = "management.custom-registry-socket"; - public static final String MGMT_JMXPORT_REGISTRYSERVER = "management.jmxport.registryServer"; - public static final String MGMT_JMXPORT_CONNECTORSERVER = "management.jmxport.connectorServer"; - public static final String SECURITY_DEFAULT_AUTH_MANAGER = "security.default-auth-manager"; - public static final String SECURITY_PORT_MAPPINGS_PORT_MAPPING_AUTH_MANAGER = "security.port-mappings.port-mapping.auth-manager"; - public static final String SECURITY_PORT_MAPPINGS_PORT_MAPPING_PORT = "security.port-mappings.port-mapping.port"; - public static final String STATUS_UPDATES = "status-updates"; - public static final String ADVANCED_LOCALE = "advanced.locale"; - public static final String CONNECTOR_AMQP10ENABLED = "connector.amqp10enabled"; - public static final String CONNECTOR_AMQP010ENABLED = "connector.amqp010enabled"; - public static final String CONNECTOR_AMQP091ENABLED = "connector.amqp091enabled"; - public static final String CONNECTOR_AMQP09ENABLED = "connector.amqp09enabled"; - public static final String CONNECTOR_AMQP08ENABLED = "connector.amqp08enabled"; - public static final String CONNECTOR_AMQP_SUPPORTED_REPLY = "connector.amqpDefaultSupportedProtocolReply"; - public static final String CONNECTOR_INCLUDE_10 = "connector.include10"; - public static final String CONNECTOR_INCLUDE_010 = "connector.include010"; - public static final String CONNECTOR_INCLUDE_091 = "connector.include091"; - public static final String CONNECTOR_INCLUDE_09 = "connector.include09"; - public static final String CONNECTOR_INCLUDE_08 = "connector.include08"; - - { - envVarMap.put("QPID_PORT", "connector.port"); - envVarMap.put("QPID_SSLPORT", "connector.ssl.port"); - envVarMap.put("QPID_JMXPORT_REGISTRYSERVER", MGMT_JMXPORT_REGISTRYSERVER); - envVarMap.put("QPID_JMXPORT_CONNECTORSERVER", MGMT_JMXPORT_CONNECTORSERVER); - envVarMap.put("QPID_FRAMESIZE", "advanced.framesize"); - envVarMap.put("QPID_MSGAUTH", "security.msg-auth"); - envVarMap.put("QPID_AUTOREGISTER", "auto_register"); - envVarMap.put("QPID_MANAGEMENTENABLED", "management.enabled"); - envVarMap.put("QPID_HTTPMANAGEMENTENABLED", "management.http.enabled"); - envVarMap.put("QPID_HTTPMANAGEMENTPORT", "management.http.port"); - envVarMap.put("QPID_HEARTBEATDELAY", "heartbeat.delay"); - envVarMap.put("QPID_HEARTBEATTIMEOUTFACTOR", "heartbeat.timeoutFactor"); - envVarMap.put("QPID_MAXIMUMMESSAGEAGE", "maximumMessageAge"); - envVarMap.put("QPID_MAXIMUMMESSAGECOUNT", "maximumMessageCount"); - envVarMap.put("QPID_MAXIMUMQUEUEDEPTH", "maximumQueueDepth"); - envVarMap.put("QPID_MAXIMUMMESSAGESIZE", "maximumMessageSize"); - envVarMap.put("QPID_MAXIMUMCHANNELCOUNT", "maximumChannelCount"); - envVarMap.put("QPID_MINIMUMALERTREPEATGAP", "minimumAlertRepeatGap"); - envVarMap.put("QPID_QUEUECAPACITY", "capacity"); - envVarMap.put("QPID_FLOWRESUMECAPACITY", "flowResumeCapacity"); - envVarMap.put("QPID_SOCKETRECEIVEBUFFER", "connector.socketReceiveBuffer"); - envVarMap.put("QPID_SOCKETWRITEBUFFER", "connector.socketWriteBuffer"); - envVarMap.put("QPID_TCPNODELAY", "connector.tcpNoDelay"); - envVarMap.put("QPID_STATUS-UPDATES", "status-updates"); - } - - /** - * Loads the given file and sets up the HUP signal handler. - * - * This will load the file and present the root level properties but will - * not perform any virtualhost configuration. - * <p> - * To perform this {@link #initialise()} must be called. - * <p> - * This has been made a two step process to allow the Plugin Manager and - * Configuration Manager to be initialised in the Application Registry. - * <p> - * If using this ServerConfiguration via an ApplicationRegistry there is no - * need to explicitly call {@link #initialise()} as this is done via the - * {@link ApplicationRegistry#initialise()} method. - * - * @param configurationURL - * @throws org.apache.commons.configuration.ConfigurationException - */ - public ServerConfiguration(File configurationURL) throws ConfigurationException - { - this(parseConfig(configurationURL)); - _configFile = configurationURL; - - SignalHandlerTask hupReparseTask = new SignalHandlerTask() - { - public void handle() - { - try - { - reparseConfigFileSecuritySections(); - } - catch (ConfigurationException e) - { - _logger.error("Could not reload configuration file security sections", e); - } - } - }; - - if(!hupReparseTask.register("HUP")) - { - _logger.info("Unable to register Signal HUP handler to reload security configuration."); - _logger.info("Signal HUP not supported for this OS / JVM combination - " + SignalHandlerTask.getPlatformDescription()); - } - } - - /** - * Wraps the given Commons Configuration as a ServerConfiguration. - * - * Mainly used during testing and in locations where configuration is not - * desired but the interface requires configuration. - * <p> - * If the given configuration has VirtualHost configuration then - * {@link #initialise()} must be called to perform the required setup. - * <p> - * This has been made a two step process to allow the Plugin Manager and - * Configuration Manager to be initialised in the Application Registry. - * <p> - * If using this ServerConfiguration via an ApplicationRegistry there is no - * need to explicitly call {@link #initialise()} as this is done via the - * {@link ApplicationRegistry#initialise()} method. - * - * @param conf - */ - public ServerConfiguration(Configuration conf) - { - setConfig(conf); - } - - /** - * Processes this configuration and setups any VirtualHosts defined in the - * configuration. - * - * This has been separated from the constructor to allow the PluginManager - * time to be created and provide plugins to the ConfigurationManager for - * processing here. - * <p> - * Called by {@link ApplicationRegistry#initialise()}. - * <p> - * NOTE: A DEFAULT ApplicationRegistry must exist when using this method - * or a new ApplicationRegistry will be created. - * - * @throws ConfigurationException - */ - public void initialise() throws ConfigurationException - { - setConfiguration("", getConfig()); - setupVirtualHosts(getConfig()); - } - - public String[] getElementsProcessed() - { - return new String[] { "" }; - } - - @Override - public void validateConfiguration() throws ConfigurationException - { - // Support for security.jmx.access was removed when JMX access rights were incorporated into the main ACL. - // This ensure that users remove the element from their configuration file. - - if (getListValue("security.jmx.access").size() > 0) - { - String message = "Validation error : security/jmx/access is no longer a supported element within the configuration xml." - + (_configFile == null ? "" : " Configuration file : " + _configFile); - throw new ConfigurationException(message); - } - - if (getListValue("security.jmx.principal-database").size() > 0) - { - String message = "Validation error : security/jmx/principal-database is no longer a supported element within the configuration xml." - + (_configFile == null ? "" : " Configuration file : " + _configFile); - throw new ConfigurationException(message); - } - - if (getListValue("security.principal-databases.principal-database(0).class").size() > 0) - { - String message = "Validation error : security/principal-databases is no longer supported within the configuration xml." - + (_configFile == null ? "" : " Configuration file : " + _configFile); - throw new ConfigurationException(message); - } - - // QPID-3266. Tidy up housekeeping configuration option for scheduling frequency - if (contains("housekeeping.expiredMessageCheckPeriod")) - { - String message = "Validation error : housekeeping/expiredMessageCheckPeriod must be replaced by housekeeping/checkPeriod." - + (_configFile == null ? "" : " Configuration file : " + _configFile); - throw new ConfigurationException(message); - } - - String[] ports = getConfig().getStringArray(SECURITY_PORT_MAPPINGS_PORT_MAPPING_PORT); - String[] authManagers = getConfig().getStringArray(SECURITY_PORT_MAPPINGS_PORT_MAPPING_AUTH_MANAGER); - if (ports.length != authManagers.length) - { - throw new ConfigurationException("Validation error: Each port-mapping must have exactly one port and exactly one auth-manager."); - } - - // QPID-3517: Inconsistency in capitalisation in the SSL configuration keys used within the connector and management configuration - // sections. For the moment, continue to understand both but generate a deprecated warning if the less preferred keystore is used. - for (String key : new String[] {"management.ssl.keystorePath", - "management.ssl.keystorePassword," + - "connector.ssl.keystorePath", - "connector.ssl.keystorePassword"}) - { - if (contains(key)) - { - final String deprecatedXpath = key.replaceAll("\\.", "/"); - final String preferredXpath = deprecatedXpath.replaceAll("keystore", "keyStore"); - _logger.warn("Validation warning: " + deprecatedXpath + " is deprecated and must be replaced by " + preferredXpath - + (_configFile == null ? "" : " Configuration file : " + _configFile)); - } - } - - // QPID-3739 certType was a misleading name. - if (contains("connector.ssl.certType")) - { - _logger.warn("Validation warning: connector/ssl/certType is deprecated and must be replaced by connector/ssl/keyManagerFactoryAlgorithm" - + (_configFile == null ? "" : " Configuration file : " + _configFile)); - } - } - - /* - * Modified to enforce virtualhosts configuration in external file or main file, but not - * both, as a fix for QPID-2360 and QPID-2361. - */ - @SuppressWarnings("unchecked") - protected void setupVirtualHosts(Configuration conf) throws ConfigurationException - { - List<String> vhostFiles = (List) conf.getList("virtualhosts"); - Configuration vhostConfig = conf.subset("virtualhosts"); - - // Only one configuration mechanism allowed - if (!vhostFiles.isEmpty() && !vhostConfig.subset("virtualhost").isEmpty()) - { - throw new ConfigurationException("Only one of external or embedded virtualhosts configuration allowed."); - } - - // We can only have one vhosts XML file included - if (vhostFiles.size() > 1) - { - throw new ConfigurationException("Only one external virtualhosts configuration file allowed, multiple filenames found."); - } - - // Virtualhost configuration object - Configuration vhostConfiguration = new HierarchicalConfiguration(); - - // Load from embedded configuration if possible - if (!vhostConfig.subset("virtualhost").isEmpty()) - { - vhostConfiguration = vhostConfig; - } - else - { - // Load from the external configuration if possible - for (String fileName : vhostFiles) - { - // Open the vhosts XML file and copy values from it to our config - _vhostsFile = new File(fileName); - if (!_vhostsFile.exists()) - { - throw new ConfigurationException("Virtualhosts file does not exist"); - } - vhostConfiguration = parseConfig(new File(fileName)); - - // save the default virtualhost name - String defaultVirtualHost = vhostConfiguration.getString("default"); - getConfig().setProperty("virtualhosts.default", defaultVirtualHost); - } - } - - // Now extract the virtual host names from the configuration object - List hosts = vhostConfiguration.getList("virtualhost.name"); - for (int j = 0; j < hosts.size(); j++) - { - String name = (String) hosts.get(j); - - // Add the virtual hosts to the server configuration - VirtualHostConfiguration virtualhost = new VirtualHostConfiguration(name, vhostConfiguration.subset("virtualhost." + name)); - _virtualHosts.put(virtualhost.getName(), virtualhost); - } - } - - private static void substituteEnvironmentVariables(Configuration conf) - { - for (Entry<String, String> var : envVarMap.entrySet()) - { - String val = System.getenv(var.getKey()); - if (val != null) - { - conf.setProperty(var.getValue(), val); - } - } - } - - private static Configuration parseConfig(File file) throws ConfigurationException - { - ConfigurationFactory factory = new ConfigurationFactory(); - factory.setConfigurationFileName(file.getAbsolutePath()); - Configuration conf = factory.getConfiguration(); - - Iterator<?> keys = conf.getKeys(); - if (!keys.hasNext()) - { - keys = null; - conf = flatConfig(file); - } - - substituteEnvironmentVariables(conf); - - return conf; - } - - /** - * Check the configuration file to see if status updates are enabled. - * - * @return true if status updates are enabled - */ - public boolean getStatusUpdatesEnabled() - { - // Retrieve the setting from configuration but default to on. - String value = getStringValue(STATUS_UPDATES, DEFAULT_STATUS_UPDATES); - - return value.equalsIgnoreCase("on"); - } - - /** - * The currently defined {@see Locale} for this broker - * - * @return the configuration defined locale - */ - public Locale getLocale() - { - String localeString = getStringValue(ADVANCED_LOCALE); - // Expecting locale of format langauge_country_variant - - // If the configuration does not have a defined locale use the JVM default - if (localeString == null) - { - return Locale.getDefault(); - } - - String[] parts = localeString.split("_"); - - Locale locale; - switch (parts.length) - { - case 1: - locale = new Locale(localeString); - break; - case 2: - locale = new Locale(parts[0], parts[1]); - break; - default: - StringBuilder variant = new StringBuilder(parts[2]); - // If we have a variant such as the Java doc suggests for Spanish - // Traditional_WIN we may end up with more than 3 parts on a - // split with '_'. So we should recombine the variant. - if (parts.length > 3) - { - for (int index = 3; index < parts.length; index++) - { - variant.append('_').append(parts[index]); - } - } - - locale = new Locale(parts[0], parts[1], variant.toString()); - } - - return locale; - } - - // Our configuration class needs to make the interpolate method - // public so it can be called below from the config method. - public static class MyConfiguration extends CompositeConfiguration - { - public String interpolate(String obj) - { - return super.interpolate(obj); - } - } - - public final static Configuration flatConfig(File file) throws ConfigurationException - { - // We have to override the interpolate methods so that - // interpolation takes place across the entirety of the - // composite configuration. Without doing this each - // configuration object only interpolates variables defined - // inside itself. - final MyConfiguration conf = new MyConfiguration(); - conf.addConfiguration(new SystemConfiguration() - { - protected String interpolate(String o) - { - return conf.interpolate(o); - } - }); - conf.addConfiguration(new XMLConfiguration(file) - { - protected String interpolate(String o) - { - return conf.interpolate(o); - } - }); - return conf; - } - - public String getConfigurationURL() - { - return _configFile == null ? "" : _configFile.getAbsolutePath(); - } - - public void reparseConfigFileSecuritySections() throws ConfigurationException - { - if (_configFile != null) - { - Configuration newConfig = parseConfig(_configFile); - setConfiguration("", newConfig); - ApplicationRegistry.getInstance().getSecurityManager().configureHostPlugins(this); - - // Reload virtualhosts from correct location - Configuration newVhosts; - if (_vhostsFile == null) - { - newVhosts = newConfig.subset("virtualhosts"); - } - else - { - newVhosts = parseConfig(_vhostsFile); - } - - VirtualHostRegistry vhostRegistry = ApplicationRegistry.getInstance().getVirtualHostRegistry(); - for (String hostName : _virtualHosts.keySet()) - { - VirtualHost vhost = vhostRegistry.getVirtualHost(hostName); - Configuration vhostConfig = newVhosts.subset("virtualhost." + hostName); - vhost.getConfiguration().setConfiguration("virtualhosts.virtualhost", vhostConfig); - vhost.getSecurityManager().configureGlobalPlugins(this); - vhost.getSecurityManager().configureHostPlugins(vhost.getConfiguration()); - } - - _logger.warn(SECURITY_CONFIG_RELOADED); - } - } - - public String getQpidWork() - { - if ( _qpidWork == null ) - { - return System.getProperty(QPID_WORK, System.getProperty("java.io.tmpdir")); - } - else - { - return _qpidWork; - } - } - - public String getQpidHome() - { - if ( _qpidHome == null ) - { - return System.getProperty(QPID_HOME); - } - else - { - return _qpidHome; - } - } - - public void setJMXPortRegistryServer(int registryServerPort) - { - getConfig().setProperty(MGMT_JMXPORT_REGISTRYSERVER, registryServerPort); - } - - public int getJMXPortRegistryServer() - { - return getIntValue(MGMT_JMXPORT_REGISTRYSERVER, DEFAULT_JMXPORT_REGISTRYSERVER); - } - - public void setJMXPortConnectorServer(int connectorServerPort) - { - getConfig().setProperty(MGMT_JMXPORT_CONNECTORSERVER, connectorServerPort); - } - - public int getJMXConnectorServerPort() - { - return getIntValue(MGMT_JMXPORT_CONNECTORSERVER, getJMXPortRegistryServer() + JMXPORT_CONNECTORSERVER_OFFSET); - } - - public boolean getUseCustomRMISocketFactory() - { - return getBooleanValue(MGMT_CUSTOM_REGISTRY_SOCKET, true); - } - - public void setUseCustomRMISocketFactory(boolean bool) - { - getConfig().setProperty(MGMT_CUSTOM_REGISTRY_SOCKET, bool); - } - - public boolean getPlatformMbeanserver() - { - return getBooleanValue("management.platform-mbeanserver", true); - } - - public boolean getHTTPManagementEnabled() - { - return getBooleanValue("management.http.enabled", true); - } - - public int getHTTPManagementPort() - { - return getIntValue("management.http.port", DEFAULT_HTTP_MANAGEMENT_PORT); - } - - public boolean getHTTPSManagementEnabled() - { - return getBooleanValue("management.https.enabled", false); - } - - public int getHTTPSManagementPort() - { - return getIntValue("management.https.port", DEFAULT_HTTPS_MANAGEMENT_PORT); - } - - public String[] getVirtualHosts() - { - return _virtualHosts.keySet().toArray(new String[_virtualHosts.size()]); - } - - public String getPluginDirectory() - { - return getStringValue("plugin-directory"); - } - - public String getCacheDirectory() - { - return getStringValue("cache-directory"); - } - - public VirtualHostConfiguration getVirtualHostConfig(String name) - { - return _virtualHosts.get(name); - } - - public void setVirtualHostConfig(VirtualHostConfiguration config) - { - _virtualHosts.put(config.getName(), config); - } - - public int getFrameSize() - { - return getIntValue("advanced.framesize", DEFAULT_FRAME_SIZE); - } - - public boolean getSynchedClocks() - { - return getBooleanValue("advanced.synced-clocks"); - } - - public boolean getMsgAuth() - { - return getBooleanValue("security.msg-auth"); - } - - public String getDefaultAuthenticationManager() - { - return getStringValue(SECURITY_DEFAULT_AUTH_MANAGER); - } - - public Map<Integer, String> getPortAuthenticationMappings() - { - String[] ports = getConfig().getStringArray(SECURITY_PORT_MAPPINGS_PORT_MAPPING_PORT); - String[] authManagers = getConfig().getStringArray(SECURITY_PORT_MAPPINGS_PORT_MAPPING_AUTH_MANAGER); - - Map<Integer,String> portMappings = new HashMap<Integer, String>(); - for(int i = 0; i < ports.length; i++) - { - portMappings.put(Integer.valueOf(ports[i]), authManagers[i]); - } - - return portMappings; - } - - - public String getManagementKeyStorePath() - { - final String fallback = getStringValue("management.ssl.keystorePath"); - return getStringValue("management.ssl.keyStorePath", fallback); - } - - public boolean getManagementSSLEnabled() - { - return getBooleanValue("management.ssl.enabled", false); - } - - public String getManagementKeyStorePassword() - { - final String fallback = getStringValue("management.ssl.keystorePassword"); - return getStringValue("management.ssl.keyStorePassword", fallback); - } - - public boolean getQueueAutoRegister() - { - return getBooleanValue("queue.auto_register", true); - } - - public boolean getJMXManagementEnabled() - { - return getBooleanValue("management.enabled", true); - } - - public int getHeartBeatDelay() - { - return getIntValue("heartbeat.delay", 5); - } - - public double getHeartBeatTimeout() - { - return getDoubleValue("heartbeat.timeoutFactor", 2.0); - } - - public long getMaximumMessageAge() - { - return getLongValue("maximumMessageAge"); - } - - public long getMaximumMessageCount() - { - return getLongValue("maximumMessageCount"); - } - - public long getMaximumQueueDepth() - { - return getLongValue("maximumQueueDepth"); - } - - public long getMaximumMessageSize() - { - return getLongValue("maximumMessageSize"); - } - - public long getMinimumAlertRepeatGap() - { - return getLongValue("minimumAlertRepeatGap", DEFAULT_MINIMUM_ALERT_REPEAT_GAP); - } - - public long getCapacity() - { - return getLongValue("capacity"); - } - - public long getFlowResumeCapacity() - { - return getLongValue("flowResumeCapacity", getCapacity()); - } - - public int getConnectorProcessors() - { - return getIntValue("connector.processors", 4); - } - - public List getPorts() - { - return getListValue("connector.port", Collections.<Integer>singletonList(DEFAULT_PORT)); - } - - public List getPortExclude10() - { - return getListValue("connector.non10port"); - } - - public List getPortExclude010() - { - return getListValue("connector.non010port"); - } - - public List getPortExclude091() - { - return getListValue("connector.non091port"); - } - - public List getPortExclude09() - { - return getListValue("connector.non09port"); - } - - public List getPortExclude08() - { - return getListValue("connector.non08port"); - } - - public List getPortInclude08() - { - return getListValue(CONNECTOR_INCLUDE_08); - } - - public List getPortInclude09() - { - return getListValue(CONNECTOR_INCLUDE_09); - } - - public List getPortInclude091() - { - return getListValue(CONNECTOR_INCLUDE_091); - } - - public List getPortInclude010() - { - return getListValue(CONNECTOR_INCLUDE_010); - } - - public List getPortInclude10() - { - return getListValue(CONNECTOR_INCLUDE_10); - } - - public String getBind() - { - return getStringValue("connector.bind", WILDCARD_ADDRESS); - } - - public int getReceiveBufferSize() - { - return getIntValue("connector.socketReceiveBuffer", DEFAULT_BUFFER_SIZE); - } - - public int getWriteBufferSize() - { - return getIntValue("connector.socketWriteBuffer", DEFAULT_BUFFER_SIZE); - } - - public boolean getTcpNoDelay() - { - return getBooleanValue("connector.tcpNoDelay", true); - } - - public boolean getEnableSSL() - { - return getBooleanValue("connector.ssl.enabled"); - } - - public boolean getSSLOnly() - { - return getBooleanValue("connector.ssl.sslOnly"); - } - - public List getSSLPorts() - { - return getListValue("connector.ssl.port", Collections.<Integer>singletonList(DEFAULT_SSL_PORT)); - } - - public String getConnectorKeyStorePath() - { - final String fallback = getStringValue("connector.ssl.keystorePath"); // pre-0.13 broker supported this name. - return getStringValue("connector.ssl.keyStorePath", fallback); - } - - public String getConnectorKeyStorePassword() - { - final String fallback = getStringValue("connector.ssl.keystorePassword"); // pre-0.13 brokers supported this name. - return getStringValue("connector.ssl.keyStorePassword", fallback); - } - - public String getConnectorKeyStoreType() - { - return getStringValue("connector.ssl.keyStoreType", "JKS"); - } - - public String getConnectorKeyManagerFactoryAlgorithm() - { - final String systemFallback = KeyManagerFactory.getDefaultAlgorithm(); - // deprecated, pre-0.17 brokers supported this name. - final String fallback = getStringValue("connector.ssl.certType", systemFallback); - return getStringValue("connector.ssl.keyManagerFactoryAlgorithm", fallback); - } - - public String getConnectorTrustStorePath() - { - return getStringValue("connector.ssl.trustStorePath", null); - } - - public String getConnectorTrustStorePassword() - { - return getStringValue("connector.ssl.trustStorePassword", null); - } - - public String getConnectorTrustStoreType() - { - return getStringValue("connector.ssl.trustStoreType", "JKS"); - } - - public String getConnectorTrustManagerFactoryAlgorithm() - { - return getStringValue("connector.ssl.trustManagerFactoryAlgorithm", TrustManagerFactory.getDefaultAlgorithm()); - } - - public String getCertAlias() - { - return getStringValue("connector.ssl.certAlias", null); - } - - public boolean needClientAuth() - { - return getConfig().getBoolean("connector.ssl.needClientAuth", false); - } - - public boolean wantClientAuth() - { - return getConfig().getBoolean("connector.ssl.wantClientAuth", false); - } - - public String getDefaultVirtualHost() - { - return getStringValue("virtualhosts.default"); - } - - public void setDefaultVirtualHost(String vhost) - { - getConfig().setProperty("virtualhosts.default", vhost); - } - - public void setHousekeepingCheckPeriod(long value) - { - getConfig().setProperty("housekeeping.checkPeriod", value); - } - - public long getHousekeepingCheckPeriod() - { - return getLongValue("housekeeping.checkPeriod", DEFAULT_HOUSEKEEPING_PERIOD); - } - - public long getStatisticsSamplePeriod() - { - return getConfig().getLong("statistics.sample.period", 5000L); - } - - public boolean isStatisticsGenerationBrokerEnabled() - { - return getConfig().getBoolean("statistics.generation.broker", false); - } - - public boolean isStatisticsGenerationVirtualhostsEnabled() - { - return getConfig().getBoolean("statistics.generation.virtualhosts", false); - } - - public boolean isStatisticsGenerationConnectionsEnabled() - { - return getConfig().getBoolean("statistics.generation.connections", false); - } - - public long getStatisticsReportingPeriod() - { - return getConfig().getLong("statistics.reporting.period", 0L); - } - - public boolean isStatisticsReportResetEnabled() - { - return getConfig().getBoolean("statistics.reporting.reset", false); - } - - public int getMaxChannelCount() - { - return getIntValue("maximumChannelCount", 256); - } - - /** - * List of Broker features that have been disabled within configuration. Disabled - * features won't be advertised to the clients on connection. - * - * @return list of disabled features, or empty list if no features are disabled. - */ - public List<String> getDisabledFeatures() - { - final List<String> disabledFeatures = getListValue("disabledFeatures", Collections.emptyList()); - return disabledFeatures; - } - - public boolean getManagementRightsInferAllAccess() - { - return getBooleanValue("management.managementRightsInferAllAccess", true); - } - - public int getMaxDeliveryCount() - { - return getConfig().getInt("maximumDeliveryCount", 0); - } - - /** - * Check if dead letter queue delivery is enabled, defaults to disabled if not set. - */ - public boolean isDeadLetterQueueEnabled() - { - return getConfig().getBoolean("deadLetterQueues", false); - } - - /** - * String to affix to end of queue name when generating an alternate exchange for DLQ purposes. - */ - public String getDeadLetterExchangeSuffix() - { - return getConfig().getString("deadLetterExchangeSuffix", DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX); - } - - /** - * String to affix to end of queue name when generating a queue for DLQ purposes. - */ - public String getDeadLetterQueueSuffix() - { - return getConfig().getString("deadLetterQueueSuffix", AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX); - } - - public boolean isAmqp10enabled() - { - return getConfig().getBoolean(CONNECTOR_AMQP10ENABLED, true); - } - - public boolean isAmqp010enabled() - { - return getConfig().getBoolean(CONNECTOR_AMQP010ENABLED, true); - } - - public boolean isAmqp091enabled() - { - return getConfig().getBoolean(CONNECTOR_AMQP091ENABLED, true); - } - - public boolean isAmqp09enabled() - { - return getConfig().getBoolean(CONNECTOR_AMQP09ENABLED, true); - } - - public boolean isAmqp08enabled() - { - return getConfig().getBoolean(CONNECTOR_AMQP08ENABLED, true); - } - - /** - * Returns the configured default reply to an unsupported AMQP protocol initiation, or null if there is none - */ - public AmqpProtocolVersion getDefaultSupportedProtocolReply() - { - String reply = getConfig().getString(CONNECTOR_AMQP_SUPPORTED_REPLY, null); - - return reply == null ? null : AmqpProtocolVersion.valueOf(reply); - } - - public void setQpidWork(String path) - { - _qpidWork = path; - } - - public void setQpidHome(String path) - { - _qpidHome = path; - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java deleted file mode 100644 index 51dcc38c47..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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.configuration; - -import java.net.InetSocketAddress; -import org.apache.qpid.transport.NetworkTransportConfiguration; - -public class ServerNetworkTransportConfiguration implements NetworkTransportConfiguration -{ - private final ServerConfiguration _serverConfig; - private final String _transport; - private InetSocketAddress _address; - - public ServerNetworkTransportConfiguration(final ServerConfiguration serverConfig, - final InetSocketAddress address, - final String transport) - { - _serverConfig = serverConfig; - _address = address; - _transport = transport; - } - - public Boolean getTcpNoDelay() - { - return _serverConfig.getTcpNoDelay(); - } - - public Integer getSendBufferSize() - { - return _serverConfig.getWriteBufferSize(); - } - - public Integer getReceiveBufferSize() - { - return _serverConfig.getReceiveBufferSize(); - } - - public Integer getPort() - { - return _address.getPort(); - } - - public String getHost() - { - return _address.getHostName(); - } - - public String getTransport() - { - return _transport; - } - - public Integer getConnectorProcessors() - { - return _serverConfig.getConnectorProcessors(); - } - - public InetSocketAddress getAddress() - { - return _address; - } - - public boolean needClientAuth() - { - return _serverConfig.needClientAuth(); - } - - @Override - public boolean wantClientAuth() - { - return _serverConfig.wantClientAuth(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfig.java deleted file mode 100644 index 8fef642eff..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfig.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * 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.configuration; - -import org.apache.qpid.AMQException; - -public interface SessionConfig extends ConfiguredObject<SessionConfigType, SessionConfig> -{ - VirtualHostConfig getVirtualHost(); - - String getSessionName(); - - int getChannel(); - - ConnectionConfig getConnectionConfig(); - - boolean isAttached(); - - long getDetachedLifespan(); - - Long getExpiryTime(); - - Long getMaxClientRate(); - - Long getTxnStarts(); - - Long getTxnCommits(); - - Long getTxnRejects(); - - Long getTxnCount(); - - boolean isTransactional(); - - void mgmtClose() throws AMQException; -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java deleted file mode 100644 index 1685cfab60..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * - * 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.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public final class SessionConfigType extends ConfigObjectType<SessionConfigType, SessionConfig> -{ - private static final List<SessionProperty<?>> SESSION_PROPERTIES = new ArrayList<SessionProperty<?>>(); - - public static interface SessionProperty<S> extends ConfigProperty<SessionConfigType, SessionConfig, S> - { - } - - private abstract static class SessionReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<SessionConfigType, SessionConfig, S> implements SessionProperty<S> - { - public SessionReadWriteProperty(String name) - { - super(name); - SESSION_PROPERTIES.add(this); - } - } - - private abstract static class SessionReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<SessionConfigType, SessionConfig, S> implements SessionProperty<S> - { - public SessionReadOnlyProperty(String name) - { - super(name); - SESSION_PROPERTIES.add(this); - } - } - - public static final SessionReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new SessionReadOnlyProperty<VirtualHostConfig>("virtualHost") - { - public VirtualHostConfig getValue(SessionConfig object) - { - return object.getVirtualHost(); - } - }; - - public static final SessionReadOnlyProperty<String> NAME_PROPERTY = new SessionReadOnlyProperty<String>("name") - { - public String getValue(SessionConfig object) - { - return object.getSessionName(); - } - }; - - public static final SessionReadOnlyProperty<Integer> CHANNEL_ID_PROPERTY = new SessionReadOnlyProperty<Integer>("channelId") - { - public Integer getValue(SessionConfig object) - { - return object.getChannel(); - } - }; - - public static final SessionReadOnlyProperty<ConnectionConfig> CONNECTION_PROPERTY = new SessionReadOnlyProperty<ConnectionConfig>("connection") - { - public ConnectionConfig getValue(SessionConfig object) - { - return object.getConnectionConfig(); - } - }; - - public static final SessionReadOnlyProperty<Boolean> ATTACHED_PROPERTY = new SessionReadOnlyProperty<Boolean>("attached") - { - public Boolean getValue(SessionConfig object) - { - return object.isAttached(); - } - }; - - public static final SessionReadOnlyProperty<Long> DETACHED_LIFESPAN_PROPERTY = new SessionReadOnlyProperty<Long>("detachedLifespan") - { - public Long getValue(SessionConfig object) - { - return object.getDetachedLifespan(); - } - }; - - public static final SessionReadOnlyProperty<Long> EXPIRE_TIME_PROPERTY = new SessionReadOnlyProperty<Long>("expireTime") - { - public Long getValue(SessionConfig object) - { - return object.getExpiryTime(); - } - }; - - public static final SessionReadOnlyProperty<Long> MAX_CLIENT_RATE_PROPERTY = new SessionReadOnlyProperty<Long>("maxClientRate") - { - public Long getValue(SessionConfig object) - { - return object.getMaxClientRate(); - } - }; - - private static final SessionConfigType INSTANCE = new SessionConfigType(); - - private SessionConfigType() - { - } - - public Collection<SessionProperty<?>> getProperties() - { - return Collections.unmodifiableList(SESSION_PROPERTIES); - } - - public static SessionConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java deleted file mode 100644 index 7b7848dd87..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * - * 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.configuration; - - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public final class SubscriptionConfigType extends ConfigObjectType<SubscriptionConfigType, SubscriptionConfig> -{ - private static final List<SubscriptionProperty<?>> SUBSCRIPTION_PROPERTIES = new ArrayList<SubscriptionProperty<?>>(); - - public static interface SubscriptionProperty<S> extends ConfigProperty<SubscriptionConfigType, SubscriptionConfig, S> - { - } - - private abstract static class SubscriptionReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<SubscriptionConfigType, SubscriptionConfig, S> implements SubscriptionProperty<S> - { - public SubscriptionReadWriteProperty(String name) - { - super(name); - SUBSCRIPTION_PROPERTIES.add(this); - } - } - - private abstract static class SubscriptionReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<SubscriptionConfigType, SubscriptionConfig, S> implements SubscriptionProperty<S> - { - public SubscriptionReadOnlyProperty(String name) - { - super(name); - SUBSCRIPTION_PROPERTIES.add(this); - } - } - - public static final SubscriptionReadOnlyProperty<SessionConfig> SESSION_PROPERTY = new SubscriptionReadOnlyProperty<SessionConfig>("session") - { - public SessionConfig getValue(SubscriptionConfig object) - { - return object.getSessionConfig(); - } - }; - - public static final SubscriptionReadOnlyProperty<QueueConfig> QUEUE_PROPERTY = new SubscriptionReadOnlyProperty<QueueConfig>("queue") - { - public QueueConfig getValue(SubscriptionConfig object) - { - return object.getQueue(); - } - }; - - public static final SubscriptionReadOnlyProperty<String> NAME_PROPERTY = new SubscriptionReadOnlyProperty<String>("name") - { - public String getValue(SubscriptionConfig object) - { - return object.getName(); - } - }; - - public static final SubscriptionReadOnlyProperty<Map<String,Object>> ARGUMENTS = new SubscriptionReadOnlyProperty<Map<String,Object>>("arguments") - { - public Map<String,Object> getValue(SubscriptionConfig object) - { - return object.getArguments(); - } - }; - - public static final SubscriptionReadOnlyProperty<String> CREDIT_MODE_PROPERTY = new SubscriptionReadOnlyProperty<String>("creditMode") - { - public String getValue(SubscriptionConfig object) - { - return object.getCreditMode(); - } - }; - - public static final SubscriptionReadOnlyProperty<Boolean> BROWSING_PROPERTY = new SubscriptionReadOnlyProperty<Boolean>("browsing") - { - public Boolean getValue(SubscriptionConfig object) - { - return object.isBrowsing(); - } - }; - - public static final SubscriptionReadOnlyProperty<Boolean> EXCLUSIVE_PROPERTY = new SubscriptionReadOnlyProperty<Boolean>("exclusive") - { - public Boolean getValue(SubscriptionConfig object) - { - return object.isExclusive(); - } - }; - - public static final SubscriptionReadOnlyProperty<Boolean> EXPLICIT_ACK_PROPERTY = new SubscriptionReadOnlyProperty<Boolean>("explicitAck") - { - public Boolean getValue(SubscriptionConfig object) - { - return object.isExplicitAcknowledge(); - } - }; - - private static final SubscriptionConfigType INSTANCE = new SubscriptionConfigType(); - - private SubscriptionConfigType() - { - } - - public Collection<SubscriptionProperty<?>> getProperties() - { - return Collections.unmodifiableList(SUBSCRIPTION_PROPERTIES); - } - - - public static SubscriptionConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java deleted file mode 100644 index 80c2e8b2f1..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * - * 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.configuration; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - -public class SystemConfigImpl implements SystemConfig -{ - private static final String OS_NAME = System.getProperty("os.name"); - private static final String OS_ARCH = System.getProperty("os.arch"); - private static final String OS_VERSION = System.getProperty("os.version"); - - private final UUID _qmfId; - private String _name; - - private final String _host; - - private final Map<UUID, BrokerConfig> _brokers = new ConcurrentHashMap<UUID, BrokerConfig>(); - - private final long _createTime = System.currentTimeMillis(); - private final ConfigStore _store; - - public SystemConfigImpl(ConfigStore store) - { - this(store.createId(), store); - } - - public SystemConfigImpl(UUID qmfId, ConfigStore store) - { - _qmfId = qmfId; - _store = store; - String host; - try - { - InetAddress addr = InetAddress.getLocalHost(); - host = addr.getHostName(); - } - catch (UnknownHostException e) - { - host="localhost"; - } - _host = host; - } - - public String getName() - { - return _name; - } - - public String getOperatingSystemName() - { - return OS_NAME; - } - - public String getNodeName() - { - return _host; - } - - public String getOSRelease() - { - return OS_VERSION; - } - - public String getOSVersion() - { - return ""; - } - - public String getOSArchitecture() - { - return OS_ARCH; - } - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public SystemConfigType getConfigType() - { - return SystemConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return null; - } - - public boolean isDurable() - { - return false; - } - - public void addBroker(final BrokerConfig broker) - { - broker.setSystem(this); - _store.addConfiguredObject(broker); - _brokers.put(broker.getQMFId(), broker); - } - - public void removeBroker(final BrokerConfig broker) - { - _brokers.remove(broker.getQMFId()); - _store.removeConfiguredObject(broker); - } - - public long getCreateTime() - { - return _createTime; - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java deleted file mode 100644 index 4a383cce7a..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * - * 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.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.UUID; - -public final class SystemConfigType extends ConfigObjectType<SystemConfigType, SystemConfig> -{ - private static final List<SystemProperty<?>> SYSTEM_PROPERTIES = new ArrayList<SystemProperty<?>>(); - - public static interface SystemProperty<S> extends ConfigProperty<SystemConfigType, SystemConfig, S> - { - } - - private abstract static class SystemReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<SystemConfigType, SystemConfig, S> implements SystemProperty<S> - { - public SystemReadWriteProperty(String name) - { - super(name); - SYSTEM_PROPERTIES.add(this); - } - } - - private abstract static class SystemReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<SystemConfigType, SystemConfig, S> implements SystemProperty<S> - { - public SystemReadOnlyProperty(String name) - { - super(name); - SYSTEM_PROPERTIES.add(this); - } - } - - public static final SystemReadOnlyProperty<String> NAME_PROPERTY = new SystemReadOnlyProperty<String>("name") - { - public String getValue(SystemConfig object) - { - return object.getName(); - } - }; - - public static final SystemReadOnlyProperty<UUID> ID_PROPERTY = new SystemReadOnlyProperty<UUID>("id") - { - public UUID getValue(SystemConfig object) - { - return object.getQMFId(); - } - }; - - public static final SystemReadOnlyProperty<String> OS_NAME_PROPERTY = new SystemReadOnlyProperty<String>("osName") - { - public String getValue(SystemConfig object) - { - return object.getOperatingSystemName(); - } - }; - - public static final SystemReadOnlyProperty<String> NODE_NAME_PROPERTY = new SystemReadOnlyProperty<String>("nodeName") - { - public String getValue(SystemConfig object) - { - return object.getNodeName(); - } - }; - - public static final SystemReadOnlyProperty<String> RELEASE_PROPERTY = new SystemReadOnlyProperty<String>("release") - { - public String getValue(SystemConfig object) - { - return object.getOSRelease(); - } - }; - - public static final SystemReadOnlyProperty<String> VERSION_PROPERTY = new SystemReadOnlyProperty<String>("version") - { - public String getValue(SystemConfig object) - { - return object.getOSVersion(); - } - }; - - public static final SystemReadOnlyProperty<String> MACHINE_PROPERTY = new SystemReadOnlyProperty<String>("machine") - { - public String getValue(SystemConfig object) - { - return object.getOSArchitecture(); - } - }; - - private static final SystemConfigType INSTANCE = new SystemConfigType(); - - private SystemConfigType() - { - } - - public Collection<SystemProperty<?>> getProperties() - { - return Collections.unmodifiableList(SYSTEM_PROPERTIES); - } - - - - public static SystemConfigType getInstance() - { - return INSTANCE; - } - - - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java deleted file mode 100644 index aaa1766489..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * - * 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.configuration; - -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.PropertiesConfiguration; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; - -public class TopicConfig extends ConfigurationPlugin -{ - public TopicConfig() - { - setConfig(new PropertiesConfiguration()); - } - - @Override - public String[] getElementsProcessed() - { - return new String[]{"name", "subscriptionName"}; - } - - public String getName() - { - // If we don't have a specific topic then this config is for all topics. - return getStringValue("name", "#"); - } - - public String getSubscriptionName() - { - return getStringValue("subscriptionName"); - } - - public void validateConfiguration() throws ConfigurationException - { - if (getConfig().isEmpty()) - { - throw new ConfigurationException("Topic section cannot be empty."); - } - - if (getStringValue("name") == null && getSubscriptionName() == null) - { - throw new ConfigurationException("Topic section must have a 'name' or 'subscriptionName' element."); - } - - } - - - @Override - public String formatToString() - { - String response = "Topic:"+getName(); - if (getSubscriptionName() != null) - { - response += ", SubscriptionName:"+getSubscriptionName(); - } - - return response; - } -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfiguration.java deleted file mode 100644 index feafd3de1d..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfiguration.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * - * 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.configuration; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; -import org.apache.qpid.server.exchange.TopicExchange; -import org.apache.qpid.server.queue.AMQQueue; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -public class TopicConfiguration extends ConfigurationPlugin implements ExchangeConfigurationPlugin -{ - public static final ConfigurationPluginFactory FACTORY = new TopicConfigurationFactory(); - - private static final String VIRTUALHOSTS_VIRTUALHOST_TOPICS = "virtualhosts.virtualhost.topics"; - - public static class TopicConfigurationFactory implements ConfigurationPluginFactory - { - - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException - { - TopicConfiguration topicsConfig = new TopicConfiguration(); - topicsConfig.setConfiguration(path, config); - return topicsConfig; - } - - public List<String> getParentPaths() - { - return Arrays.asList(VIRTUALHOSTS_VIRTUALHOST_TOPICS); - } - } - - private Map<String, TopicConfig> _topics = new HashMap<String, TopicConfig>(); - private Map<String, Map<String, TopicConfig>> _subscriptions = new HashMap<String, Map<String, TopicConfig>>(); - - public String[] getElementsProcessed() - { - return new String[]{"topic"}; - } - - @Override - public void validateConfiguration() throws ConfigurationException - { - if (getConfig().isEmpty()) - { - throw new ConfigurationException("Topics section cannot be empty."); - } - - int topics = getConfig().getList("topic.name").size() + - getConfig().getList("topic.subscriptionName").size(); - - for (int index = 0; index < topics; index++) - { - Configuration topicSubset = getConfig().subset("topic(" + index + ")"); - - // This will occur when we have a subscriptionName that is bound to a - // topic. - if (topicSubset.isEmpty()) - { - break; - } - - TopicConfig topic = new TopicConfig(); - - topic.setConfiguration(VIRTUALHOSTS_VIRTUALHOST_TOPICS + ".topic", topicSubset ); - - String name = getConfig().getString("topic(" + index + ").name"); - String subscriptionName = getConfig().getString("topic(" + index + ").subscriptionName"); - - // Record config if subscriptionName is there - if (subscriptionName != null) - { - processSubscription(subscriptionName, topic); - } - else - { - // Otherwise record config as topic if we have the name - if (name != null) - { - processTopic(name, topic); - } - } - } - } - - /** - * @param name - * @param topic - * - * @throws org.apache.commons.configuration.ConfigurationException - * - */ - private void processTopic(String name, TopicConfig topic) throws ConfigurationException - { - if (_topics.containsKey(name)) - { - throw new ConfigurationException("Topics section cannot contain two entries for the same topic."); - } - else - { - _topics.put(name, topic); - } - } - - - private void processSubscription(String name, TopicConfig topic) throws ConfigurationException - { - Map<String,TopicConfig> topics; - if (_subscriptions.containsKey(name)) - { - topics = _subscriptions.get(name); - - if (topics.containsKey(topic.getName())) - { - throw new ConfigurationException("Subcription cannot contain two entries for the same topic."); - } - } - else - { - topics = new HashMap<String,TopicConfig>(); - } - - topics.put(topic.getName(),topic); - _subscriptions.put(name, topics); - - } - - @Override - public String formatToString() - { - return "Topics:" + _topics + ", Subscriptions:" + _subscriptions; - } - - /** - * This processes the given queue and apply configuration in the following - * order: - * - * Global Topic Values -> Topic Values -> Subscription Values - * - * @param queue - * - * @return - */ - public ConfigurationPlugin getConfiguration(AMQQueue queue) - { - //Create config with global topic configuration - TopicConfig config = new TopicConfig(); - - // Add global topic configuration - config.addConfiguration(this); - - // Process Topic Bindings as these are more generic than subscriptions - List<TopicConfig> boundToTopics = new LinkedList<TopicConfig>(); - - //Merge the configuration in the order that they are bound - for (Binding binding : queue.getBindings()) - { - if (binding.getExchange().getType().equals(TopicExchange.TYPE)) - { - // Identify topic for the binding key - TopicConfig topicConfig = getTopicConfigForRoutingKey(binding.getBindingKey()); - if (topicConfig != null) - { - boundToTopics.add(topicConfig); - } - } - } - - // If the Queue is bound to a number of topics then only use the global - // topic configuration. - // todo - What does it mean in terms of configuration to be bound to a - // number of topics? Do we try and merge? - // YES - right thing to do would be to merge from generic to specific. - // Means we need to be able to get an ordered list of topics for this - // binding. - if (boundToTopics.size() == 1) - { - config.addConfiguration(boundToTopics.get(0)); - } - - // If we have a subscription then attempt to look it up. - String subscriptionName = queue.getName(); - - // Apply subscription configurations - if (_subscriptions.containsKey(subscriptionName)) - { - - //Get all the Configuration that this subscription is bound to. - Map<String, TopicConfig> topics = _subscriptions.get(subscriptionName); - - TopicConfig subscriptionSpecificConfig = null; - - // See if we have a TopicConfig in topics for a topic we are bound to. - for (Binding binding : queue.getBindings()) - { - if (binding.getExchange().getType().equals(TopicExchange.TYPE)) - { - //todo - What does it mean to have multiple matches? - // Take the first match we get - if (subscriptionSpecificConfig == null) - { - // lookup the binding to see if we have a match in the subscription configs - subscriptionSpecificConfig = topics.get(binding.getBindingKey()); - } - } - } - - //todo we don't account for wild cards here. only explicit matching and all subscriptions - if (subscriptionSpecificConfig == null) - { - // lookup the binding to see if we have a match in the subscription configs - subscriptionSpecificConfig = topics.get("#"); - } - - // Apply subscription specific config. - if (subscriptionSpecificConfig != null) - { - config.addConfiguration(subscriptionSpecificConfig); - } - } - return config; - } - - /** - * This method should perform the same heuristics as the TopicExchange - * to attempt to identify a piece of configuration for the give routingKey. - * - * i.e. If we have 'stocks.*' defined in the config - * and we bind 'stocks.appl' then we should return the 'stocks.*' - * configuration. - * - * @param routingkey the key to lookup - * - * @return the TopicConfig if found. - */ - private TopicConfig getTopicConfigForRoutingKey(String routingkey) - { - //todo actually perform TopicExchange style lookup not just straight - // lookup as we are just now. - return _topics.get(routingkey); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java deleted file mode 100644 index 16e08e3934..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * - * 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.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public class VirtualHostConfigType extends ConfigObjectType<VirtualHostConfigType, VirtualHostConfig> -{ - private static final List<VirtualHostProperty<?>> VIRTUAL_HOST_PROPERTIES = new ArrayList<VirtualHostProperty<?>>(); - private static final VirtualHostConfigType INSTANCE = new VirtualHostConfigType(); -public static interface VirtualHostProperty<S> extends ConfigProperty<VirtualHostConfigType, VirtualHostConfig, S> - { - } - - private abstract static class VirtualHostReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<VirtualHostConfigType, VirtualHostConfig, S> implements VirtualHostProperty<S> - { - public VirtualHostReadWriteProperty(String name) - { - super(name); - VIRTUAL_HOST_PROPERTIES.add(this); - } - } - - private abstract static class VirtualHostReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<VirtualHostConfigType, VirtualHostConfig, S> implements VirtualHostProperty<S> - { - public VirtualHostReadOnlyProperty(String name) - { - super(name); - VIRTUAL_HOST_PROPERTIES.add(this); - } - } - - - public static final VirtualHostReadOnlyProperty<String> NAME_PROPERTY = new VirtualHostReadOnlyProperty<String>("name") - { - public String getValue(VirtualHostConfig object) - { - return object.getName(); - } - }; - - - public static final VirtualHostReadOnlyProperty<BrokerConfig> BROKER_PROPERTY = new VirtualHostReadOnlyProperty<BrokerConfig>("broker") - { - public BrokerConfig getValue(VirtualHostConfig object) - { - return object.getBroker(); - } - }; - - public static final VirtualHostReadOnlyProperty<String> FEDERATION_TAG_PROPERTY = new VirtualHostReadOnlyProperty<String>("federationTag") - { - public String getValue(VirtualHostConfig object) - { - return object.getFederationTag(); - } - }; - - - - public Collection<? extends ConfigProperty<VirtualHostConfigType, VirtualHostConfig, ?>> getProperties() - { - return Collections.unmodifiableList(VIRTUAL_HOST_PROPERTIES); - } - - - private VirtualHostConfigType() - { - } - - public static VirtualHostConfigType getInstance() - { - return INSTANCE; - } - - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java index e557085631..eada676b65 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java @@ -23,35 +23,66 @@ package org.apache.qpid.server.configuration; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.PropertiesConfiguration; - -import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.registry.ApplicationRegistry; + +import org.apache.qpid.server.configuration.plugins.AbstractConfiguration; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.store.MemoryMessageStore; -import java.util.ArrayList; -import java.util.Arrays; +import java.io.File; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -public class VirtualHostConfiguration extends ConfigurationPlugin +public class VirtualHostConfiguration extends AbstractConfiguration { private final String _name; private final Map<String, QueueConfiguration> _queues = new HashMap<String, QueueConfiguration>(); private final Map<String, ExchangeConfiguration> _exchanges = new HashMap<String, ExchangeConfiguration>(); + private final Broker _broker; + private final long _defaultHouseKeepingCheckPeriod; - public VirtualHostConfiguration(String name, Configuration config) throws ConfigurationException + public VirtualHostConfiguration(String name, Configuration config, Broker broker) throws ConfigurationException { _name = name; + _broker = broker; + + // store value of this attribute for running life of virtual host since updating of this value has no run-time effect + _defaultHouseKeepingCheckPeriod = ((Number)_broker.getAttribute(Broker.HOUSEKEEPING_CHECK_PERIOD)).longValue(); setConfiguration(config); } + public VirtualHostConfiguration(String name, File configurationFile, Broker broker) throws ConfigurationException + { + this(name, loadConfiguration(name, configurationFile), broker); + } + + private static Configuration loadConfiguration(String name, File configurationFile) throws ConfigurationException + { + Configuration configuration = null; + if (configurationFile == null) + { + throw new IllegalConfigurationException("Virtualhost configuration file must be supplied!"); + } + else + { + Configuration virtualHostConfig = XmlConfigurationUtilities.parseConfig(configurationFile, null); + + // check if it is an old virtual host configuration file which has an element of the same name as virtual host + Configuration config = virtualHostConfig.subset("virtualhost." + XmlConfigurationUtilities.escapeTagName(name)); + if (config.isEmpty()) + { + // assume it is a new configuration which does not have an element of the same name as the virtual host + configuration = virtualHostConfig; + } + else + { + configuration = config; + } + } + return configuration; + } + /** * Apply the given configuration to this VirtualHostConfiguration * @@ -89,12 +120,7 @@ public class VirtualHostConfiguration extends ConfigurationPlugin public long getHousekeepingCheckPeriod() { - return getLongValue("housekeeping.checkPeriod", ApplicationRegistry.getInstance().getConfiguration().getHousekeepingCheckPeriod()); - } - - public List getCustomExchanges() - { - return getListValue("custom-exchanges.class-name"); + return getLongValue("housekeeping.checkPeriod", _defaultHouseKeepingCheckPeriod); } public Configuration getStoreConfiguration() @@ -149,138 +175,39 @@ public class VirtualHostConfiguration extends ConfigurationPlugin } } - public ConfigurationPlugin getQueueConfiguration(AMQQueue queue) - { - VirtualHostConfiguration hostConfig = queue.getVirtualHost().getConfiguration(); - - // First check if we have a named queue configuration (the easy case) - if (Arrays.asList(hostConfig.getQueueNames()).contains(queue.getName())) - { - return null; - } - - // We don't have an explicit queue config we must find out what we need. - ArrayList<Binding> bindings = new ArrayList<Binding>(queue.getBindings()); - - List<AMQShortString> exchangeClasses = new ArrayList<AMQShortString>(bindings.size()); - - //Remove default exchange - for (int index = 0; index < bindings.size(); index++) - { - // Ignore the DEFAULT Exchange binding - if (bindings.get(index).getExchange().getNameShortString().equals(ExchangeDefaults.DEFAULT_EXCHANGE_NAME)) - { - bindings.remove(index); - } - else - { - exchangeClasses.add(bindings.get(index).getExchange().getType().getName()); - - if (exchangeClasses.size() > 1) - { - // If we have more than 1 class of exchange then we can only use the global queue configuration. - // and this will be returned from the default getQueueConfiguration - return null; - } - } - } - - // If we are just bound the the default exchange then use the default. - if (bindings.isEmpty()) - { - return null; - } - - // If we are bound to only one type of exchange then we are going - // to have to resolve the configuration for that exchange. - - String exchangeName = bindings.get(0).getExchange().getType().getName().toString(); - - // Lookup a Configuration handler for this Exchange. - - // Build the expected class name. <Exchangename>sConfiguration - // i.e. TopicConfiguration or HeadersConfiguration - String exchangeClass = "org.apache.qpid.server.configuration." - + exchangeName.substring(0, 1).toUpperCase() - + exchangeName.substring(1) + "Configuration"; - - ExchangeConfigurationPlugin exchangeConfiguration - = (ExchangeConfigurationPlugin) queue.getVirtualHost().getConfiguration().getConfiguration(exchangeClass); - - // now need to perform the queue-topic-topics-queues magic. - // So make a new ConfigurationObject that will hold all the configuration for this queue. - ConfigurationPlugin queueConfig = new QueueConfiguration.QueueConfig(); - - // Initialise the queue with any Global values we may have - PropertiesConfiguration newQueueConfig = new PropertiesConfiguration(); - newQueueConfig.setProperty("name", queue.getName()); - - try - { - //Set the queue name - CompositeConfiguration mungedConf = new CompositeConfiguration(); - //Set the queue name - mungedConf.addConfiguration(newQueueConfig); - //Set the global queue configuration - mungedConf.addConfiguration(getConfig().subset("queues")); - - // Set configuration - queueConfig.setConfiguration("virtualhosts.virtualhost.queues", mungedConf); - } - catch (ConfigurationException e) - { - // This will not occur as queues only require a name. - _logger.error("QueueConfiguration requirements have changed."); - } - - // Merge any configuration the Exchange wishes to apply - if (exchangeConfiguration != null) - { - queueConfig.addConfiguration(exchangeConfiguration.getConfiguration(queue)); - } - - //Finally merge in any specific queue configuration we have. - if (_queues.containsKey(queue.getName())) - { - queueConfig.addConfiguration(_queues.get(queue.getName())); - } - - return queueConfig; - } - public int getMaximumMessageAge() { - return getIntValue("queues.maximumMessageAge"); + return getIntValue("queues.maximumMessageAge", getBrokerAttributeAsInt(Broker.ALERT_THRESHOLD_MESSAGE_AGE)); } public Long getMaximumQueueDepth() { - return getLongValue("queues.maximumQueueDepth"); + return getLongValue("queues.maximumQueueDepth", getBrokerAttributeAsLong(Broker.ALERT_THRESHOLD_QUEUE_DEPTH)); } public Long getMaximumMessageSize() { - return getLongValue("queues.maximumMessageSize"); + return getLongValue("queues.maximumMessageSize", getBrokerAttributeAsLong(Broker.ALERT_THRESHOLD_MESSAGE_SIZE)); } public Long getMaximumMessageCount() { - return getLongValue("queues.maximumMessageCount"); + return getLongValue("queues.maximumMessageCount", getBrokerAttributeAsLong(Broker.ALERT_THRESHOLD_MESSAGE_COUNT)); } public Long getMinimumAlertRepeatGap() { - return getLongValue("queues.minimumAlertRepeatGap", ApplicationRegistry.getInstance().getConfiguration().getMinimumAlertRepeatGap()); + return getLongValue("queues.minimumAlertRepeatGap", getBrokerAttributeAsLong(Broker.ALERT_REPEAT_GAP)); } public long getCapacity() { - return getLongValue("queues.capacity"); + return getLongValue("queues.capacity", getBrokerAttributeAsLong(Broker.FLOW_CONTROL_SIZE_BYTES)); } public long getFlowResumeCapacity() { - return getLongValue("queues.flowResumeCapacity", getCapacity()); + return getLongValue("queues.flowResumeCapacity", getBrokerAttributeAsLong(Broker.FLOW_CONTROL_RESUME_SIZE_BYTES)); } public String[] getElementsProcessed() @@ -336,7 +263,7 @@ public class VirtualHostConfiguration extends ConfigurationPlugin public int getMaxDeliveryCount() { - return getIntValue("queues.maximumDeliveryCount", ApplicationRegistry.getInstance().getConfiguration().getMaxDeliveryCount()); + return getIntValue("queues.maximumDeliveryCount", getBrokerAttributeAsInt(Broker.MAXIMUM_DELIVERY_ATTEMPTS)); } /** @@ -344,7 +271,25 @@ public class VirtualHostConfiguration extends ConfigurationPlugin */ public boolean isDeadLetterQueueEnabled() { - return getBooleanValue("queues.deadLetterQueues", ApplicationRegistry.getInstance().getConfiguration().isDeadLetterQueueEnabled()); + return getBooleanValue("queues.deadLetterQueues", getBrokerAttributeAsBoolean(Broker.DEAD_LETTER_QUEUE_ENABLED)); + } + + private long getBrokerAttributeAsLong(String name) + { + Number brokerValue = (Number)_broker.getAttribute(name); + return brokerValue == null? 0 : brokerValue.longValue(); + } + + private int getBrokerAttributeAsInt(String name) + { + Number brokerValue = (Number)_broker.getAttribute(name); + return brokerValue == null? 0 : brokerValue.intValue(); + } + + private boolean getBrokerAttributeAsBoolean(String name) + { + Boolean brokerValue = (Boolean)_broker.getAttribute(name); + return brokerValue == null? false : brokerValue.booleanValue(); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/XmlConfigurationUtilities.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/XmlConfigurationUtilities.java new file mode 100644 index 0000000000..c0cff2c109 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/XmlConfigurationUtilities.java @@ -0,0 +1,111 @@ +/* + * + * 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.configuration; + +import java.io.File; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.ConfigurationFactory; +import org.apache.commons.configuration.SystemConfiguration; +import org.apache.commons.configuration.XMLConfiguration; + +public class XmlConfigurationUtilities +{ + + // Our configuration class needs to make the interpolate method + // public so it can be called below from the config method. + public static class MyConfiguration extends CompositeConfiguration + { + public String interpolate(String obj) + { + return super.interpolate(obj); + } + } + + public static Configuration parseConfig(File file, Map<String, String> envVarMap) throws ConfigurationException + { + ConfigurationFactory factory = new ConfigurationFactory(); + factory.setConfigurationFileName(file.getAbsolutePath()); + Configuration conf = factory.getConfiguration(); + + Iterator<?> keys = conf.getKeys(); + if (!keys.hasNext()) + { + keys = null; + conf = flatConfig(file); + } + + XmlConfigurationUtilities.substituteEnvironmentVariables(conf, envVarMap); + return conf; + } + + public final static Configuration flatConfig(File file) throws ConfigurationException + { + // We have to override the interpolate methods so that + // interpolation takes place across the entirety of the + // composite configuration. Without doing this each + // configuration object only interpolates variables defined + // inside itself. + final MyConfiguration conf = new MyConfiguration(); + conf.addConfiguration(new SystemConfiguration() + { + protected String interpolate(String o) + { + return conf.interpolate(o); + } + }); + conf.addConfiguration(new XMLConfiguration(file) + { + protected String interpolate(String o) + { + return conf.interpolate(o); + } + }); + return conf; + } + + static void substituteEnvironmentVariables(Configuration conf, Map<String, String> envVarMap) + { + if (envVarMap == null || envVarMap.isEmpty()) + { + return; + } + for (Entry<String, String> var : envVarMap.entrySet()) + { + String val = System.getenv(var.getKey()); + if (val != null) + { + conf.setProperty(var.getValue(), val); + } + } + } + + + public static String escapeTagName(String name) + { + return name.replaceAll("\\.", "\\.\\."); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/AbstractConfiguration.java index d08e3bc806..3c17faef75 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/AbstractConfiguration.java @@ -23,25 +23,16 @@ import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.ConversionException; import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.ConfigurationManager; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.registry.IApplicationRegistry; - import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; -public abstract class ConfigurationPlugin +public abstract class AbstractConfiguration { - protected static final Logger _logger = Logger.getLogger(ConfigurationPlugin.class); - - private Map<String, ConfigurationPlugin> - _pluginConfiguration = new HashMap<String, ConfigurationPlugin>(); + protected static final Logger _logger = Logger.getLogger(AbstractConfiguration.class); private Configuration _config; @@ -69,11 +60,6 @@ public abstract class ConfigurationPlugin return _config; } - public <C extends ConfigurationPlugin> C getConfiguration(String plugin) - { - return (C) _pluginConfiguration.get(plugin); - } - /** * Sets the configuration for this plugin * @@ -118,7 +104,7 @@ public abstract class ConfigurationPlugin // With an XMLConfiguration the key will be [@property] // but with a CompositeConfiguration it will be @property]. // Hide this issue from our users so when/if we change the - // configuration they don't have to. + // configuration they don't have to. int bracketIndex = tag.indexOf("["); if (bracketIndex != -1) { @@ -140,62 +126,9 @@ public abstract class ConfigurationPlugin } } - offerRemainingConfigurationToOtherPlugins(path, configuration, elements); - validateConfiguration(); } - private void offerRemainingConfigurationToOtherPlugins(String path, - Configuration configuration, Set<String> elements) throws ConfigurationException - { - final IApplicationRegistry appRegistry = safeGetApplicationRegistryInstance(); - - if (appRegistry == null) - { - // We see this happen during shutdown due to asynchronous reconfig using IO threads. - // Need to remove the responsibility for offering configuration to other class. - _logger.info("Cannot offer remaining config to other plugins, can't find app registry"); - return; - } - - final ConfigurationManager configurationManager = appRegistry.getConfigurationManager(); - // Process the elements in the configuration - for (String element : elements) - { - Configuration handled = element.length() == 0 ? configuration : configuration.subset(element); - - String configurationElement = element; - if (path.length() > 0) - { - configurationElement = path + "." + configurationElement; - } - - List<ConfigurationPlugin> handlers = configurationManager.getConfigurationPlugins(configurationElement, handled); - - if(_logger.isDebugEnabled()) - { - _logger.debug("For '" + element + "' found handlers (" + handlers.size() + "):" + handlers); - } - - for (ConfigurationPlugin plugin : handlers) - { - _pluginConfiguration.put(plugin.getClass().getName(), plugin); - } - } - } - - private IApplicationRegistry safeGetApplicationRegistryInstance() - { - try - { - return ApplicationRegistry.getInstance(); - } - catch (IllegalStateException ise) - { - return null; - } - } - /** Helper method to print out list of keys in a {@link Configuration}. */ public static final void showKeys(Configuration config) { @@ -382,101 +315,9 @@ public abstract class ConfigurationPlugin } } - /** - * Given another configuration merge the configuration into our own config - * - * The new values being merged in will take precedence over existing values. - * - * In the simplistic case this means something like: - * - * So if we have configuration set - * name = 'fooo' - * - * And the new configuration contains a name then that will be reset. - * name = 'new' - * - * However this plugin will simply contain other plugins so the merge will - * be called until we end up at a base plugin that understand how to merge - * items. i.e Alerting values. Where the provided configuration will take - * precedence. - * - * @param configuration the config to merge in to our own. - */ - public void addConfiguration(ConfigurationPlugin configuration) - { - // If given configuration is null then there is nothing to process. - if (configuration == null) - { - return; - } - - // Merge all the sub configuration items - for (Map.Entry<String, ConfigurationPlugin> newPlugins : configuration._pluginConfiguration.entrySet()) - { - String key = newPlugins.getKey(); - ConfigurationPlugin config = newPlugins.getValue(); - - if (_pluginConfiguration.containsKey(key)) - { - //Merge the configuration if we already have this type of config - _pluginConfiguration.get(key).mergeConfiguration(config); - } - else - { - //otherwise just add it to our config. - _pluginConfiguration.put(key, config); - } - } - - //Merge the configuration itself - String key = configuration.getClass().getName(); - if (_pluginConfiguration.containsKey(key)) - { - //Merge the configuration if we already have this type of config - _pluginConfiguration.get(key).mergeConfiguration(configuration); - } - else - { - //If we are adding a configuration of our own type then merge - if (configuration.getClass() == this.getClass()) - { - mergeConfiguration(configuration); - } - else - { - // just store this in case someone else needs it. - _pluginConfiguration.put(key, configuration); - } - - } - - } - - protected void mergeConfiguration(ConfigurationPlugin configuration) - { - _config = configuration.getConfig(); - } - - public String toString() - { - StringBuilder sb = new StringBuilder(); - - sb.append("\n").append(getClass().getSimpleName()); - sb.append("=[ (").append(formatToString()).append(")"); - - for(Map.Entry<String,ConfigurationPlugin> item : _pluginConfiguration.entrySet()) - { - sb.append("\n").append(item.getValue()); - } - - sb.append("]\n"); - - return sb.toString(); - } - - public String formatToString() + public static String escapeTagName(String name) { - return super.toString(); + return name.replaceAll("\\.", "\\.\\."); } protected void setConfig(Configuration config) diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginFactory.java deleted file mode 100644 index fa41f3ef06..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * 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.configuration.plugins; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import java.util.List; - -public interface ConfigurationPluginFactory -{ - /** - * The Parent paths of the configuration that this plugin supports. - * - * For example, {@code queue} elements have a parent path of {@code virtualhosts.virtualhost}. - */ - public List<String> getParentPaths(); - - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException; -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionConfiguration.java deleted file mode 100644 index a90b1d514f..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionConfiguration.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * 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.configuration.plugins; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.TimeUnit; - -public class SlowConsumerDetectionConfiguration extends ConfigurationPlugin -{ - public static class SlowConsumerDetectionConfigurationFactory implements ConfigurationPluginFactory - { - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException - { - SlowConsumerDetectionConfiguration slowConsumerConfig = new SlowConsumerDetectionConfiguration(); - slowConsumerConfig.setConfiguration(path, config); - return slowConsumerConfig; - } - - public List<String> getParentPaths() - { - return Arrays.asList("virtualhosts.virtualhost.slow-consumer-detection"); - } - } - - //Set Default time unit to seconds - private TimeUnit _timeUnit = TimeUnit.SECONDS; - - public String[] getElementsProcessed() - { - return new String[]{"delay", - "timeunit"}; - } - - public long getDelay() - { - return getLongValue("delay", 10); - } - - public TimeUnit getTimeUnit() - { - return _timeUnit; - } - - @Override - public void validateConfiguration() throws ConfigurationException - { - validatePositiveLong("delay"); - - String timeUnit = getStringValue("timeunit"); - - if (timeUnit != null) - { - try - { - _timeUnit = TimeUnit.valueOf(timeUnit.toUpperCase()); - } - catch (IllegalArgumentException iae) - { - throw new ConfigurationException("Unable to configure Slow Consumer Detection invalid TimeUnit:" + timeUnit); - } - } - - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionPolicyConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionPolicyConfiguration.java deleted file mode 100644 index a9026c6164..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionPolicyConfiguration.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * 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.configuration.plugins; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import java.util.Arrays; -import java.util.List; - -public class SlowConsumerDetectionPolicyConfiguration extends ConfigurationPlugin -{ - public static class SlowConsumerDetectionPolicyConfigurationFactory implements ConfigurationPluginFactory - { - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException - { - SlowConsumerDetectionPolicyConfiguration slowConsumerConfig = new SlowConsumerDetectionPolicyConfiguration(); - slowConsumerConfig.setConfiguration(path, config); - return slowConsumerConfig; - } - - public List<String> getParentPaths() - { - return Arrays.asList( - "virtualhosts.virtualhost.queues.slow-consumer-detection.policy", - "virtualhosts.virtualhost.queues.queue.slow-consumer-detection.policy", - "virtualhosts.virtualhost.topics.slow-consumer-detection.policy", - "virtualhosts.virtualhost.topics.topic.slow-consumer-detection.policy"); - } - } - - public String[] getElementsProcessed() - { - return new String[]{"name"}; - } - - public String getPolicyName() - { - return getStringValue("name"); - } - - @Override - public void validateConfiguration() throws ConfigurationException - { - if (getPolicyName() == null) - { - throw new ConfigurationException("No Slow consumer policy defined."); - } - } - - @Override - public String formatToString() - { - return "Policy:"+getPolicyName(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionQueueConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionQueueConfiguration.java deleted file mode 100644 index cb3bb5a77f..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionQueueConfiguration.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * - * 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.configuration.plugins; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.plugins.PluginManager; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPlugin; -import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPluginFactory; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -public class SlowConsumerDetectionQueueConfiguration extends ConfigurationPlugin -{ - private SlowConsumerPolicyPlugin _policyPlugin; - - public static class SlowConsumerDetectionQueueConfigurationFactory implements ConfigurationPluginFactory - { - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException - { - SlowConsumerDetectionQueueConfiguration slowConsumerConfig = new SlowConsumerDetectionQueueConfiguration(); - slowConsumerConfig.setConfiguration(path, config); - return slowConsumerConfig; - } - - public List<String> getParentPaths() - { - return Arrays.asList( - "virtualhosts.virtualhost.queues.slow-consumer-detection", - "virtualhosts.virtualhost.queues.queue.slow-consumer-detection", - "virtualhosts.virtualhost.topics.slow-consumer-detection", - "virtualhosts.virtualhost.topics.topic.slow-consumer-detection"); - } - } - - public String[] getElementsProcessed() - { - return new String[]{"messageAge", - "depth", - "messageCount"}; - } - - public long getMessageAge() - { - return getLongValue("messageAge"); - } - - public long getDepth() - { - return getLongValue("depth"); - } - - public long getMessageCount() - { - return getLongValue("messageCount"); - } - - public SlowConsumerPolicyPlugin getPolicy() - { - return _policyPlugin; - } - - @Override - public void validateConfiguration() throws ConfigurationException - { - PluginManager pluginManager; - try - { - pluginManager = ApplicationRegistry.getInstance().getPluginManager(); - } - catch (IllegalStateException ise) - { - // We see this happen during shutdown due to asynchronous reconfig performed IO threads - // running at the same time as the shutdown handler. - _policyPlugin = null; - return; - } - - if (!containsPositiveLong("messageAge") && - !containsPositiveLong("depth") && - !containsPositiveLong("messageCount")) - { - throw new ConfigurationException("At least one configuration property" + - "('messageAge','depth' or 'messageCount') must be specified."); - } - - SlowConsumerDetectionPolicyConfiguration policyConfig = getConfiguration(SlowConsumerDetectionPolicyConfiguration.class.getName()); - Map<String, SlowConsumerPolicyPluginFactory> factories = pluginManager.getSlowConsumerPlugins(); - - if (policyConfig == null) - { - throw new ConfigurationException("No Slow Consumer Policy specified. Known Policies:" + factories.keySet()); - } - - if (_logger.isDebugEnabled()) - { - Iterator<?> keys = policyConfig.getConfig().getKeys(); - - while (keys.hasNext()) - { - String key = (String) keys.next(); - - _logger.debug("Policy Keys:" + key); - } - - } - - SlowConsumerPolicyPluginFactory<SlowConsumerPolicyPlugin> pluginFactory = factories.get(policyConfig.getPolicyName().toLowerCase()); - - if (pluginFactory == null) - { - throw new ConfigurationException("Unknown Slow Consumer Policy specified:" + policyConfig.getPolicyName() + " Known Policies:" + factories.keySet()); - } - - _policyPlugin = pluginFactory.newInstance(policyConfig); - - // Debug the creation of this Config - _logger.debug(this); - } - - public String formatToString() - { - StringBuilder sb = new StringBuilder(); - if (getMessageAge() > 0) - { - sb.append("Age:").append(getMessageAge()).append(":"); - } - if (getDepth() > 0) - { - sb.append("Depth:").append(getDepth()).append(":"); - } - if (getMessageCount() > 0) - { - sb.append("Count:").append(getMessageCount()).append(":"); - } - - sb.append("Policy[").append(getPolicy()).append("]"); - return sb.toString(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java new file mode 100644 index 0000000000..9b06a2b499 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java @@ -0,0 +1,55 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.startup; + +import java.util.Map; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; + +public class AuthenticationProviderRecoverer implements ConfiguredObjectRecoverer<AuthenticationProvider> +{ + private final AuthenticationProviderFactory _authenticationProviderFactory; + + public AuthenticationProviderRecoverer(AuthenticationProviderFactory authenticationProviderFactory) + { + _authenticationProviderFactory = authenticationProviderFactory; + } + + @Override + public AuthenticationProvider create(RecovererProvider recovererProvider, ConfigurationEntry configurationEntry, ConfiguredObject... parents) + { + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + Map<String, Object> attributes = configurationEntry.getAttributes(); + AuthenticationProvider authenticationProvider = _authenticationProviderFactory.create( + configurationEntry.getId(), + broker, + attributes, null); + + return authenticationProvider; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java new file mode 100644 index 0000000000..4bfa0ca7a3 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java @@ -0,0 +1,139 @@ +package org.apache.qpid.server.configuration.startup; + +import java.util.Collection; +import java.util.Map; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.logging.LogRecorder; +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; +import org.apache.qpid.server.model.adapter.BrokerAdapter; +import org.apache.qpid.server.model.adapter.PortFactory; +import org.apache.qpid.server.configuration.store.StoreConfigurationChangeListener; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.security.group.GroupPrincipalAccessor; +import org.apache.qpid.server.stats.StatisticsGatherer; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; + +public class BrokerRecoverer implements ConfiguredObjectRecoverer<Broker> +{ + private final StatisticsGatherer _statisticsGatherer; + private final VirtualHostRegistry _virtualHostRegistry; + private final LogRecorder _logRecorder; + private final RootMessageLogger _rootMessageLogger; + private final AuthenticationProviderFactory _authenticationProviderFactory; + private final PortFactory _portFactory; + private final TaskExecutor _taskExecutor; + + public BrokerRecoverer(AuthenticationProviderFactory authenticationProviderFactory, PortFactory portFactory, + StatisticsGatherer statisticsGatherer, VirtualHostRegistry virtualHostRegistry, LogRecorder logRecorder, + RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor) + { + _portFactory = portFactory; + _authenticationProviderFactory = authenticationProviderFactory; + _statisticsGatherer = statisticsGatherer; + _virtualHostRegistry = virtualHostRegistry; + _logRecorder = logRecorder; + _rootMessageLogger = rootMessageLogger; + _taskExecutor = taskExecutor; + } + + @Override + public Broker create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents) + { + StoreConfigurationChangeListener storeChangeListener = new StoreConfigurationChangeListener(entry.getStore()); + BrokerAdapter broker = new BrokerAdapter(entry.getId(), entry.getAttributes(), _statisticsGatherer, _virtualHostRegistry, + _logRecorder, _rootMessageLogger, _authenticationProviderFactory, _portFactory, _taskExecutor); + broker.addChangeListener(storeChangeListener); + Map<String, Collection<ConfigurationEntry>> childEntries = entry.getChildren(); + for (String type : childEntries.keySet()) + { + ConfiguredObjectRecoverer<?> recoverer = recovererProvider.getRecoverer(type); + if (recoverer == null) + { + throw new IllegalConfigurationException("Cannot recover entry for the type '" + type + "' from broker"); + } + Collection<ConfigurationEntry> entries = childEntries.get(type); + for (ConfigurationEntry childEntry : entries) + { + ConfiguredObject object = recoverer.create(recovererProvider, childEntry, broker); + if (object == null) + { + throw new IllegalConfigurationException("Cannot create configured object for the entry " + childEntry); + } + broker.recoverChild(object); + object.addChangeListener(storeChangeListener); + } + } + wireUpConfiguredObjects(broker, entry.getAttributes()); + + return broker; + } + + private void wireUpConfiguredObjects(BrokerAdapter broker, Map<String, Object> brokerAttributes) + { + AuthenticationProvider defaultAuthenticationProvider = null; + Collection<AuthenticationProvider> authenticationProviders = broker.getAuthenticationProviders(); + int numberOfAuthenticationProviders = authenticationProviders.size(); + if (numberOfAuthenticationProviders == 0) + { + throw new IllegalConfigurationException("No authentication provider was configured"); + } + else if (numberOfAuthenticationProviders == 1) + { + defaultAuthenticationProvider = authenticationProviders.iterator().next(); + } + else + { + String name = (String) brokerAttributes.get(Broker.DEFAULT_AUTHENTICATION_PROVIDER); + if (name == null) + { + throw new IllegalConfigurationException("Multiple authentication providers defined, but no default was configured."); + } + + defaultAuthenticationProvider = getAuthenticationProviderByName(broker, name); + } + broker.setDefaultAuthenticationProvider(defaultAuthenticationProvider); + + GroupPrincipalAccessor groupPrincipalAccessor = new GroupPrincipalAccessor(broker.getGroupProviders()); + for (AuthenticationProvider authenticationProvider : authenticationProviders) + { + authenticationProvider.setGroupAccessor(groupPrincipalAccessor); + } + + Collection<Port> ports = broker.getPorts(); + for (Port port : ports) + { + String authenticationProviderName = (String) port.getAttribute(Port.AUTHENTICATION_MANAGER); + AuthenticationProvider provider = null; + if (authenticationProviderName != null) + { + provider = getAuthenticationProviderByName(broker, authenticationProviderName); + } + else + { + provider = defaultAuthenticationProvider; + } + port.setAuthenticationProvider(provider); + } + } + + private AuthenticationProvider getAuthenticationProviderByName(BrokerAdapter broker, String authenticationProviderName) + { + AuthenticationProvider provider = broker.getAuthenticationProviderByName(authenticationProviderName); + if (provider == null) + { + throw new IllegalConfigurationException("Cannot find the authentication provider with name: " + + authenticationProviderName); + } + return provider; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java new file mode 100644 index 0000000000..15cb229d8a --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java @@ -0,0 +1,112 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.startup; + +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.logging.LogRecorder; +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.model.KeyStore; +import org.apache.qpid.server.model.Plugin; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; +import org.apache.qpid.server.model.adapter.PortFactory; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; +import org.apache.qpid.server.plugin.GroupManagerFactory; +import org.apache.qpid.server.plugin.PluginFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; +import org.apache.qpid.server.stats.StatisticsGatherer; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; + +public class DefaultRecovererProvider implements RecovererProvider +{ + + private final StatisticsGatherer _brokerStatisticsGatherer; + private final VirtualHostRegistry _virtualHostRegistry; + private final LogRecorder _logRecorder; + private final RootMessageLogger _rootMessageLogger; + private final AuthenticationProviderFactory _authenticationProviderFactory; + private final PortFactory _portFactory; + private final QpidServiceLoader<GroupManagerFactory> _groupManagerServiceLoader; + private final QpidServiceLoader<PluginFactory> _pluginFactoryServiceLoader; + private final TaskExecutor _taskExecutor; + + public DefaultRecovererProvider(StatisticsGatherer brokerStatisticsGatherer, VirtualHostRegistry virtualHostRegistry, + LogRecorder logRecorder, RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor) + { + _authenticationProviderFactory = new AuthenticationProviderFactory(new QpidServiceLoader<AuthenticationManagerFactory>()); + _portFactory = new PortFactory(); + _brokerStatisticsGatherer = brokerStatisticsGatherer; + _virtualHostRegistry = virtualHostRegistry; + _logRecorder = logRecorder; + _rootMessageLogger = rootMessageLogger; + _groupManagerServiceLoader = new QpidServiceLoader<GroupManagerFactory>(); + _pluginFactoryServiceLoader = new QpidServiceLoader<PluginFactory>(); + _taskExecutor = taskExecutor; + } + + @Override + public ConfiguredObjectRecoverer<?> getRecoverer(String type) + { + if (Broker.class.getSimpleName().equals(type)) + { + return new BrokerRecoverer(_authenticationProviderFactory, _portFactory, _brokerStatisticsGatherer, _virtualHostRegistry, + _logRecorder, _rootMessageLogger, _taskExecutor); + } + else if(VirtualHost.class.getSimpleName().equals(type)) + { + return new VirtualHostRecoverer(_brokerStatisticsGatherer); + } + else if(AuthenticationProvider.class.getSimpleName().equals(type)) + { + return new AuthenticationProviderRecoverer(_authenticationProviderFactory); + } + else if(Port.class.getSimpleName().equals(type)) + { + return new PortRecoverer(_portFactory); + } + else if(GroupProvider.class.getSimpleName().equals(type)) + { + return new GroupProviderRecoverer(_groupManagerServiceLoader); + } + else if(KeyStore.class.getSimpleName().equals(type)) + { + return new KeyStoreRecoverer(); + } + else if(TrustStore.class.getSimpleName().equals(type)) + { + return new TrustStoreRecoverer(); + } + else if(Plugin.class.getSimpleName().equals(type)) + { + return new PluginRecoverer(_pluginFactoryServiceLoader); + } + + return null; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/GroupProviderRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/GroupProviderRecoverer.java new file mode 100644 index 0000000000..275a0c736c --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/GroupProviderRecoverer.java @@ -0,0 +1,74 @@ +/* + * + * 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.configuration.startup; + +import java.util.Map; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.model.adapter.GroupProviderAdapter; +import org.apache.qpid.server.plugin.GroupManagerFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; +import org.apache.qpid.server.security.group.GroupManager; + +public class GroupProviderRecoverer implements ConfiguredObjectRecoverer<GroupProvider> +{ + private QpidServiceLoader<GroupManagerFactory> _groupManagerServiceLoader; + + public GroupProviderRecoverer(QpidServiceLoader<GroupManagerFactory> groupManagerServiceLoader) + { + super(); + _groupManagerServiceLoader = groupManagerServiceLoader; + } + + @Override + public GroupProvider create(RecovererProvider recovererProvider, ConfigurationEntry configurationEntry, ConfiguredObject... parents) + { + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + Map<String, Object> attributes = configurationEntry.getAttributes(); + GroupManager groupManager = createGroupManager(attributes); + if (groupManager == null) + { + throw new IllegalConfigurationException("Cannot create GroupManager from attributes : " + attributes); + } + GroupProviderAdapter groupProviderAdapter = new GroupProviderAdapter(configurationEntry.getId(), groupManager, broker); + return groupProviderAdapter; + } + + private GroupManager createGroupManager(Map<String, Object> attributes) + { + for(GroupManagerFactory factory : _groupManagerServiceLoader.instancesOf(GroupManagerFactory.class)) + { + GroupManager groupManager = factory.createInstance(attributes); + if (groupManager != null) + { + return groupManager; + } + } + return null; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/KeyStoreRecoverer.java index 833ccfbca4..8efedd37b5 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/KeyStoreRecoverer.java @@ -18,30 +18,23 @@ * under the License. * */ -package org.apache.qpid.qmf; +package org.apache.qpid.server.configuration.startup; -import org.apache.qpid.transport.codec.BBEncoder; +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.KeyStore; +import org.apache.qpid.server.model.adapter.KeyStoreAdapter; -public abstract class QMFEventCommand<T extends QMFEventClass> extends QMFCommand +public class KeyStoreRecoverer implements ConfiguredObjectRecoverer<KeyStore> { - private final long _timestamp; - - protected QMFEventCommand() - { - super(new QMFCommandHeader((byte)'2',0, QMFOperation.EVENT)); - _timestamp = System.currentTimeMillis(); - } - - abstract public T getEventClass(); - @Override - public void encode(final BBEncoder encoder) + public KeyStore create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents) { - super.encode(encoder); - encoder.writeStr8(getEventClass().getPackage().getName()); - encoder.writeStr8(getEventClass().getName()); - encoder.writeBin128(new byte[16]); - encoder.writeUint64(_timestamp * 1000000L); - encoder.writeUint8((short) getEventClass().getSeverity().ordinal()); + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + return new KeyStoreAdapter(entry.getId(), broker, entry.getAttributes()); } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PluginRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PluginRecoverer.java new file mode 100644 index 0000000000..ddc4482953 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PluginRecoverer.java @@ -0,0 +1,66 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.startup; + +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.plugin.PluginFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; + +public class PluginRecoverer implements ConfiguredObjectRecoverer<ConfiguredObject> +{ + private QpidServiceLoader<PluginFactory> _serviceLoader; + + public PluginRecoverer(QpidServiceLoader<PluginFactory> serviceLoader) + { + _serviceLoader = serviceLoader; + } + + @Override + public ConfiguredObject create(RecovererProvider recovererProvider, ConfigurationEntry configurationEntry, ConfiguredObject... parents) + { + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + Map<String, Object> attributes = configurationEntry.getAttributes(); + Iterable<PluginFactory> factories = _serviceLoader.instancesOf(PluginFactory.class); + for (PluginFactory pluginFactory : factories) + { + UUID configurationId = configurationEntry.getId(); + ConfiguredObject pluginObject = pluginFactory.createInstance(configurationId, attributes, broker); + if (pluginObject != null) + { + UUID pluginId = pluginObject.getId(); + if (!configurationId.equals(pluginId)) + { + throw new IllegalStateException("Plugin object id '" + pluginId + "' does not equal expected id " + configurationId); + } + return pluginObject; + } + } + throw new IllegalConfigurationException("Cannot create a plugin object for " + attributes + " with factories " + factories); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PortRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PortRecoverer.java new file mode 100644 index 0000000000..147e835a8d --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PortRecoverer.java @@ -0,0 +1,52 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.startup; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.adapter.BrokerAdapter; +import org.apache.qpid.server.model.adapter.PortFactory; + +public class PortRecoverer implements ConfiguredObjectRecoverer<Port> +{ + /** + * delegates to a {@link PortFactory} so that the logic can be shared by + * {@link BrokerAdapter} + */ + private final PortFactory _portFactory; + + public PortRecoverer(PortFactory portFactory) + { + _portFactory = portFactory; + } + + @Override + public Port create(RecovererProvider recovererProvider, ConfigurationEntry configurationEntry, ConfiguredObject... parents) + { + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + return _portFactory.createPort(configurationEntry.getId(), broker, configurationEntry.getAttributes()); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/RecovererHelper.java index 9c8fa1e2c6..b60c9c289f 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/RecovererHelper.java @@ -18,27 +18,27 @@ * under the License. * */ +package org.apache.qpid.server.configuration.startup; -package org.apache.qpid.qmf; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; -import org.apache.qpid.transport.codec.BBEncoder; - -public class QMFPackageIndicationCommand extends QMFCommand +public class RecovererHelper { - private String _supportedSchema; - - public QMFPackageIndicationCommand(QMFPackageQueryCommand qmfPackageQueryCommand, String supportedSchema) - { - super( new QMFCommandHeader(qmfPackageQueryCommand.getHeader().getVersion(), - qmfPackageQueryCommand.getHeader().getSeq(), - QMFOperation.PACKAGE_INDICATION)); - _supportedSchema = supportedSchema; - - } - - public void encode(BBEncoder encoder) + public static Broker verifyOnlyBrokerIsParent(ConfiguredObject... parents) { - super.encode(encoder); - encoder.writeStr8(_supportedSchema); + if (parents == null || parents.length == 0) + { + throw new IllegalArgumentException("Broker parent is not passed!"); + } + if (parents.length != 1) + { + throw new IllegalArgumentException("Only one parent is expected!"); + } + if (!(parents[0] instanceof Broker)) + { + throw new IllegalArgumentException("Parent is not a broker"); + } + return (Broker)parents[0]; } } diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/TrustStoreRecoverer.java index 613e1e5978..7e9428a4d6 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/TrustStoreRecoverer.java @@ -18,31 +18,23 @@ * under the License. * */ +package org.apache.qpid.server.configuration.startup; -package org.apache.qpid.qmf; +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.server.model.adapter.TrustStoreAdapter; -import org.apache.qpid.transport.codec.BBEncoder; - -public class QMFClassIndicationCommand extends QMFCommand +public class TrustStoreRecoverer implements ConfiguredObjectRecoverer<TrustStore> { - private QMFClass _qmfClass; - - public QMFClassIndicationCommand(QMFClassQueryCommand qmfClassQueryCommand, QMFClass qmfClass) - { - super(new QMFCommandHeader(qmfClassQueryCommand.getHeader().getVersion(), - qmfClassQueryCommand.getHeader().getSeq(), - QMFOperation.CLASS_INDICATION)); - _qmfClass = qmfClass; - } - - @Override - public void encode(BBEncoder encoder) + public TrustStore create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents) { - super.encode(encoder); - encoder.writeUint8(_qmfClass.getType().getValue()); - encoder.writeStr8(_qmfClass.getPackage().getName()); - encoder.writeStr8(_qmfClass.getName()); - encoder.writeBin128(_qmfClass.getSchemaHash()); + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + return new TrustStoreAdapter(entry.getId(), broker, entry.getAttributes()); } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/VirtualHostRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/VirtualHostRecoverer.java new file mode 100644 index 0000000000..4f863adfb5 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/VirtualHostRecoverer.java @@ -0,0 +1,51 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.startup; + + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.adapter.VirtualHostAdapter; +import org.apache.qpid.server.stats.StatisticsGatherer; + +public class VirtualHostRecoverer implements ConfiguredObjectRecoverer<VirtualHost> +{ + private StatisticsGatherer _brokerStatisticsGatherer; + + public VirtualHostRecoverer(StatisticsGatherer brokerStatisticsGatherer) + { + super(); + _brokerStatisticsGatherer = brokerStatisticsGatherer; + } + + @Override + public VirtualHost create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents) + { + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + + return new VirtualHostAdapter(entry.getId(), entry.getAttributes(), broker, _brokerStatisticsGatherer, broker.getTaskExecutor()); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java new file mode 100644 index 0000000000..e11b63001a --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java @@ -0,0 +1,711 @@ +package org.apache.qpid.server.configuration.store; + +import static org.apache.qpid.server.configuration.ConfigurationEntry.ATTRIBUTE_NAME; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.util.FileUtils; +import org.apache.qpid.util.Strings; +import org.codehaus.jackson.JsonGenerationException; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.JsonMappingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.SerializationConfig; +import org.codehaus.jackson.node.ArrayNode; + +public class JsonConfigurationEntryStore implements ConfigurationEntryStore +{ + public static final String STORE_TYPE = "json"; + public static final String IN_MEMORY = ":memory:"; + + private static final String DEFAULT_BROKER_NAME = "Broker"; + private static final String ID = "id"; + private static final String TYPE = "@type"; + + private ObjectMapper _objectMapper; + private Map<UUID, ConfigurationEntry> _entries; + private File _storeFile; + private UUID _rootId; + private Map<String, Class<? extends ConfiguredObject>> _relationshipClasses; + + public JsonConfigurationEntryStore() + { + _objectMapper = new ObjectMapper(); + _objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true); + _objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); + _entries = new HashMap<UUID, ConfigurationEntry>(); + _relationshipClasses = buildRelationshipClassMap(); + } + + @Override + public void open(String storeLocation) + { + if (_rootId != null) + { + throw new IllegalConfigurationException("The store has been opened alread"); + } + if (!IN_MEMORY.equals(storeLocation)) + { + _storeFile = new File(storeLocation); + } + createOrLoadStore(); + } + + @Override + public void open(String storeLocation, String initialStoreLocation) + { + if (_rootId != null) + { + throw new IllegalConfigurationException("The store has been opened already"); + } + if (!IN_MEMORY.equals(storeLocation)) + { + _storeFile = new File(storeLocation); + if ((!_storeFile.exists() || _storeFile.length() == 0) && initialStoreLocation != null) + { + copyInitialStoreFile(initialStoreLocation); + } + createOrLoadStore(); + } + else + { + if (initialStoreLocation == null) + { + createRootEntryIfNotExists(); + } + else + { + load(toURL(initialStoreLocation)); + } + } + } + + @Override + public void open(String storeLocation, ConfigurationEntryStore initialStore) + { + if (_rootId != null) + { + throw new IllegalConfigurationException("The store has been opened already"); + } + boolean copyStore = false; + if (IN_MEMORY.equals(storeLocation)) + { + copyStore = initialStore != null; + } + else + { + _storeFile = new File(storeLocation); + if ((!_storeFile.exists() || _storeFile.length() == 0) && initialStore != null) + { + createStoreFileIfNotExist(_storeFile); + copyStore = true; + } + } + if (copyStore) + { + ConfigurationEntry rootEntry = initialStore.getRootEntry(); + _rootId = rootEntry.getId(); + copyEntry(rootEntry.getId(), initialStore); + saveAsTree(); + } + else + { + createOrLoadStore(); + } + } + + @Override + public synchronized UUID[] remove(UUID... entryIds) + { + List<UUID> removedIds = new ArrayList<UUID>(); + boolean anyRemoved = false; + for (UUID uuid : entryIds) + { + if (_rootId.equals(uuid)) + { + throw new IllegalConfigurationException("Cannot remove root entry"); + } + } + for (UUID uuid : entryIds) + { + if (removeInternal(uuid)) + { + anyRemoved = true; + + // remove references to the entry from parent entries + for (ConfigurationEntry entry : _entries.values()) + { + if (entry.hasChild(uuid)) + { + Set<UUID> children = new HashSet<UUID>(entry.getChildrenIds()); + children.remove(uuid); + ConfigurationEntry referal = new ConfigurationEntry(entry.getId(), entry.getType(), + entry.getAttributes(), children, this); + _entries.put(entry.getId(), referal); + } + } + removedIds.add(uuid); + } + } + if (anyRemoved) + { + saveAsTree(); + } + return removedIds.toArray(new UUID[removedIds.size()]); + } + + @Override + public synchronized void save(ConfigurationEntry... entries) + { + boolean anySaved = false; + for (ConfigurationEntry entry : entries) + { + ConfigurationEntry oldEntry = _entries.put(entry.getId(), entry); + if (!entry.equals(oldEntry)) + { + anySaved = true; + } + } + if (anySaved) + { + saveAsTree(); + } + } + + @Override + public ConfigurationEntry getRootEntry() + { + return getEntry(_rootId); + } + + @Override + public synchronized ConfigurationEntry getEntry(UUID id) + { + return _entries.get(id); + } + + @Override + public void copyTo(String copyLocation) + { + if (_rootId == null) + { + throw new IllegalConfigurationException("The store has not been opened"); + } + File file = new File(copyLocation); + if (!file.exists()) + { + createStoreFileIfNotExist(file); + } + saveAsTree(_rootId, _entries, _objectMapper, file); + } + + @Override + public String toString() + { + return "JsonConfigurationEntryStore [_storeFile=" + _storeFile + ", _rootId=" + _rootId + "]"; + } + + private Map<String, Class<? extends ConfiguredObject>> buildRelationshipClassMap() + { + Map<String, Class<? extends ConfiguredObject>> relationships = new HashMap<String, Class<? extends ConfiguredObject>>(); + + Collection<Class<? extends ConfiguredObject>> children = Model.getInstance().getChildTypes(Broker.class); + for (Class<? extends ConfiguredObject> childClass : children) + { + String name = childClass.getSimpleName().toLowerCase(); + String relationshipName = name + (name.endsWith("s") ? "es" : "s"); + relationships.put(relationshipName, childClass); + } + return relationships; + } + + private void createOrLoadStore() + { + if (_storeFile != null) + { + if (!_storeFile.exists() || _storeFile.length() == 0) + { + createStoreFileIfNotExist(_storeFile); + } + else + { + load(fileToURL(_storeFile)); + } + } + + createRootEntryIfNotExists(); + } + + private void createRootEntryIfNotExists() + { + if (_rootId == null) + { + // create a root entry for an empty store + ConfigurationEntry brokerEntry = new ConfigurationEntry(UUIDGenerator.generateRandomUUID(), + Broker.class.getSimpleName(), Collections.<String, Object> emptyMap(), Collections.<UUID> emptySet(), this); + _rootId = brokerEntry.getId(); + _entries.put(_rootId, brokerEntry); + } + } + + private void load(URL url) + { + InputStream is = null; + try + { + is = url.openStream(); + JsonNode node = loadJsonNodes(is, _objectMapper); + ConfigurationEntry brokerEntry = toEntry(node, Broker.class, _entries); + _rootId = brokerEntry.getId(); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot load store from: " + url, e); + } + finally + { + if (is != null) + { + if (is != null) + { + try + { + is.close(); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot close input stream for: " + url, e); + } + } + } + } + } + + private void copyInitialStoreFile(String initialStoreLocation) + { + createStoreFileIfNotExist(_storeFile); + URL initialStoreURL = toURL(initialStoreLocation); + InputStream in = null; + try + { + in = initialStoreURL.openStream(); + FileUtils.copy(in, _storeFile); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot create store file " + _storeFile + " by copying initial store from " + initialStoreLocation , e); + } + finally + { + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot close initial store input stream: " + initialStoreLocation , e); + } + } + } + } + + private URL fileToURL(File storeFile) + { + URL storeURL = null; + try + { + storeURL = storeFile.toURI().toURL(); + } + catch (MalformedURLException e) + { + throw new IllegalConfigurationException("Cannot create URL for file " + storeFile, e); + } + return storeURL; + } + + private boolean removeInternal(UUID entryId) + { + ConfigurationEntry oldEntry = _entries.remove(entryId); + if (oldEntry != null) + { + Set<UUID> children = oldEntry.getChildrenIds(); + if (children != null && !children.isEmpty()) + { + for (UUID childId : children) + { + removeInternal(childId); + } + } + return true; + } + return false; + } + + private void saveAsTree() + { + if (_storeFile != null) + { + saveAsTree(_rootId, _entries, _objectMapper, _storeFile); + } + } + + private void saveAsTree(UUID rootId, Map<UUID, ConfigurationEntry> entries, ObjectMapper mapper, File file) + { + Map<String, Object> tree = toTree(rootId, entries); + try + { + mapper.writeValue(file, tree); + } + catch (JsonGenerationException e) + { + throw new IllegalConfigurationException("Cannot generate json!", e); + } + catch (JsonMappingException e) + { + throw new IllegalConfigurationException("Cannot map objects for json serialization!", e); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot save configuration into " + file + "!", e); + } + } + + private Map<String, Object> toTree(UUID rootId, Map<UUID, ConfigurationEntry> entries) + { + ConfigurationEntry entry = entries.get(rootId); + if (entry == null || !entry.getId().equals(rootId)) + { + throw new IllegalConfigurationException("Cannot find entry with id " + rootId + "!"); + } + Map<String, Object> tree = new TreeMap<String, Object>(); + Map<String, Object> attributes = entry.getAttributes(); + if (attributes != null) + { + tree.putAll(attributes); + } + tree.put(ID, entry.getId()); + tree.put(TYPE, entry.getType()); + Set<UUID> childrenIds = entry.getChildrenIds(); + if (childrenIds != null && !childrenIds.isEmpty()) + { + for (UUID relationship : childrenIds) + { + ConfigurationEntry child = entries.get(relationship); + if (child != null) + { + String relationshipName = child.getType().toLowerCase() + "s"; + + @SuppressWarnings("unchecked") + Collection<Map<String, Object>> children = (Collection<Map<String, Object>>) tree.get(relationshipName); + if (children == null) + { + children = new ArrayList<Map<String, Object>>(); + tree.put(relationshipName, children); + } + Map<String, Object> childAsMap = toTree(relationship, entries); + children.add(childAsMap); + } + } + } + return tree; + } + + private JsonNode loadJsonNodes(InputStream is, ObjectMapper mapper) + { + JsonNode root = null; + try + { + root = mapper.readTree(is); + } + catch (JsonProcessingException e) + { + throw new IllegalConfigurationException("Cannot parse json", e); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot read json", e); + } + return root; + } + + private ConfigurationEntry toEntry(JsonNode parent, Class<? extends ConfiguredObject> expectedConfiguredObjectClass, Map<UUID, ConfigurationEntry> entries) + { + Map<String, Object> attributes = null; + Set<UUID> childrenIds = new TreeSet<UUID>(); + Iterator<String> fieldNames = parent.getFieldNames(); + String type = null; + String idAsString = null; + while (fieldNames.hasNext()) + { + String fieldName = fieldNames.next(); + JsonNode fieldNode = parent.get(fieldName); + if (fieldName.equals(ID)) + { + idAsString = fieldNode.asText(); + } + else if (fieldName.equals(TYPE)) + { + type = fieldNode.asText(); + } + else if (fieldNode.isArray()) + { + // array containing either broker children or attribute values + Iterator<JsonNode> elements = fieldNode.getElements(); + List<Object> fieldValues = null; + while (elements.hasNext()) + { + JsonNode element = elements.next(); + if (element.isObject()) + { + Class<? extends ConfiguredObject> expectedChildConfiguredObjectClass = _relationshipClasses.get(fieldName); + // assuming it is a child node + ConfigurationEntry entry = toEntry(element, expectedChildConfiguredObjectClass, entries); + childrenIds.add(entry.getId()); + } + else + { + if (fieldValues == null) + { + fieldValues = new ArrayList<Object>(); + } + fieldValues.add(toObject(element)); + } + } + if (fieldValues != null) + { + Object[] array = fieldValues.toArray(new Object[fieldValues.size()]); + attributes.put(fieldName, array); + } + } + else if (fieldNode.isObject()) + { + // ignore, in-line objects are not supported yet + } + else + { + // primitive attribute + Object value = toObject(fieldNode); + if (attributes == null) + { + attributes = new HashMap<String, Object>(); + } + attributes.put(fieldName, value); + } + } + + if (type == null) + { + if (expectedConfiguredObjectClass == null) + { + throw new IllegalConfigurationException("Type attribute is not provided for configuration entry " + parent); + } + else + { + type = expectedConfiguredObjectClass.getSimpleName(); + } + } + String name = null; + if (attributes != null) + { + name = (String) attributes.get(ATTRIBUTE_NAME); + } + if ((name == null || "".equals(name))) + { + if (expectedConfiguredObjectClass == Broker.class) + { + name = DEFAULT_BROKER_NAME; + } + else + { + throw new IllegalConfigurationException("Name attribute is not provided for configuration entry " + parent); + } + } + UUID id = null; + if (idAsString == null) + { + if (expectedConfiguredObjectClass == Broker.class) + { + id = UUIDGenerator.generateRandomUUID(); + } + else + { + id = UUIDGenerator.generateBrokerChildUUID(type, name); + } + } + else + { + try + { + id = UUID.fromString(idAsString); + } + catch (Exception e) + { + throw new IllegalConfigurationException( + "ID attribute value does not conform to UUID format for configuration entry " + parent); + } + } + ConfigurationEntry entry = new ConfigurationEntry(id, type, attributes, childrenIds, this); + if (entries.containsKey(id)) + { + throw new IllegalConfigurationException("Duplicate id is found: " + id + + "! The following configuration entries have the same id: " + entries.get(id) + ", " + entry); + } + entries.put(id, entry); + return entry; + } + + private Object toObject(JsonNode node) + { + if (node.isValueNode()) + { + if (node.isBoolean()) + { + return node.asBoolean(); + } + else if (node.isDouble()) + { + return node.asDouble(); + } + else if (node.isInt()) + { + return node.asInt(); + } + else if (node.isLong()) + { + return node.asLong(); + } + else if (node.isNull()) + { + return null; + } + else + { + return Strings.expand(node.asText()); + } + } + else if (node.isArray()) + { + return toArray(node); + } + else if (node.isObject()) + { + return toMap(node); + } + else + { + throw new IllegalConfigurationException("Unexpected node: " + node); + } + } + + private Map<String, Object> toMap(JsonNode node) + { + Map<String, Object> object = new TreeMap<String, Object>(); + Iterator<String> fieldNames = node.getFieldNames(); + while (fieldNames.hasNext()) + { + String name = fieldNames.next(); + Object value = toObject(node.get(name)); + object.put(name, value); + } + return object; + } + + private Object toArray(JsonNode node) + { + ArrayNode arrayNode = (ArrayNode) node; + Object[] array = new Object[arrayNode.size()]; + Iterator<JsonNode> elements = arrayNode.getElements(); + for (int i = 0; i < array.length; i++) + { + array[i] = toObject(elements.next()); + } + return array; + } + + /* + * Initial store location can be URL or absolute path + */ + private URL toURL(String location) + { + URL url = null; + try + { + url = new URL(location); + } + catch (MalformedURLException e) + { + File locationFile = new File(location); + url = fileToURL(locationFile); + } + return url; + } + + private void createStoreFileIfNotExist(File file) + { + File parent = file.getParentFile(); + if (!parent.exists()) + { + if (!parent.mkdirs()) + { + throw new IllegalConfigurationException("Cannot create folders " + parent); + } + } + try + { + file.createNewFile(); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot create file " + file, e); + } + } + + private void copyEntry(UUID entryId, ConfigurationEntryStore initialStore) + { + ConfigurationEntry entry = initialStore.getEntry(entryId); + if (entry != null) + { + if (_entries.containsKey(entryId)) + { + throw new IllegalConfigurationException("Duplicate id is found: " + entryId + + "! The following configuration entries have the same id: " + _entries.get(entryId) + ", " + entry); + } + _entries.put(entryId, entry); + Set<UUID> children = entry.getChildrenIds(); + if (children != null) + { + for (UUID uuid : children) + { + copyEntry(uuid, initialStore); + } + } + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java new file mode 100644 index 0000000000..e7c474bf55 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java @@ -0,0 +1,327 @@ +package org.apache.qpid.server.configuration.store; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.apache.log4j.Logger; +import org.apache.qpid.server.BrokerOptions; +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.Protocol; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.util.MapValueConverter; + +public class ManagementModeStoreHandler implements ConfigurationEntryStore +{ + private static final Logger LOGGER = Logger.getLogger(ManagementModeStoreHandler.class); + + private static final String MANAGEMENT_MODE_PORT_PREFIX = "MANAGEMENT-MODE-PORT-"; + private static final String PORT_TYPE = Port.class.getSimpleName(); + private static final String VIRTUAL_HOST_TYPE = VirtualHost.class.getSimpleName(); + private static final String ATTRIBUTE_STATE = VirtualHost.STATE; + + private final ConfigurationEntryStore _store; + private final Map<UUID, ConfigurationEntry> _cliEntries; + private final Map<UUID, Object> _quiescedEntries; + private final UUID _rootId; + + public ManagementModeStoreHandler(ConfigurationEntryStore store, BrokerOptions options) + { + ConfigurationEntry storeRoot = store.getRootEntry(); + _store = store; + _rootId = storeRoot.getId(); + _cliEntries = createPortsFromCommadLineOptions(options); + _quiescedEntries = quiesceEntries(storeRoot, options); + } + + @Override + public void open(String storeLocation) + { + throw new IllegalStateException("The store should be already opened"); + } + + @Override + public void open(String storeLocation, String initialStoreLocation) + { + throw new IllegalStateException("The store should be already opened"); + } + + @Override + public void open(String storeLocation, ConfigurationEntryStore initialStore) + { + throw new IllegalStateException("The store should be already opened"); + } + + @Override + public ConfigurationEntry getRootEntry() + { + return getEntry(_rootId); + } + + @Override + public ConfigurationEntry getEntry(UUID id) + { + synchronized (_store) + { + if (_cliEntries.containsKey(id)) + { + return _cliEntries.get(id); + } + + ConfigurationEntry entry = _store.getEntry(id); + if (_quiescedEntries.containsKey(id)) + { + entry = createEntryWithState(entry, State.QUIESCED); + } + else if (id == _rootId) + { + entry = createRootWithCLIEntries(entry); + } + return entry; + } + } + + @Override + public void save(ConfigurationEntry... entries) + { + synchronized (_store) + { + ConfigurationEntry[] entriesToSave = new ConfigurationEntry[entries.length]; + + for (int i = 0; i < entries.length; i++) + { + ConfigurationEntry entry = entries[i]; + UUID id = entry.getId(); + if (_cliEntries.containsKey(id)) + { + throw new IllegalConfigurationException("Cannot save configuration provided as command line argument:" + + entry); + } + else if (_quiescedEntries.containsKey(id)) + { + // save entry with the original state + entry = createEntryWithState(entry, _quiescedEntries.get(ATTRIBUTE_STATE)); + } + else if (_rootId.equals(id)) + { + // save root without command line entries + Set<UUID> childrenIds = new HashSet<UUID>(entry.getChildrenIds()); + if (!_cliEntries.isEmpty()) + { + childrenIds.removeAll(_cliEntries.entrySet()); + } + HashMap<String, Object> attributes = new HashMap<String, Object>(entry.getAttributes()); + entry = new ConfigurationEntry(entry.getId(), entry.getType(), attributes, childrenIds, this); + } + entriesToSave[i] = entry; + } + + _store.save(entriesToSave); + } + } + + @Override + public UUID[] remove(UUID... entryIds) + { + synchronized (_store) + { + for (UUID id : entryIds) + { + if (_cliEntries.containsKey(id)) + { + throw new IllegalConfigurationException("Cannot change configuration for command line entry:" + + _cliEntries.get(id)); + } + } + UUID[] result = _store.remove(entryIds); + for (UUID id : entryIds) + { + if (_quiescedEntries.containsKey(id)) + { + _quiescedEntries.remove(id); + } + } + return result; + } + } + + @Override + public void copyTo(String copyLocation) + { + synchronized (_store) + { + _store.copyTo(copyLocation); + } + } + + private Map<UUID, ConfigurationEntry> createPortsFromCommadLineOptions(BrokerOptions options) + { + int managementModeRmiPort = options.getManagementModeRmiPort(); + if (managementModeRmiPort < 0) + { + throw new IllegalConfigurationException("Invalid rmi port is specified: " + managementModeRmiPort); + } + int managementModeConnectorPort = options.getManagementModeConnectorPort(); + if (managementModeConnectorPort < 0) + { + throw new IllegalConfigurationException("Invalid connector port is specified: " + managementModeConnectorPort); + } + int managementModeHttpPort = options.getManagementModeHttpPort(); + if (managementModeHttpPort < 0) + { + throw new IllegalConfigurationException("Invalid http port is specified: " + managementModeHttpPort); + } + Map<UUID, ConfigurationEntry> cliEntries = new HashMap<UUID, ConfigurationEntry>(); + if (managementModeRmiPort != 0) + { + ConfigurationEntry entry = createCLIPortEntry(managementModeRmiPort, Protocol.RMI); + cliEntries.put(entry.getId(), entry); + if (managementModeConnectorPort == 0) + { + ConfigurationEntry connectorEntry = createCLIPortEntry(managementModeRmiPort + 100, Protocol.JMX_RMI); + cliEntries.put(connectorEntry.getId(), connectorEntry); + } + } + if (managementModeConnectorPort != 0) + { + ConfigurationEntry entry = createCLIPortEntry(managementModeConnectorPort, Protocol.JMX_RMI); + cliEntries.put(entry.getId(), entry); + } + if (managementModeHttpPort != 0) + { + ConfigurationEntry entry = createCLIPortEntry(managementModeHttpPort, Protocol.HTTP); + cliEntries.put(entry.getId(), entry); + } + return cliEntries; + } + + private ConfigurationEntry createCLIPortEntry(int port, Protocol protocol) + { + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(Port.PORT, port); + attributes.put(Port.PROTOCOLS, Collections.singleton(protocol)); + attributes.put(Port.NAME, MANAGEMENT_MODE_PORT_PREFIX + protocol.name()); + ConfigurationEntry portEntry = new ConfigurationEntry(UUID.randomUUID(), PORT_TYPE, attributes, + Collections.<UUID> emptySet(), this); + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Add management mode port configuration " + portEntry + " for port " + port + " and protocol " + + protocol); + } + return portEntry; + } + + private ConfigurationEntry createRootWithCLIEntries(ConfigurationEntry storeRoot) + { + Set<UUID> childrenIds = new HashSet<UUID>(storeRoot.getChildrenIds()); + if (!_cliEntries.isEmpty()) + { + childrenIds.addAll(_cliEntries.keySet()); + } + ConfigurationEntry root = new ConfigurationEntry(storeRoot.getId(), storeRoot.getType(), new HashMap<String, Object>( + storeRoot.getAttributes()), childrenIds, this); + return root; + } + + private Map<UUID, Object> quiesceEntries(ConfigurationEntry storeRoot, BrokerOptions options) + { + Map<UUID, Object> quiescedEntries = new HashMap<UUID, Object>(); + Set<UUID> childrenIds; + int managementModeRmiPort = options.getManagementModeRmiPort(); + int managementModeConnectorPort = options.getManagementModeConnectorPort(); + int managementModeHttpPort = options.getManagementModeHttpPort(); + childrenIds = storeRoot.getChildrenIds(); + for (UUID id : childrenIds) + { + ConfigurationEntry entry = _store.getEntry(id); + String entryType = entry.getType(); + Map<String, Object> attributes = entry.getAttributes(); + boolean quiesce = false; + if (VIRTUAL_HOST_TYPE.equals(entryType)) + { + quiesce = true; + } + else if (PORT_TYPE.equalsIgnoreCase(entryType)) + { + if (attributes == null) + { + throw new IllegalConfigurationException("Port attributes are not set in " + entry); + } + Set<Protocol> protocols = getPortProtocolsAttribute(attributes); + if (protocols == null) + { + quiesce = true; + } + else + { + for (Protocol protocol : protocols) + { + switch (protocol) + { + case JMX_RMI: + quiesce = managementModeConnectorPort > 0 || managementModeRmiPort > 0; + break; + case RMI: + quiesce = managementModeRmiPort > 0; + break; + case HTTP: + case HTTPS: + quiesce = managementModeHttpPort > 0; + break; + default: + quiesce = true; + } + } + } + } + if (quiesce) + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Management mode quiescing entry " + entry); + } + + // save original state + quiescedEntries.put(entry.getId(), attributes.get(ATTRIBUTE_STATE)); + } + } + return quiescedEntries; + } + + private Set<Protocol> getPortProtocolsAttribute(Map<String, Object> attributes) + { + Object object = attributes.get(Port.PROTOCOLS); + if (object == null) + { + return null; + } + return MapValueConverter.getEnumSetAttribute(Port.PROTOCOLS, attributes, Protocol.class); + } + + private ConfigurationEntry createEntryWithState(ConfigurationEntry entry, Object state) + { + Map<String, Object> attributes = new HashMap<String, Object>(entry.getAttributes()); + if (state == null) + { + attributes.remove(ATTRIBUTE_STATE); + } + else + { + attributes.put(ATTRIBUTE_STATE, state); + } + Set<UUID> originalChildren = entry.getChildrenIds(); + Set<UUID> children = null; + if (originalChildren != null) + { + children = new HashSet<UUID>(originalChildren); + } + return new ConfigurationEntry(entry.getId(), entry.getType(), attributes, children, entry.getStore()); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java new file mode 100644 index 0000000000..813702d0a6 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java @@ -0,0 +1,205 @@ +/* + * + * 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.configuration.store; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.TreeSet; +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfigurationChangeListener; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.VirtualHost; + +public class StoreConfigurationChangeListener implements ConfigurationChangeListener +{ + private ConfigurationEntryStore _store; + + public StoreConfigurationChangeListener(ConfigurationEntryStore store) + { + super(); + _store = store; + } + + @Override + public void stateChanged(ConfiguredObject object, State oldState, State newState) + { + if (newState == State.DELETED) + { + _store.remove(object.getId()); + object.removeChangeListener(this); + } + } + + @Override + public void childAdded(ConfiguredObject object, ConfiguredObject child) + { + // exclude VirtualHost children from storing in broker store + if (!(object instanceof VirtualHost)) + { + child.addChangeListener(this); + ConfigurationEntry parentEntry = toConfigurationEntry(object); + ConfigurationEntry childEntry = toConfigurationEntry(child); + _store.save(parentEntry, childEntry); + } + + } + + @Override + public void childRemoved(ConfiguredObject object, ConfiguredObject child) + { + _store.save(toConfigurationEntry(object)); + } + + @Override + public void attributeSet(ConfiguredObject object, String attrinuteName, Object oldAttributeValue, Object newAttributeValue) + { + _store.save(toConfigurationEntry(object)); + } + + private ConfigurationEntry toConfigurationEntry(ConfiguredObject object) + { + Class<? extends ConfiguredObject> objectType = getConfiguredObjectType(object); + Set<UUID> childrenIds = getChildernIds(object, objectType); + ConfigurationEntry entry = new ConfigurationEntry(object.getId(), objectType.getSimpleName(), + object.getActualAttributes(), childrenIds, _store); + return entry; + } + + private Set<UUID> getChildernIds(ConfiguredObject object, Class<? extends ConfiguredObject> objectType) + { + // Virtual Host children's IDs should not be stored in broker store + if (object instanceof VirtualHost) + { + return Collections.emptySet(); + } + Set<UUID> childrenIds = new TreeSet<UUID>(); + Collection<Class<? extends ConfiguredObject>> childClasses = Model.getInstance().getChildTypes(objectType); + if (childClasses != null) + { + for (Class<? extends ConfiguredObject> childClass : childClasses) + { + Collection<? extends ConfiguredObject> children = object.getChildren(childClass); + if (children != null) + { + for (ConfiguredObject childObject : children) + { + childrenIds.add(childObject.getId()); + } + } + } + } + return childrenIds; + } + + private Class<? extends ConfiguredObject> getConfiguredObjectType(ConfiguredObject object) + { + if (object instanceof Broker) + { + return Broker.class; + } + return getConfiguredObjectTypeFromImplementedInterfaces(object.getClass()); + } + + @SuppressWarnings("unchecked") + private Class<? extends ConfiguredObject> getConfiguredObjectTypeFromImplementedInterfaces(Class<?> objectClass) + { + // get all implemented interfaces extending ConfiguredObject + Set<Class<?>> interfaces = getImplementedInterfacesExtendingSuper(objectClass, ConfiguredObject.class); + + if (interfaces.size() == 0) + { + throw new RuntimeException("Can not identify the configured object type"); + } + + if (interfaces.size() == 1) + { + return (Class<? extends ConfiguredObject>)interfaces.iterator().next(); + } + + Set<Class<?>> superInterfaces = new HashSet<Class<?>>(); + + // find all super interfaces + for (Class<?> interfaceClass : interfaces) + { + for (Class<?> interfaceClass2 : interfaces) + { + if (interfaceClass != interfaceClass2) + { + if (interfaceClass.isAssignableFrom(interfaceClass2)) + { + superInterfaces.add(interfaceClass); + } + } + } + } + + // remove super interfaces + for (Class<?> superInterface : superInterfaces) + { + interfaces.remove(superInterface); + } + + if (interfaces.size() == 1) + { + return (Class<? extends ConfiguredObject>)interfaces.iterator().next(); + } + else + { + throw new RuntimeException("Can not identify the configured object type as an it implements" + + " more than one configured object interfaces: " + interfaces); + } + + } + + private Set<Class<?>> getImplementedInterfacesExtendingSuper(Class<?> classInstance, Class<?> superInterface) + { + Set<Class<?>> interfaces = new HashSet<Class<?>>(); + Class<?>[] classInterfaces = classInstance.getInterfaces(); + for (Class<?> interfaceClass : classInterfaces) + { + if (interfaceClass!= superInterface && superInterface.isAssignableFrom(interfaceClass)) + { + interfaces.add(interfaceClass); + } + } + Class<?> superClass = classInstance.getSuperclass(); + if (superClass != null) + { + Set<Class<?>> superClassInterfaces = getImplementedInterfacesExtendingSuper(superClass, superInterface); + interfaces.addAll(superClassInterfaces); + } + return interfaces; + } + + @Override + public String toString() + { + return "StoreConfigurationChangeListener [store=" + _store + "]"; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventClass.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/factory/JsonConfigurationStoreFactory.java index ec471f18e8..e37e58b840 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventClass.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/factory/JsonConfigurationStoreFactory.java @@ -18,25 +18,24 @@ * under the License. * */ -package org.apache.qpid.qmf; +package org.apache.qpid.server.configuration.store.factory; -import java.util.List; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.ConfigurationStoreFactory; +import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore; -public abstract class QMFEventClass extends QMFClass +public class JsonConfigurationStoreFactory implements ConfigurationStoreFactory { - public QMFEventClass(String name, - byte[] schemaHash, - List<QMFProperty> properties, - List<QMFStatistic> statistics, List<QMFMethod> methods) + @Override + public ConfigurationEntryStore createStore() { - super(Type.EVENT, name, schemaHash, properties, statistics, methods); + return new JsonConfigurationEntryStore(); } - public QMFEventClass(String name, byte[] schemaHash) + @Override + public String getStoreType() { - super(Type.EVENT, name, schemaHash); + return JsonConfigurationEntryStore.STORE_TYPE; } - abstract public QMFEventSeverity getSeverity(); - -}
\ No newline at end of file +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/ChangeStateTask.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/ChangeStateTask.java new file mode 100644 index 0000000000..b6de1e136a --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/ChangeStateTask.java @@ -0,0 +1,67 @@ +/* + * + * 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.configuration.updater; + +import java.util.concurrent.Callable; + +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.State; + +public final class ChangeStateTask implements Callable<State> +{ + private ConfiguredObject _object; + private State _expectedState; + private State _desiredState; + + public ChangeStateTask(ConfiguredObject object, State expectedState, State desiredState) + { + _object = object; + _expectedState = expectedState; + _desiredState = desiredState; + } + + public ConfiguredObject getObject() + { + return _object; + } + + public State getExpectedState() + { + return _expectedState; + } + + public State getDesiredState() + { + return _desiredState; + } + + @Override + public State call() + { + return _object.setDesiredState(_expectedState, _desiredState); + } + + @Override + public String toString() + { + return "ChangeStateTask [object=" + _object + ", expectedState=" + _expectedState + ", desiredState=" + _desiredState + "]"; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/CreateChildTask.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/CreateChildTask.java new file mode 100644 index 0000000000..d3a8f5b797 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/CreateChildTask.java @@ -0,0 +1,78 @@ +/* + * + * 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.configuration.updater; + +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.Callable; + +import org.apache.qpid.server.model.ConfiguredObject; + +public final class CreateChildTask implements Callable<ConfiguredObject> +{ + private ConfiguredObject _object; + private Class<? extends ConfiguredObject> _childClass; + private Map<String, Object> _attributes; + private ConfiguredObject[] _otherParents; + + public CreateChildTask(ConfiguredObject object, Class<? extends ConfiguredObject> childClass, Map<String, Object> attributes, + ConfiguredObject... otherParents) + { + _object = object; + _childClass = childClass; + _attributes = attributes; + _otherParents = otherParents; + } + + public ConfiguredObject getObject() + { + return _object; + } + + public Class<? extends ConfiguredObject> getChildClass() + { + return _childClass; + } + + public Map<String, Object> getAttributes() + { + return _attributes; + } + + public ConfiguredObject[] getOtherParents() + { + return _otherParents; + } + + @Override + public ConfiguredObject call() + { + return _object.createChild(_childClass, _attributes, _otherParents); + } + + @Override + public String toString() + { + return "CreateChildTask [object=" + _object + ", childClass=" + _childClass + ", attributes=" + _attributes + + ", otherParents=" + Arrays.toString(_otherParents) + "]"; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/SetAttributeTask.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/SetAttributeTask.java new file mode 100644 index 0000000000..94649434e6 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/SetAttributeTask.java @@ -0,0 +1,74 @@ +/* + * + * 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.configuration.updater; + +import java.util.concurrent.Callable; + +import org.apache.qpid.server.model.ConfiguredObject; + +public final class SetAttributeTask implements Callable<Object> +{ + private ConfiguredObject _object; + private String _attributeName; + private Object _expectedValue; + private Object _desiredValue; + + public SetAttributeTask(ConfiguredObject object, String attributeName, Object expectedValue, Object desiredValue) + { + _object = object; + _attributeName = attributeName; + _expectedValue = expectedValue; + _desiredValue = desiredValue; + } + + public ConfiguredObject getObject() + { + return _object; + } + + public String getAttributeName() + { + return _attributeName; + } + + public Object getExpectedValue() + { + return _expectedValue; + } + + public Object getDesiredValue() + { + return _desiredValue; + } + + @Override + public Object call() + { + return _object.setAttribute(_attributeName, _expectedValue, _desiredValue); + } + + @Override + public String toString() + { + return "SetAttributeTask [object=" + _object + ", attributeName=" + _attributeName + ", expectedValue=" + _expectedValue + + ", desiredValue=" + _desiredValue + "]"; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java new file mode 100644 index 0000000000..671104d413 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java @@ -0,0 +1,324 @@ +/* + * + * 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.configuration.updater; + +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.RunnableFuture; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import javax.security.auth.Subject; + +import org.apache.log4j.Logger; +import org.apache.qpid.server.logging.LogActor; +import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.security.SecurityManager; + +public class TaskExecutor +{ + private static final String TASK_EXECUTION_THREAD_NAME = "Broker-Configuration-Thread"; + private static final Logger LOGGER = Logger.getLogger(TaskExecutor.class); + + private volatile Thread _taskThread; + private final AtomicReference<State> _state; + private volatile ExecutorService _executor; + + public TaskExecutor() + { + _state = new AtomicReference<State>(State.INITIALISING); + } + + public State getState() + { + return _state.get(); + } + + public void start() + { + if (_state.compareAndSet(State.INITIALISING, State.ACTIVE)) + { + LOGGER.debug("Starting task executor"); + _executor = Executors.newFixedThreadPool(1, new ThreadFactory() + { + @Override + public Thread newThread(Runnable r) + { + _taskThread = new Thread(r, TASK_EXECUTION_THREAD_NAME); + return _taskThread; + } + }); + LOGGER.debug("Task executor is started"); + } + } + + public void stopImmediately() + { + if (_state.compareAndSet(State.ACTIVE, State.STOPPED)) + { + ExecutorService executor = _executor; + if (executor != null) + { + LOGGER.debug("Stopping task executor immediately"); + List<Runnable> cancelledTasks = executor.shutdownNow(); + if (cancelledTasks != null) + { + for (Runnable runnable : cancelledTasks) + { + if (runnable instanceof RunnableFuture<?>) + { + ((RunnableFuture<?>) runnable).cancel(true); + } + } + } + _executor = null; + _taskThread = null; + LOGGER.debug("Task executor was stopped immediately. Number of unfinished tasks: " + cancelledTasks.size()); + } + } + } + + public void stop() + { + if (_state.compareAndSet(State.ACTIVE, State.STOPPED)) + { + ExecutorService executor = _executor; + if (executor != null) + { + LOGGER.debug("Stopping task executor"); + executor.shutdown(); + _executor = null; + _taskThread = null; + LOGGER.debug("Task executor is stopped"); + } + } + } + + Future<?> submit(Callable<?> task) + { + checkState(); + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Submitting task: " + task); + } + Future<?> future = null; + if (isTaskExecutorThread()) + { + Object result = executeTaskAndHandleExceptions(task); + return new ImmediateFuture(result); + } + else + { + future = _executor.submit(new CallableWrapper(task)); + } + return future; + } + + public Object submitAndWait(Callable<?> task) throws CancellationException + { + try + { + Future<?> future = submit(task); + return future.get(); + } + catch (InterruptedException e) + { + throw new RuntimeException("Task execution was interrupted: " + task, e); + } + catch (ExecutionException e) + { + Throwable cause = e.getCause(); + if (cause instanceof RuntimeException) + { + throw (RuntimeException) cause; + } + else if (cause instanceof Exception) + { + throw new RuntimeException("Failed to execute user task: " + task, cause); + } + else if (cause instanceof Error) + { + throw (Error) cause; + } + else + { + throw new RuntimeException("Failed to execute user task: " + task, cause); + } + } + } + + public boolean isTaskExecutorThread() + { + return Thread.currentThread() == _taskThread; + } + + private void checkState() + { + if (_state.get() != State.ACTIVE) + { + throw new IllegalStateException("Task executor is not in ACTIVE state"); + } + } + + private Object executeTaskAndHandleExceptions(Callable<?> userTask) + { + try + { + return executeTask(userTask); + } + catch (Exception e) + { + if (e instanceof RuntimeException) + { + throw (RuntimeException) e; + } + throw new RuntimeException("Failed to execute user task: " + userTask, e); + } + } + + private Object executeTask(Callable<?> userTask) throws Exception + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Performing task " + userTask); + } + Object result = userTask.call(); + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Task " + userTask + " is performed successfully with result:" + result); + } + return result; + } + + private class CallableWrapper implements Callable<Object> + { + private Callable<?> _userTask; + private Subject _securityManagerSubject; + private LogActor _actor; + private Subject _contextSubject; + + public CallableWrapper(Callable<?> userWork) + { + _userTask = userWork; + _securityManagerSubject = SecurityManager.getThreadSubject(); + _actor = CurrentActor.get(); + _contextSubject = Subject.getSubject(AccessController.getContext()); + } + + @Override + public Object call() throws Exception + { + SecurityManager.setThreadSubject(_securityManagerSubject); + CurrentActor.set(_actor); + + try + { + Object result = null; + try + { + result = Subject.doAs(_contextSubject, new PrivilegedExceptionAction<Object>() + { + @Override + public Object run() throws Exception + { + return executeTask(_userTask); + } + }); + } + catch (PrivilegedActionException e) + { + throw e.getException(); + } + return result; + } + finally + { + try + { + CurrentActor.remove(); + } + catch (Exception e) + { + LOGGER.warn("Unxpected exception on current actor removal", e); + } + try + { + SecurityManager.setThreadSubject(null); + } + catch (Exception e) + { + LOGGER.warn("Unxpected exception on nullifying of subject for a security manager", e); + } + } + } + } + + private class ImmediateFuture implements Future<Object> + { + private Object _result; + + public ImmediateFuture(Object result) + { + super(); + this._result = result; + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) + { + return false; + } + + @Override + public boolean isCancelled() + { + return false; + } + + @Override + public boolean isDone() + { + return true; + } + + @Override + public Object get() + { + return _result; + } + + @Override + public Object get(long timeout, TimeUnit unit) + { + return get(); + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java index 512a8c6996..246e056f0b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java @@ -23,14 +23,12 @@ package org.apache.qpid.server.exchange; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.ExchangeConfigType; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.messages.ExchangeMessages; import org.apache.qpid.server.logging.subjects.ExchangeLogSubject; import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.QueueRegistry; @@ -86,8 +84,6 @@ public abstract class AbstractExchange implements Exchange //TODO : persist creation time private long _createTime = System.currentTimeMillis(); - private UUID _qmfId; - public AbstractExchange(final ExchangeType<? extends Exchange> type) { _type = type; @@ -113,19 +109,12 @@ public abstract class AbstractExchange implements Exchange _ticket = ticket; _id = id; - _qmfId = getConfigStore().createId(); - getConfigStore().addConfiguredObject(this); _logSubject = new ExchangeLogSubject(this, this.getVirtualHost()); // Log Exchange creation CurrentActor.get().message(ExchangeMessages.CREATED(String.valueOf(getTypeShortString()), String.valueOf(name), durable)); } - public ConfigStore getConfigStore() - { - return getVirtualHost().getConfigStore(); - } - public boolean isDurable() { return _durable; @@ -146,7 +135,6 @@ public abstract class AbstractExchange implements Exchange if(_closed.compareAndSet(false,true)) { - getConfigStore().removeConfiguredObject(this); if(_alternateExchange != null) { _alternateExchange.removeReference(this); @@ -298,29 +286,11 @@ public abstract class AbstractExchange implements Exchange return _id; } - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public ExchangeConfigType getConfigType() - { - return ExchangeConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return _virtualHost; - } - public long getBindingCount() { return getBindings().size(); } - - public final List<? extends BaseQueue> route(final InboundMessage message) { _receivedMessageCount.incrementAndGet(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java index 5058f91995..5e6e36d330 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java @@ -27,10 +27,9 @@ import org.apache.qpid.AMQSecurityException; import org.apache.qpid.AMQUnknownExchangeType; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.qmf.ManagementExchange; -import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.plugin.ExchangeType; +import org.apache.qpid.server.plugin.QpidServiceLoader; import org.apache.qpid.server.virtualhost.VirtualHost; import java.util.ArrayList; @@ -41,42 +40,72 @@ import java.util.UUID; public class DefaultExchangeFactory implements ExchangeFactory { - private static final Logger _logger = Logger.getLogger(DefaultExchangeFactory.class); public static final String DEFAULT_DLE_NAME_SUFFIX = "_DLE"; - private Map<AMQShortString, ExchangeType<? extends Exchange>> _exchangeClassMap = new HashMap<AMQShortString, ExchangeType<? extends Exchange>>(); + private static final Logger LOGGER = Logger.getLogger(DefaultExchangeFactory.class); + + private static final AMQShortString[] BASE_EXCHANGE_TYPES = + new AMQShortString[]{ExchangeDefaults.DIRECT_EXCHANGE_CLASS, + ExchangeDefaults.FANOUT_EXCHANGE_CLASS, + ExchangeDefaults.HEADERS_EXCHANGE_CLASS, + ExchangeDefaults.TOPIC_EXCHANGE_CLASS}; + private final VirtualHost _host; + private Map<AMQShortString, ExchangeType<? extends Exchange>> _exchangeClassMap = new HashMap<AMQShortString, ExchangeType<? extends Exchange>>(); public DefaultExchangeFactory(VirtualHost host) { _host = host; - registerExchangeType(DirectExchange.TYPE); - registerExchangeType(TopicExchange.TYPE); - registerExchangeType(HeadersExchange.TYPE); - registerExchangeType(FanoutExchange.TYPE); - registerExchangeType(ManagementExchange.TYPE); + + @SuppressWarnings("rawtypes") + Iterable<ExchangeType> exchangeTypes = loadExchangeTypes(); + for (ExchangeType<?> exchangeType : exchangeTypes) + { + AMQShortString typeName = exchangeType.getName(); + + if(LOGGER.isDebugEnabled()) + { + LOGGER.debug("Registering exchange type '" + typeName + "' using class '" + exchangeType.getClass().getName() + "'"); + } + + if(_exchangeClassMap.containsKey(typeName)) + { + ExchangeType<?> existingType = _exchangeClassMap.get(typeName); + + throw new IllegalStateException("ExchangeType with type name '" + typeName + "' is already registered using class '" + + existingType.getClass().getName() + "', can not register class '" + + exchangeType.getClass().getName() + "'"); + } + + _exchangeClassMap.put(typeName, exchangeType); + } + + for(AMQShortString type : BASE_EXCHANGE_TYPES) + { + if(!_exchangeClassMap.containsKey(type)) + { + throw new IllegalStateException("Did not find expected exchange type: " + type.asString()); + } + } } - public void registerExchangeType(ExchangeType<? extends Exchange> type) + @SuppressWarnings("rawtypes") + protected Iterable<ExchangeType> loadExchangeTypes() { - _exchangeClassMap.put(type.getName(), type); + return new QpidServiceLoader<ExchangeType>().atLeastOneInstanceOf(ExchangeType.class); } public Collection<ExchangeType<? extends Exchange>> getRegisteredTypes() { return _exchangeClassMap.values(); } - + public Collection<ExchangeType<? extends Exchange>> getPublicCreatableTypes() { Collection<ExchangeType<? extends Exchange>> publicTypes = new ArrayList<ExchangeType<? extends Exchange>>(); publicTypes.addAll(_exchangeClassMap.values()); - //Remove the ManagementExchange type if present, as these - //are private and cannot be created by external means - publicTypes.remove(ManagementExchange.TYPE); - return publicTypes; } @@ -120,42 +149,4 @@ public class DefaultExchangeFactory implements ExchangeFactory Exchange e = exchType.newInstance(id, _host, exchange, durable, ticket, autoDelete); return e; } - - public void initialise(VirtualHostConfiguration hostConfig) - { - - if (hostConfig == null) - { - return; - } - - for(Object className : hostConfig.getCustomExchanges()) - { - try - { - ExchangeType<?> exchangeType = ApplicationRegistry.getInstance().getPluginManager().getExchanges().get(String.valueOf(className)); - if (exchangeType == null) - { - _logger.error("No such custom exchange class found: \""+String.valueOf(className)+"\""); - continue; - } - Class<? extends ExchangeType> exchangeTypeClass = exchangeType.getClass(); - ExchangeType<? extends ExchangeType> type = exchangeTypeClass.newInstance(); - registerExchangeType(type); - } - catch (ClassCastException classCastEx) - { - _logger.error("No custom exchange class: \""+String.valueOf(className)+"\" cannot be registered as it does not extend class \""+ExchangeType.class+"\""); - } - catch (IllegalAccessException e) - { - _logger.error("Cannot create custom exchange class: \""+String.valueOf(className)+"\"",e); - } - catch (InstantiationException e) - { - _logger.error("Cannot create custom exchange class: \""+String.valueOf(className)+"\"",e); - } - } - - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java index 07813b073b..9cce8d640b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java @@ -26,6 +26,7 @@ import org.apache.qpid.AMQSecurityException; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.virtualhost.VirtualHost; diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java index 92326412c1..fc6ce15bc4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java @@ -20,30 +20,22 @@ */ package org.apache.qpid.server.exchange; -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.virtualhost.VirtualHost; -import javax.management.JMException; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; public class DirectExchange extends AbstractExchange { - private static final Logger _logger = Logger.getLogger(DirectExchange.class); - private static final class BindingSet { private CopyOnWriteArraySet<Binding> _bindings = new CopyOnWriteArraySet<Binding>(); @@ -55,7 +47,6 @@ public class DirectExchange extends AbstractExchange recalculateQueues(); } - public synchronized void removeBinding(Binding binding) { _bindings.remove(binding); @@ -91,36 +82,7 @@ public class DirectExchange extends AbstractExchange private final ConcurrentHashMap<String, BindingSet> _bindingsByKey = new ConcurrentHashMap<String, BindingSet>(); - public static final ExchangeType<DirectExchange> TYPE = new ExchangeType<DirectExchange>() - { - - public AMQShortString getName() - { - return ExchangeDefaults.DIRECT_EXCHANGE_CLASS; - } - - public Class<DirectExchange> getExchangeClass() - { - return DirectExchange.class; - } - - public DirectExchange newInstance(UUID id, VirtualHost host, - AMQShortString name, - boolean durable, - int ticket, - boolean autoDelete) throws AMQException - { - DirectExchange exch = new DirectExchange(); - exch.initialise(id, host,name,durable,ticket,autoDelete); - return exch; - } - - public AMQShortString getDefaultExchangeName() - { - return ExchangeDefaults.DIRECT_EXCHANGE_NAME; - } - }; - + public static final ExchangeType<DirectExchange> TYPE = new DirectExchangeType(); public DirectExchange() { diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java new file mode 100644 index 0000000000..096d5265ed --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java @@ -0,0 +1,53 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.exchange; + +import java.util.UUID; + +import org.apache.qpid.AMQException; +import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.plugin.ExchangeType; +import org.apache.qpid.server.virtualhost.VirtualHost; + +public class DirectExchangeType implements ExchangeType<DirectExchange> +{ + public AMQShortString getName() + { + return ExchangeDefaults.DIRECT_EXCHANGE_CLASS; + } + + public DirectExchange newInstance(UUID id, VirtualHost host, + AMQShortString name, + boolean durable, + int ticket, + boolean autoDelete) throws AMQException + { + DirectExchange exch = new DirectExchange(); + exch.initialise(id, host,name,durable,ticket,autoDelete); + return exch; + } + + public AMQShortString getDefaultExchangeName() + { + return ExchangeDefaults.DIRECT_EXCHANGE_NAME; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java index 762686e68d..4bafb04c33 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java @@ -26,8 +26,8 @@ import org.apache.qpid.AMQSecurityException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.ExchangeConfig; import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.virtualhost.VirtualHost; @@ -38,9 +38,23 @@ import java.util.List; import java.util.Map; import java.util.UUID; -public interface Exchange extends ExchangeReferrer, ExchangeConfig +public interface Exchange extends ExchangeReferrer { + String getName(); + + ExchangeType getType(); + + long getBindingCount(); + + long getByteDrops(); + + long getByteReceives(); + + long getMsgDrops(); + + long getMsgReceives(); + public interface BindingListener { void bindingAdded(Exchange exchange, Binding binding); diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java index aae4ae89bb..e602d476d9 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java @@ -22,7 +22,7 @@ package org.apache.qpid.server.exchange; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.configuration.VirtualHostConfiguration; +import org.apache.qpid.server.plugin.ExchangeType; import java.util.Collection; import java.util.UUID; @@ -34,8 +34,6 @@ public interface ExchangeFactory int ticket) throws AMQException; - void initialise(VirtualHostConfiguration hostConfig); - Collection<ExchangeType<? extends Exchange>> getRegisteredTypes(); Collection<ExchangeType<? extends Exchange>> getPublicCreatableTypes(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeInitialiser.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeInitialiser.java index ba4f57a8e0..edb476f3aa 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeInitialiser.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeInitialiser.java @@ -24,6 +24,7 @@ package org.apache.qpid.server.exchange; import org.apache.qpid.AMQException; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.store.DurableConfigurationStore; public class ExchangeInitialiser diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java index 5f4998f77f..8c433ce985 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java @@ -22,19 +22,15 @@ package org.apache.qpid.server.exchange; import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.virtualhost.VirtualHost; -import javax.management.JMException; import java.util.ArrayList; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; public class FanoutExchange extends AbstractExchange @@ -48,35 +44,7 @@ public class FanoutExchange extends AbstractExchange */ private final ConcurrentHashMap<AMQQueue,Integer> _queues = new ConcurrentHashMap<AMQQueue,Integer>(); - public static final ExchangeType<FanoutExchange> TYPE = new ExchangeType<FanoutExchange>() - { - - public AMQShortString getName() - { - return ExchangeDefaults.FANOUT_EXCHANGE_CLASS; - } - - public Class<FanoutExchange> getExchangeClass() - { - return FanoutExchange.class; - } - - public FanoutExchange newInstance(UUID id, VirtualHost host, - AMQShortString name, - boolean durable, - int ticket, - boolean autoDelete) throws AMQException - { - FanoutExchange exch = new FanoutExchange(); - exch.initialise(id, host, name, durable, ticket, autoDelete); - return exch; - } - - public AMQShortString getDefaultExchangeName() - { - return ExchangeDefaults.FANOUT_EXCHANGE_NAME; - } - }; + public static final ExchangeType<FanoutExchange> TYPE = new FanoutExchangeType(); public FanoutExchange() { diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeType.java index 34b2a851dc..0371a363de 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeType.java @@ -18,28 +18,34 @@ * under the License. * */ +package org.apache.qpid.server.exchange; -package org.apache.qpid.qmf; +import java.util.UUID; +import org.apache.qpid.AMQException; +import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBEncoder; -public class QMFBrokerResponseCommand extends QMFCommand +public class FanoutExchangeType implements ExchangeType<FanoutExchange> { - private QMFCommandHeader _header; - private VirtualHost _virtualHost; + public AMQShortString getName() + { + return ExchangeDefaults.FANOUT_EXCHANGE_CLASS; + } - public QMFBrokerResponseCommand(QMFBrokerRequestCommand qmfBrokerRequestCommand, VirtualHost virtualHost) + public FanoutExchange newInstance(UUID id, VirtualHost host, AMQShortString name, + boolean durable, int ticket, boolean autoDelete) + throws AMQException { - super( new QMFCommandHeader(qmfBrokerRequestCommand.getHeader().getVersion(), - qmfBrokerRequestCommand.getHeader().getSeq(), - QMFOperation.BROKER_RESPONSE)); - _virtualHost = virtualHost; + FanoutExchange exch = new FanoutExchange(); + exch.initialise(id, host, name, durable, ticket, autoDelete); + return exch; } - public void encode(BBEncoder encoder) + public AMQShortString getDefaultExchangeName() { - super.encode(encoder); - encoder.writeUuid(_virtualHost.getBrokerId()); + return ExchangeDefaults.FANOUT_EXCHANGE_NAME; } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java index 6bad59c2ae..746c8ac6bc 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java @@ -22,22 +22,18 @@ package org.apache.qpid.server.exchange; import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.message.AMQMessageHeader; import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.virtualhost.VirtualHost; -import javax.management.JMException; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.Map; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; @@ -81,40 +77,12 @@ public class HeadersExchange extends AbstractExchange new CopyOnWriteArrayList<HeadersBinding>(); - public static final ExchangeType<HeadersExchange> TYPE = new ExchangeType<HeadersExchange>() - { - - public AMQShortString getName() - { - return ExchangeDefaults.HEADERS_EXCHANGE_CLASS; - } - - public Class<HeadersExchange> getExchangeClass() - { - return HeadersExchange.class; - } - - public HeadersExchange newInstance(UUID id, VirtualHost host, AMQShortString name, boolean durable, int ticket, - boolean autoDelete) throws AMQException - { - HeadersExchange exch = new HeadersExchange(); - - exch.initialise(id, host, name, durable, ticket, autoDelete); - return exch; - } - - public AMQShortString getDefaultExchangeName() - { - - return ExchangeDefaults.HEADERS_EXCHANGE_NAME; - } - }; + public static final ExchangeType<HeadersExchange> TYPE = new HeadersExchangeType(); public HeadersExchange() { super(TYPE); } - public ArrayList<BaseQueue> doRoute(InboundMessage payload) diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostHouseKeepingPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeType.java index 191f8041d2..ed4d57d0f8 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostHouseKeepingPlugin.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeType.java @@ -18,44 +18,35 @@ * under the License. * */ -package org.apache.qpid.server.virtualhost.plugins; +package org.apache.qpid.server.exchange; -import org.apache.log4j.Logger; +import java.util.UUID; -import org.apache.qpid.server.virtualhost.HouseKeepingTask; +import org.apache.qpid.AMQException; +import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.virtualhost.VirtualHost; -import java.util.concurrent.TimeUnit; - -public abstract class VirtualHostHouseKeepingPlugin extends HouseKeepingTask implements VirtualHostPlugin +public class HeadersExchangeType implements ExchangeType<HeadersExchange> { - private final Logger _logger = Logger.getLogger(getClass()); - - public VirtualHostHouseKeepingPlugin(VirtualHost vhost) + public AMQShortString getName() { - super(vhost); + return ExchangeDefaults.HEADERS_EXCHANGE_CLASS; } + public HeadersExchange newInstance(UUID id, VirtualHost host, AMQShortString name, boolean durable, int ticket, + boolean autoDelete) throws AMQException + { + HeadersExchange exch = new HeadersExchange(); - /** - * Long value representing the delay between repeats - * - * @return - */ - public abstract long getDelay(); - - /** - * Option to specify what the delay value represents - * - * @return - * - * @see java.util.concurrent.TimeUnit for valid value. - */ - public abstract TimeUnit getTimeUnit(); - + exch.initialise(id, host, name, durable, ticket, autoDelete); + return exch; + } - protected Logger getLogger() + public AMQShortString getDefaultExchangeName() { - return _logger; + + return ExchangeDefaults.HEADERS_EXCHANGE_NAME; } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java index 0ce16bd3f7..6d548be508 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java @@ -27,15 +27,11 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; -import java.util.UUID; import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; -import javax.management.JMException; import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; import org.apache.qpid.AMQInvalidArgumentException; import org.apache.qpid.common.AMQPFilterTypes; -import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.filter.SelectorParsingException; import org.apache.qpid.filter.selector.ParseException; import org.apache.qpid.filter.selector.TokenMgrError; @@ -49,44 +45,15 @@ import org.apache.qpid.server.exchange.topic.TopicParser; import org.apache.qpid.server.filter.JMSSelectorFilter; import org.apache.qpid.server.filter.MessageFilter; import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.Filterable; -import org.apache.qpid.server.virtualhost.VirtualHost; public class TopicExchange extends AbstractExchange { - - public static final ExchangeType<TopicExchange> TYPE = new ExchangeType<TopicExchange>() - { - - public AMQShortString getName() - { - return ExchangeDefaults.TOPIC_EXCHANGE_CLASS; - } - - public Class<TopicExchange> getExchangeClass() - { - return TopicExchange.class; - } - - public TopicExchange newInstance(UUID id, VirtualHost host, - AMQShortString name, - boolean durable, - int ticket, - boolean autoDelete) throws AMQException - { - TopicExchange exch = new TopicExchange(); - exch.initialise(id, host, name, durable, ticket, autoDelete); - return exch; - } - - public AMQShortString getDefaultExchangeName() - { - return ExchangeDefaults.TOPIC_EXCHANGE_NAME; - } - }; + public static final ExchangeType<TopicExchange> TYPE = new TopicExchangeType(); private static final Logger _logger = Logger.getLogger(TopicExchange.class); @@ -291,7 +258,7 @@ public class TopicExchange extends AbstractExchange public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue) { - Binding binding = new Binding(null, null, routingKey.toString(), queue, this, FieldTable.convertToMap(arguments)); + Binding binding = new Binding(null, routingKey.toString(), queue, this, FieldTable.convertToMap(arguments)); if (arguments == null) { @@ -314,7 +281,7 @@ public class TopicExchange extends AbstractExchange public boolean isBound(String bindingKey, Map<String, Object> arguments, AMQQueue queue) { - Binding binding = new Binding(null, null, bindingKey, queue, this, arguments); + Binding binding = new Binding(null, bindingKey, queue, this, arguments); if (arguments == null) { return _bindings.containsKey(binding); diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java new file mode 100644 index 0000000000..25a3549e61 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java @@ -0,0 +1,53 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.exchange; + +import java.util.UUID; + +import org.apache.qpid.AMQException; +import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.plugin.ExchangeType; +import org.apache.qpid.server.virtualhost.VirtualHost; + +public class TopicExchangeType implements ExchangeType<TopicExchange> +{ + public AMQShortString getName() + { + return ExchangeDefaults.TOPIC_EXCHANGE_CLASS; + } + + public TopicExchange newInstance(UUID id, VirtualHost host, + AMQShortString name, + boolean durable, + int ticket, + boolean autoDelete) throws AMQException + { + TopicExchange exch = new TopicExchange(); + exch.initialise(id, host, name, durable, ticket, autoDelete); + return exch; + } + + public AMQShortString getDefaultExchangeName() + { + return ExchangeDefaults.TOPIC_EXCHANGE_NAME; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java b/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java deleted file mode 100644 index 7eb476b15a..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java +++ /dev/null @@ -1,913 +0,0 @@ -/* - * - * 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.federation; - -import org.apache.qpid.AMQException; -import org.apache.qpid.AMQStoreException; -import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.BridgeConfig; -import org.apache.qpid.server.configuration.BridgeConfigType; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.flow.FlowCreditManager_0_10; -import org.apache.qpid.server.flow.WindowCreditManager; -import org.apache.qpid.server.message.MessageMetaData_0_10; -import org.apache.qpid.server.message.MessageTransferMessage; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.queue.AMQQueueFactory; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.store.MessageStore; -import org.apache.qpid.server.store.StoredMessage; -import org.apache.qpid.server.subscription.SubscriptionFactoryImpl; -import org.apache.qpid.server.subscription.Subscription_0_10; -import org.apache.qpid.server.transport.ServerSession; -import org.apache.qpid.server.txn.AutoCommitTransaction; -import org.apache.qpid.server.txn.ServerTransaction; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.DeliveryProperties; -import org.apache.qpid.transport.MessageAcceptMode; -import org.apache.qpid.transport.MessageAcquireMode; -import org.apache.qpid.transport.MessageCreditUnit; -import org.apache.qpid.transport.MessageFlowMode; -import org.apache.qpid.transport.MessageReject; -import org.apache.qpid.transport.MessageRejectCode; -import org.apache.qpid.transport.MessageTransfer; -import org.apache.qpid.transport.Option; -import org.apache.qpid.transport.RangeSet; -import org.apache.qpid.transport.RangeSetFactory; -import org.apache.qpid.transport.Session; -import org.apache.qpid.transport.SessionException; -import org.apache.qpid.transport.SessionListener; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -public class Bridge implements BridgeConfig -{ - private static final String DURABLE = "durable"; - private static final String DYNAMIC = "dynamic"; - private static final String SRC_IS_QUEUE = "srcIsQueue"; - private static final String SRC_IS_LOCAL = "srcIsLocal"; - private static final String SOURCE = "source"; - private static final String DESTINATION = "destination"; - private static final String KEY = "key"; - private static final String TAG = "tag"; - private static final String EXCLUDES = "excludes"; - private final boolean _durable; - private final boolean _dynamic; - private final boolean _queueBridge; - private final boolean _localSource; - private final String _source; - private final String _destination; - private final String _key; - private final String _tag; - private final String _excludes; - private final BrokerLink _link; - private UUID _qmfId; - private long _createTime = System.currentTimeMillis(); - - private Session _session; - - private BridgeImpl _delegate; - - private final int _bridgeNo; - private AutoCommitTransaction _transaction; - - public Bridge(final BrokerLink brokerLink, - final int bridgeNo, - final boolean durable, - final boolean dynamic, - final boolean srcIsQueue, - final boolean srcIsLocal, - final String src, - final String dest, - final String key, - final String tag, - final String excludes) - { - _link = brokerLink; - _bridgeNo = bridgeNo; - _durable = durable; - _dynamic = dynamic; - _queueBridge = srcIsQueue; - _localSource = srcIsLocal; - _source = src; - _destination = dest; - _key = key; - _tag = tag; - _excludes = excludes; - _qmfId = durable ? brokerLink.getConfigStore().createPersistentId() : brokerLink.getConfigStore().createId(); - - _transaction = new AutoCommitTransaction(getVirtualHost().getMessageStore()); - - if(durable) - { - try - { - brokerLink.getVirtualHost().getMessageStore().createBridge(this); - } - catch (AMQStoreException e) - { - throw new RuntimeException(e); - } - } - - createDelegate(); - } - - private void createDelegate() - { - if(_dynamic) - { - if(_localSource) - { - // TODO - } - else - { - if(_queueBridge) - { - // TODO - } - else - { - _delegate = new DynamicExchangeBridge(); - } - } - } - else - { - if(_localSource) - { - if(_queueBridge) - { - _delegate = new StaticQueuePushBridge(); - } - else - { - _delegate = new StaticExchangePushBridge(); - } - } - else - { - if(_queueBridge) - { - _delegate = new StaticQueuePullBridge(); - } - else - { - _delegate = new StaticExchangePullBridge(); - } - } - } - } - - public Bridge(final BrokerLink brokerLink, - final int bridgeNo, - final UUID id, - final long createTime, - final Map<String, String> arguments) - { - _link = brokerLink; - _bridgeNo = bridgeNo; - _qmfId = id; - brokerLink.getConfigStore().persistentIdInUse(id); - _createTime = createTime; - - _durable = Boolean.valueOf(arguments.get(DURABLE)); - _dynamic = Boolean.valueOf(arguments.get(DYNAMIC)); - _queueBridge = Boolean.valueOf(arguments.get(SRC_IS_QUEUE)); - _localSource = Boolean.valueOf(arguments.get(SRC_IS_LOCAL)); - _source = arguments.get(SOURCE); - _destination = arguments.get(DESTINATION); - _key = arguments.get(KEY); - _tag = arguments.get(TAG); - _excludes = arguments.get(EXCLUDES); - - //TODO. - _transaction = new AutoCommitTransaction(getVirtualHost().getMessageStore()); - - - if(_durable) - { - try - { - brokerLink.getVirtualHost().getMessageStore().createBridge(this); - } - catch (AMQStoreException e) - { - throw new RuntimeException(e); - } - } - - createDelegate(); - } - - - public Map<String,String> getArguments() - { - Map<String,String> arguments = new HashMap<String, String>(); - - arguments.put(DURABLE, String.valueOf(_durable)); - arguments.put(DYNAMIC, String.valueOf(_dynamic)); - arguments.put(SRC_IS_QUEUE, String.valueOf(_queueBridge)); - arguments.put(SRC_IS_LOCAL, String.valueOf(_localSource)); - arguments.put(SOURCE, _source); - arguments.put(DESTINATION, _destination); - arguments.put(KEY, _key); - arguments.put(TAG, _tag); - arguments.put(EXCLUDES, _excludes); - - return Collections.unmodifiableMap(arguments); - } - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public BridgeConfigType getConfigType() - { - return BridgeConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getLink(); - } - - public boolean isDurable() - { - return _durable; - } - - public boolean isDynamic() - { - return _dynamic; - } - - public boolean isQueueBridge() - { - return _queueBridge; - } - - public boolean isLocalSource() - { - return _localSource; - } - - public String getSource() - { - return _source; - } - - public String getDestination() - { - return _destination; - } - - public String getKey() - { - return _key; - } - - public String getTag() - { - return _tag; - } - - public String getExcludes() - { - return _excludes; - } - - public BrokerLink getLink() - { - return _link; - } - - public Integer getChannelId() - { - return (_session == null) ? 0 : _session.getChannel(); - } - - public int getAckBatching() - { - return 0; - } - - public long getCreateTime() - { - return _createTime; - } - - @Override - public boolean equals(final Object o) - { - if (this == o) - { - return true; - } - if (o == null || getClass() != o.getClass()) - { - return false; - } - - final Bridge bridge = (Bridge) o; - - if (_durable != bridge._durable) - { - return false; - } - if (_dynamic != bridge._dynamic) - { - return false; - } - if (_localSource != bridge._localSource) - { - return false; - } - if (_queueBridge != bridge._queueBridge) - { - return false; - } - if (_destination != null ? !_destination.equals(bridge._destination) : bridge._destination != null) - { - return false; - } - if (_excludes != null ? !_excludes.equals(bridge._excludes) : bridge._excludes != null) - { - return false; - } - if (_key != null ? !_key.equals(bridge._key) : bridge._key != null) - { - return false; - } - if (_source != null ? !_source.equals(bridge._source) : bridge._source != null) - { - return false; - } - if (_tag != null ? !_tag.equals(bridge._tag) : bridge._tag != null) - { - return false; - } - - return true; - } - - @Override - public int hashCode() - { - int result = (_durable ? 1 : 0); - result = 31 * result + (_dynamic ? 1 : 0); - result = 31 * result + (_queueBridge ? 1 : 0); - result = 31 * result + (_localSource ? 1 : 0); - result = 31 * result + (_source != null ? _source.hashCode() : 0); - result = 31 * result + (_destination != null ? _destination.hashCode() : 0); - result = 31 * result + (_key != null ? _key.hashCode() : 0); - result = 31 * result + (_tag != null ? _tag.hashCode() : 0); - result = 31 * result + (_excludes != null ? _excludes.hashCode() : 0); - return result; - } - - public void setSession(final Session session) - { - _session = session; - _delegate.setSession(session); - } - - private long getMessageWindowSize() - { - return 10l; - } - - - VirtualHost getVirtualHost() - { - return _link.getVirtualHost(); - } - - public void close() - { - // TODO - _delegate.close(); - _session = null; - } - - - - private interface BridgeImpl - { - void setSession(Session session); - - void close(); - } - - private abstract class AbstractPullBridge implements BridgeImpl, SessionListener - { - public final void setSession(final Session session) - { - session.setSessionListener(this); - onSession(); - - } - - abstract void onSession(); - - - - public void message(final Session ssn, final MessageTransfer xfr) - { - ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry(); - - Exchange exchange = exchangeRegistry.getExchange(_destination); - - // TODO - deal with exchange not existing - - DeliveryProperties delvProps = null; - if(xfr.getHeader() != null && (delvProps = xfr.getHeader().getDeliveryProperties()) != null && delvProps.hasTtl() && - !delvProps.hasExpiration()) - { - delvProps.setExpiration(System.currentTimeMillis() + delvProps.getTtl()); - } - - MessageMetaData_0_10 messageMetaData = new MessageMetaData_0_10(xfr); - final MessageStore store = getVirtualHost().getMessageStore(); - StoredMessage<MessageMetaData_0_10> storeMessage = store.addMessage(messageMetaData); - storeMessage.addContent(0,xfr.getBody()); - storeMessage.flushToStore(); - MessageTransferMessage message = new MessageTransferMessage(storeMessage, ((ServerSession)_session).getReference()); - - List<? extends BaseQueue> queues = exchange.route(message); - - - - if(queues != null && queues.size() != 0) - { - enqueue(message, queues); - } - else - { - if(delvProps == null || !delvProps.hasDiscardUnroutable() || !delvProps.getDiscardUnroutable()) - { - if(xfr.getAcceptMode() == MessageAcceptMode.EXPLICIT) - { - RangeSet rejects = RangeSetFactory.createRangeSet(); - rejects.add(xfr.getId()); - MessageReject reject = new MessageReject(rejects, MessageRejectCode.UNROUTABLE, "Unroutable"); - ssn.invoke(reject); - } - else - { - Exchange alternate = exchange.getAlternateExchange(); - if(alternate != null) - { - queues = alternate.route(message); - if(queues != null && queues.size() != 0) - { - enqueue(message, queues); - } - else - { - //TODO - log the message discard - } - } - else - { - //TODO - log the message discard - } - - - } - } - - - } - - ssn.processed(xfr); - - } - - - private void enqueue(final ServerMessage message, final List<? extends BaseQueue> queues) - { - _transaction.enqueue(queues,message, new ServerTransaction.Action() - { - - private BaseQueue[] _queues = queues.toArray(new BaseQueue[queues.size()]); - - public void postCommit() - { - for(int i = 0; i < _queues.length; i++) - { - try - { - _queues[i].enqueue(message); - } - catch (AMQException e) - { - // TODO - - throw new RuntimeException(e); - } - } - } - - public void onRollback() - { - // NO-OP - } - }, 0L); - } - - public void exception(final Session session, final SessionException exception) - { - // TODO - Handle exceptions - } - - public void closed(final Session session) - { - // TODO - handle close - } - - public void opened(final Session session) - { - // this method never called - } - - public void resumed(final Session session) - { - // will never resume these sessions - } - - - - } - - private final class StaticExchangePullBridge extends AbstractPullBridge - { - private final String _tmpQueueName = "bridge_queue_" + _bridgeNo + "_" + _link.getFederationTag();; - - public void onSession() - { - - final HashMap<String, Object> options = new HashMap<String, Object>(); - options.put("qpid.trace.exclude", _link.getFederationTag()); - options.put("qpid.trace.id",_link.getRemoteFederationTag()); - _session.queueDeclare(_tmpQueueName,null, options, Option.AUTO_DELETE, Option.EXCLUSIVE); - _session.sync(); - // todo check exception - final Map<String,Object> bindingArgs = new HashMap<String,Object>(); - _session.exchangeBind(_tmpQueueName, _source, _key, bindingArgs); - _session.sync(); - // todo check exception - - final Map<String,Object> subscribeOptions = Collections.EMPTY_MAP; - final String subName = String.valueOf(_bridgeNo); - _session.messageSubscribe(_tmpQueueName, - subName,MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0l, subscribeOptions); - _session.sync(); - // todo check exception - - _session.messageSetFlowMode(subName,MessageFlowMode.WINDOW); - _session.messageFlow(subName, MessageCreditUnit.MESSAGE, getMessageWindowSize()); - _session.messageFlow(subName, MessageCreditUnit.BYTE, 0xFFFFFFFF); - - } - - public void close() - { - // TODO - } - } - - private final class StaticQueuePullBridge extends AbstractPullBridge - { - - public void onSession() - { - - final Map<String,Object> subscribeOptions = Collections.EMPTY_MAP; - final String subName = String.valueOf(_bridgeNo); - _session.messageSubscribe(_source, - subName,MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0l, subscribeOptions); - _session.sync(); - // todo check exception - - _session.messageSetFlowMode(subName,MessageFlowMode.WINDOW); - _session.messageFlow(subName, MessageCreditUnit.MESSAGE, getMessageWindowSize()); - _session.messageFlow(subName, MessageCreditUnit.BYTE, 0xFFFFFFFF); - - } - - public void close() - { - // TODO - } - } - - private final class DynamicExchangeBridge extends AbstractPullBridge implements Exchange.BindingListener - { - private final String _tmpQueueName = "bridge_queue_" + _bridgeNo + "_" + _link.getFederationTag(); - - private final ConcurrentMap<Binding,Binding> _bindings = new ConcurrentHashMap<Binding,Binding>(); - - - void onSession() - { - - - final HashMap<String, Object> options = new HashMap<String, Object>(); - options.put("qpid.trace.exclude", _link.getFederationTag()); - options.put("qpid.trace.id",_link.getRemoteFederationTag()); - _session.queueDeclare(_tmpQueueName,null, options, Option.AUTO_DELETE, Option.EXCLUSIVE); - _session.sync(); - // todo - check exception - - final Map<String,Object> subscribeOptions = Collections.EMPTY_MAP; - final String subName = String.valueOf(_bridgeNo); - _session.messageSubscribe(_tmpQueueName, - subName,MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0l, subscribeOptions); - _session.sync(); - // todo check exception - _session.messageSetFlowMode(subName,MessageFlowMode.WINDOW); - _session.messageFlow(subName, MessageCreditUnit.MESSAGE, getMessageWindowSize()); - _session.messageFlow(subName, MessageCreditUnit.BYTE, 0xFFFFFFFF); - _session.sync(); - // todo check exception - - - ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry(); - - Exchange exchange = exchangeRegistry.getExchange(_destination); - - // TODO - check null - - exchange.addBindingListener(this); - - Collection<Binding> bindings = exchange.getBindings(); - for(Binding binding : bindings) - { - propogateBinding(binding); - } - - } - - private void propogateBinding(final Binding binding) - { - if(_bindings.putIfAbsent(binding,binding)== null) - { - Map<String,Object> arguments = new HashMap<String,Object>(binding.getArguments()); - - if(arguments.get("qpid.fed.origin") == null) - { - arguments.put("qpid.fed.op",""); - arguments.put("qpid.fed.origin",_link.getFederationTag()); - arguments.put("qpid.fed.tags",_link.getFederationTag()); - } - else - { - String tags = (String) arguments.get("qpid.fed.tags"); - if(tags == null) - { - tags = _link.getFederationTag(); - } - else - { - if(Arrays.asList(tags.split(",")).contains(_link.getFederationTag())) - { - return; - } - tags += "," + _link.getFederationTag(); - } - arguments.put("qpid.fed.tags", tags); - } - - _session.exchangeBind(_tmpQueueName, _source, binding.getBindingKey(), arguments); - _session.sync(); - // TODO - check exception? - - } - } - - private void propogateBindingRemoval(final Binding binding) - { - if(_bindings.remove(binding) != null) - { - // TODO - this is wrong!!!! - _session.exchangeUnbind(_tmpQueueName, _source, binding.getBindingKey()); - } - } - - - public void bindingAdded(final Exchange exchange, final Binding binding) - { - propogateBinding(binding); - } - - public void bindingRemoved(final Exchange exchange, final Binding binding) - { - propogateBindingRemoval(binding); - } - - public void close() - { - // TODO - } - } - - private class StaticExchangePushBridge implements BridgeImpl, SessionListener - { - private final String _tmpQueueName = "bridge_queue_" + _bridgeNo + "_" + _link.getFederationTag(); - private AMQQueue _queue; - - public void setSession(final Session session) - { - assert session instanceof ServerSession; - - session.setSessionListener(this); - - ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry(); - - Exchange exchange = exchangeRegistry.getExchange(_source); - - // TODO - Check null - - final HashMap<String, Object> options = new HashMap<String, Object>(); - options.put("qpid.trace.exclude", _link.getFederationTag()); - options.put("qpid.trace.id",_link.getRemoteFederationTag()); - - try - { - _queue = AMQQueueFactory.createAMQQueueImpl(null, - _tmpQueueName, - isDurable(), - _link.getFederationTag(), - false, - false, - getVirtualHost(), options); - } - catch (AMQException e) - { - // TODO - throw new RuntimeException(e); - } - - FlowCreditManager_0_10 creditManager = new WindowCreditManager(0xFFFFFFFF,getMessageWindowSize()); - - //TODO Handle the passing of non-null Filters and Arguments here - - Subscription_0_10 sub = SubscriptionFactoryImpl.INSTANCE.createSubscription((ServerSession)session, - _destination, - MessageAcceptMode.NONE, - MessageAcquireMode.PRE_ACQUIRED, - MessageFlowMode.WINDOW, - creditManager, null,null); - - ((ServerSession)session).register(_destination, sub); - - try - { - _queue.registerSubscription(sub, true); - getVirtualHost().getBindingFactory().addBinding(_key, _queue, exchange, Collections.<String, Object>emptyMap()); - } - catch (AMQException e) - { - // TODO - throw new RuntimeException(e); - } - } - - public void close() - { - // TODO - } - - public void opened(final Session session) - { - // this method never called - } - - public void resumed(final Session session) - { - // this session will never be resumed - } - - public void message(final Session ssn, final MessageTransfer xfr) - { - // messages should not be sent ... should probably log error - } - - public void exception(final Session session, final SessionException exception) - { - // TODO - } - - public void closed(final Session session) - { - // TODO - } - } - - private class StaticQueuePushBridge implements BridgeImpl, SessionListener - { - private AMQQueue _queue; - - public void setSession(final Session session) - { - assert session instanceof ServerSession; - - session.setSessionListener(this); - - QueueRegistry queueRegistry = getVirtualHost().getQueueRegistry(); - - _queue = queueRegistry.getQueue(_source); - - // TODO - null check - - FlowCreditManager_0_10 creditManager = new WindowCreditManager(0xFFFFFFFF,getMessageWindowSize()); - - //TODO Handle the passing of non-null Filters and Arguments here - - Subscription_0_10 sub = SubscriptionFactoryImpl.INSTANCE.createSubscription((ServerSession)session, - _destination, - MessageAcceptMode.NONE, - MessageAcquireMode.PRE_ACQUIRED, - MessageFlowMode.WINDOW, - creditManager, null,null); - - ((ServerSession)session).register(_destination, sub); - - try - { - _queue.registerSubscription(sub, false); - } - catch (AMQException e) - { - // TODO - throw new RuntimeException(e); - } - - } - - public void close() - { - // TODO - } - - public void opened(final Session session) - { - // never called - } - - public void resumed(final Session session) - { - // session will not resume - } - - public void message(final Session ssn, final MessageTransfer xfr) - { - // should never be called ... should probably log error - } - - public void exception(final Session session, final SessionException exception) - { - // TODO - } - - public void closed(final Session session) - { - // TODO - } - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java b/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java deleted file mode 100644 index 1ef57c53cb..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java +++ /dev/null @@ -1,692 +0,0 @@ -/* - * - * 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.federation; - -import org.apache.qpid.AMQStoreException; -import org.apache.qpid.common.ServerPropertyNames; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.ConnectionConfig; -import org.apache.qpid.server.configuration.ConnectionConfigType; -import org.apache.qpid.server.configuration.LinkConfig; -import org.apache.qpid.server.configuration.LinkConfigType; -import org.apache.qpid.server.transport.ServerSession; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.Binary; -import org.apache.qpid.transport.ClientDelegate; -import org.apache.qpid.transport.Connection; -import org.apache.qpid.transport.ConnectionException; -import org.apache.qpid.transport.ConnectionListener; -import org.apache.qpid.transport.ConnectionSettings; -import org.apache.qpid.transport.Session; -import org.apache.qpid.transport.SessionDelegate; -import org.apache.qpid.transport.TransportException; - -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.NameCallback; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.UnsupportedCallbackException; -import javax.security.sasl.Sasl; -import javax.security.sasl.SaslClient; -import javax.security.sasl.SaslException; -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; - -public class BrokerLink implements LinkConfig, ConnectionListener -{ - - private static final int CORE_POOL_SIZE = 4; - - private static final ScheduledThreadPoolExecutor _threadPool = - new ScheduledThreadPoolExecutor(CORE_POOL_SIZE); - private static final String TRANSPORT = "transport"; - private static final String HOST = "host"; - private static final String PORT = "port"; - private static final String REMOTE_VHOST = "remoteVhost"; - private static final String DURABLE = "durable"; - private static final String AUTH_MECHANISM = "authMechanism"; - private static final String USERNAME = "username"; - private static final String PASSWORD = "password"; - - - private final String _transport; - private final String _host; - private final int _port; - private final String _remoteVhost; - private final boolean _durable; - private final String _authMechanism; - private final String _username; - private final String _password; - private final VirtualHost _virtualHost; - private UUID _qmfId; - private AtomicBoolean _closing = new AtomicBoolean(); - private final long _createTime; - private Connection _qpidConnection; - private AtomicReference<Thread> _executor = new AtomicReference<Thread>(); - private AtomicInteger _bridgeId = new AtomicInteger(); - - private final ConcurrentHashMap<Bridge,Bridge> _bridges = new ConcurrentHashMap<Bridge,Bridge>(); - private final ConcurrentHashMap<Bridge,Bridge> _activeBridges = new ConcurrentHashMap<Bridge,Bridge>(); - private final ConcurrentLinkedQueue<Bridge> _pendingBridges = new ConcurrentLinkedQueue<Bridge>(); - private String _remoteFederationTag; - - private ConnectionConfig _connectionConfig; - private ConnectionException _exception; - private String _lastErrorMessage; - private int _retryDelay = 1; - private final Runnable _makeConnectionTask = new Runnable() - { - public void run() - { - doMakeConnection(); - } - }; - - - - - public static enum State - { - OPERATIONAL, - DOWN, - ESTABLISHING, - DELETED - } - - - private volatile State _state = State.DOWN; - - private static final AtomicReferenceFieldUpdater<BrokerLink, State> _stateUpdater = - AtomicReferenceFieldUpdater.newUpdater(BrokerLink.class, State.class, "_state"); - - private class ConnectionConfigAdapter implements ConnectionConfig - { - private long _adapterCreateTime = System.currentTimeMillis(); - private UUID _qmfId = BrokerLink.this.getConfigStore().createId(); - - public VirtualHost getVirtualHost() - { - return BrokerLink.this.getVirtualHost(); - } - - public String getAddress() - { - return _host+":"+_port; - } - - public Boolean isIncoming() - { - return false; - } - - public Boolean isSystemConnection() - { - return true; - } - - public Boolean isFederationLink() - { - return true; - } - - public String getAuthId() - { - return _username; - } - - public String getRemoteProcessName() - { - return null; - } - - public Integer getRemotePID() - { - return null; - } - - public Integer getRemoteParentPID() - { - return null; - } - - public ConfigStore getConfigStore() - { - return getVirtualHost().getConfigStore(); - } - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public ConnectionConfigType getConfigType() - { - return ConnectionConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getVirtualHost(); - } - - public boolean isDurable() - { - return false; - } - - public long getCreateTime() - { - return _adapterCreateTime; - } - - public Boolean isShadow() - { - return false; - } - - public void mgmtClose() - { - _connectionConfig.mgmtClose(); - } - } - - private class SessionFactory implements Connection.SessionFactory - { - - public Session newSession(final Connection conn, final Binary name, final long expiry) - { - return new ServerSession(conn, new SessionDelegate(), name, expiry, _connectionConfig); - } - }; - - public BrokerLink(final VirtualHost virtualHost, UUID qmfId, long createTime, Map<String, String> arguments) - { - _virtualHost = virtualHost; - _qmfId = qmfId; - virtualHost.getConfigStore().persistentIdInUse(qmfId); - _createTime = createTime; - _transport = arguments.get(TRANSPORT); - - _host = arguments.get(HOST); - _port = Integer.parseInt(arguments.get(PORT)); - _remoteVhost = arguments.get(REMOTE_VHOST); - _durable = Boolean.parseBoolean(arguments.get(DURABLE)); - _authMechanism = arguments.get("authMechanism"); - _username = arguments.get("username"); - _password = arguments.get("password"); - - if(_durable) - { - try - { - _virtualHost.getMessageStore().createBrokerLink(this); - } - catch (AMQStoreException e) - { - throw new RuntimeException(e); - } - } - - - _qpidConnection = new Connection(); - _connectionConfig = new ConnectionConfigAdapter(); - _qpidConnection.addConnectionListener(this); - - - makeConnection(); - - } - - - public BrokerLink(final VirtualHost virtualHost, - final String transport, - final String host, - final int port, - final String remoteVhost, - final boolean durable, - final String authMechanism, - final String username, - final String password) - { - _virtualHost = virtualHost; - _transport = transport; - _createTime = System.currentTimeMillis(); - _host = host; - _port = port; - _remoteVhost = remoteVhost; - _durable = durable; - _authMechanism = authMechanism; - _username = username; - _password = password; - _qmfId = durable ? virtualHost.getConfigStore().createPersistentId() : virtualHost.getConfigStore().createId(); - - if(durable) - { - try - { - _virtualHost.getMessageStore().createBrokerLink(this); - } - catch (AMQStoreException e) - { - throw new RuntimeException(e); - } - } - _qpidConnection = new Connection(); - _connectionConfig = new ConnectionConfigAdapter(); - _qpidConnection.addConnectionListener(this); - - makeConnection(); - } - - public Map<String,String> getArguments() - { - Map<String,String> arguments = new HashMap<String, String>(); - - arguments.put(TRANSPORT, _transport); - arguments.put(HOST, _host); - arguments.put(PORT, String.valueOf(_port)); - arguments.put(REMOTE_VHOST, _remoteVhost); - arguments.put(DURABLE, String.valueOf(_durable)); - arguments.put(AUTH_MECHANISM, _authMechanism); - arguments.put(USERNAME, _username); - arguments.put(PASSWORD, _password); - - return Collections.unmodifiableMap(arguments); - } - - private final boolean updateState(State expected, State newState) - { - return _stateUpdater.compareAndSet(this,expected,newState); - } - - private void makeConnection() - { - _threadPool.execute(_makeConnectionTask); - } - - - - private void doMakeConnection() - { - if(updateState(State.DOWN, State.ESTABLISHING)) - { - try - { - _qpidConnection.setConnectionDelegate(new ClientDelegate(new ConnectionSettings()) - { - protected SaslClient createSaslClient(List<Object> brokerMechs) throws ConnectionException, - SaslException - { - Map<String,Object> saslProps = new HashMap<String,Object>(); - - - CallbackHandler cbh = new CallbackHandler() - { - public void handle(final Callback[] callbacks) - throws IOException, UnsupportedCallbackException - { - for (int i = 0; i < callbacks.length; i++) - { - Callback cb = callbacks[i]; - if (cb instanceof NameCallback) - { - ((NameCallback)cb).setName(_username); - } - else if (cb instanceof PasswordCallback) - { - ((PasswordCallback)cb).setPassword(_password.toCharArray()); - } - else - { - throw new UnsupportedCallbackException(cb); - } - } - - } - }; - final SaslClient sc = Sasl.createSaslClient(new String[] {"PLAIN"}, null, - getConnectionSettings().getSaslProtocol(), - getConnectionSettings().getSaslServerName(), - saslProps, cbh); - - return sc; - }}); - - _qpidConnection.connect(_host, _port, _remoteVhost, _username, _password, "ssl".equals(_transport), _authMechanism); - - final Map<String,Object> serverProps = _qpidConnection.getServerProperties(); - - _remoteFederationTag = (String) serverProps.get(ServerPropertyNames.FEDERATION_TAG); - if(_remoteFederationTag == null) - { - _remoteFederationTag = UUID.fromString(_transport+":"+_host+":"+_port).toString(); - } - _qpidConnection.setSessionFactory(new SessionFactory()); - - updateState(State.ESTABLISHING, State.OPERATIONAL); - - _retryDelay = 1; - - for(Bridge bridge : _bridges.values()) - { - if(_state != State.OPERATIONAL) - { - break; - } - addBridge(bridge); - } - - - } - catch (TransportException e) - { - _lastErrorMessage = e.getMessage(); - if(_retryDelay < 60) - { - _retryDelay <<= 1; - } - - updateState(State.ESTABLISHING, State.DOWN); - _activeBridges.clear(); - scheduleConnectionRetry(); - } - } - } - - private void scheduleConnectionRetry() - { - if(_state != State.DELETED) - { - _threadPool.schedule(_makeConnectionTask, _retryDelay, TimeUnit.SECONDS); - } - } - - public VirtualHost getVirtualHost() - { - return _virtualHost; - } - - public String getTransport() - { - return _transport; - } - - public String getHost() - { - return _host; - } - - public int getPort() - { - return _port; - } - - public String getRemoteVhost() - { - return _remoteVhost; - } - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public LinkConfigType getConfigType() - { - return LinkConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getVirtualHost(); - } - - public boolean isDurable() - { - return _durable; - } - - public String getAuthMechanism() - { - return _authMechanism; - } - - public String getUsername() - { - return _username; - } - - public String getPassword() - { - return _password; - } - - @Override - public boolean equals(final Object o) - { - if (this == o) - { - return true; - } - if (o == null || getClass() != o.getClass()) - { - return false; - } - - final BrokerLink that = (BrokerLink) o; - - if (_port != that._port) - { - return false; - } - if (_host != null ? !_host.equals(that._host) : that._host != null) - { - return false; - } - if (_remoteVhost != null ? !_remoteVhost.equals(that._remoteVhost) : that._remoteVhost != null) - { - return false; - } - if (_transport != null ? !_transport.equals(that._transport) : that._transport != null) - { - return false; - } - - return true; - } - - @Override - public int hashCode() - { - int result = _transport != null ? _transport.hashCode() : 0; - result = 31 * result + (_host != null ? _host.hashCode() : 0); - result = 31 * result + _port; - result = 31 * result + (_remoteVhost != null ? _remoteVhost.hashCode() : 0); - return result; - } - - public void close() - { - if(_closing.compareAndSet(false,true)) - { - // TODO - close connection - for(Bridge bridge : _bridges.values()) - { - bridge.close(); - } - _bridges.clear(); - - _virtualHost.removeBrokerConnection(this); - } - } - - public long getCreateTime() - { - return _createTime; - } - - public void createBridge(final boolean durable, - final boolean dynamic, - final boolean srcIsQueue, - final boolean srcIsLocal, - final String src, - final String dest, - final String key, - final String tag, - final String excludes) - { - if(!_closing.get()) - { - Bridge bridge = new Bridge(this, _bridgeId.incrementAndGet(), durable,dynamic,srcIsQueue,srcIsLocal,src,dest,key,tag,excludes); - if(_bridges.putIfAbsent(bridge, bridge) == null) - { - - addBridge(bridge); - } - } - - - } - - public void createBridge(final UUID id, final long createTime, final Map<String, String> arguments) - { - if(!_closing.get()) - { - Bridge bridge = new Bridge(this, _bridgeId.incrementAndGet(), id, createTime, arguments); - if(_bridges.putIfAbsent(bridge, bridge) == null) - { - - addBridge(bridge); - } - } - } - - - private void addBridge(final Bridge bridge) - { - getConfigStore().addConfiguredObject(bridge); - - if(_state == State.OPERATIONAL && (_activeBridges.putIfAbsent(bridge,bridge) == null)) - { - - - Session session = _qpidConnection.createSession("Bridge(" - + (bridge.isDurable() ? "durable" : "transient") - + "," + (bridge.isDynamic() ? "dynamic" : "static") - + "," + (bridge.isQueueBridge() ? "queue" : "exchange") - + "," + (bridge.isLocalSource() ? "local-src" : "remote-src") - + ",[Source: '" + bridge.getSource() + "']" - + ",[Destination: '" + bridge.getDestination() + "']" - + ",[Key: '" + bridge.getKey() + "']" - + ",[Tag: '" + bridge.getTag() + "']" - + ".[Excludes: '" + bridge.getExcludes() + "'])"); - bridge.setSession(session); - - - if(_closing.get()) - { - bridge.close(); - } - } - - } - - public void opened(final Connection connection) - { - // this method not called - } - - public void exception(final Connection connection, final ConnectionException exception) - { - _exception = exception; - _lastErrorMessage = exception.getMessage(); - - } - - public void closed(final Connection connection) - { - State currentState = _state; - if(currentState != State.DOWN && currentState != State.DELETED && updateState(currentState, State.DOWN)) - { - scheduleConnectionRetry(); - } - } - - public ConfigStore getConfigStore() - { - return getVirtualHost().getConfigStore(); - } - - public String getFederationTag() - { - return getVirtualHost().getFederationTag(); - } - - public String getRemoteFederationTag() - { - return _remoteFederationTag; - } - - public String getState() - { - return _state.name(); - } - - public String getLastError() - { - return _lastErrorMessage; - } - - @Override - public String toString() - { - return "BrokerLink{" + - " _id=" + _qmfId + - ", _transport='" + _transport + '\'' + - ", _host='" + _host + '\'' + - ", _port=" + _port + - ", _remoteVhost='" + _remoteVhost + '\'' + - ", _durable=" + _durable + - ", _authMechanism='" + _authMechanism + '\'' + - ", _username='" + _username + '\'' + - ", _password='" + _password + '\'' + - ", _virtualHost=" + _virtualHost + - ", _createTime=" + _createTime + - ", _remoteFederationTag='" + _remoteFederationTag + '\'' + - ", _state=" + _state + - '}'; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java index b8c8411c5d..0339287e38 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java @@ -30,11 +30,11 @@ import org.apache.qpid.framing.ConnectionSecureOkBody; import org.apache.qpid.framing.ConnectionTuneBody; import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; import org.apache.qpid.server.state.AMQState; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; @@ -59,9 +59,10 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener public void methodReceived(AMQStateManager stateManager, ConnectionSecureOkBody body, int channelId) throws AMQException { + Broker broker = stateManager.getBroker(); AMQProtocolSession session = stateManager.getProtocolSession(); - AuthenticationManager authMgr = stateManager.getAuthenticationManager(); + SubjectCreator subjectCreator = stateManager.getSubjectCreator(); SaslServer ss = session.getSaslServer(); if (ss == null) @@ -69,7 +70,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener throw new AMQException("No SASL context set up in session"); } MethodRegistry methodRegistry = session.getMethodRegistry(); - AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse()); + SubjectAuthenticationResult authResult = subjectCreator.authenticate(ss, body.getResponse()); switch (authResult.getStatus()) { case ERROR: @@ -97,9 +98,9 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener stateManager.changeState(AMQState.CONNECTION_NOT_TUNED); ConnectionTuneBody tuneBody = - methodRegistry.createConnectionTuneBody(ApplicationRegistry.getInstance().getConfiguration().getMaxChannelCount(), - ConnectionStartOkMethodHandler.getConfiguredFrameSize(), - ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay()); + methodRegistry.createConnectionTuneBody((Integer)broker.getAttribute(Broker.SESSION_COUNT_LIMIT), + BrokerProperties.DEFAULT_FRAME_SIZE, + (Integer)broker.getAttribute(Broker.HEART_BEAT_DELAY)); session.writeFrame(tuneBody.generateFrame(0)); session.setAuthorizedSubject(authResult.getSubject()); disposeSaslServer(session); diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java index a522b9f60f..e70fa6a37b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java @@ -29,12 +29,11 @@ import org.apache.qpid.framing.ConnectionStartOkBody; import org.apache.qpid.framing.ConnectionTuneBody; import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.server.configuration.ServerConfiguration; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; import org.apache.qpid.server.state.AMQState; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; @@ -60,16 +59,17 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< public void methodReceived(AMQStateManager stateManager, ConnectionStartOkBody body, int channelId) throws AMQException { + Broker broker = stateManager.getBroker(); AMQProtocolSession session = stateManager.getProtocolSession(); _logger.info("SASL Mechanism selected: " + body.getMechanism()); _logger.info("Locale selected: " + body.getLocale()); - AuthenticationManager authMgr = stateManager.getAuthenticationManager(); + SubjectCreator subjectCreator = stateManager.getSubjectCreator(); SaslServer ss = null; try { - ss = authMgr.createSaslServer(String.valueOf(body.getMechanism()), session.getLocalFQDN(), session.getPeerPrincipal()); + ss = subjectCreator.createSaslServer(String.valueOf(body.getMechanism()), session.getLocalFQDN(), session.getPeerPrincipal()); if (ss == null) { @@ -78,7 +78,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< session.setSaslServer(ss); - final AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse()); + final SubjectAuthenticationResult authResult = subjectCreator.authenticate(ss, body.getResponse()); //save clientProperties session.setClientProperties(body.getClientProperties()); @@ -112,9 +112,9 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< stateManager.changeState(AMQState.CONNECTION_NOT_TUNED); - ConnectionTuneBody tuneBody = methodRegistry.createConnectionTuneBody(ApplicationRegistry.getInstance().getConfiguration().getMaxChannelCount(), - getConfiguredFrameSize(), - ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay()); + ConnectionTuneBody tuneBody = methodRegistry.createConnectionTuneBody((Integer)broker.getAttribute(Broker.SESSION_COUNT_LIMIT), + BrokerProperties.DEFAULT_FRAME_SIZE, + (Integer)broker.getAttribute(Broker.HEART_BEAT_DELAY)); session.writeFrame(tuneBody.generateFrame(0)); break; case CONTINUE: @@ -148,13 +148,6 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< } } - static int getConfiguredFrameSize() - { - final ServerConfiguration config = ApplicationRegistry.getInstance().getConfiguration(); - final int framesize = config.getFrameSize(); - _logger.info("Framesize set to " + framesize); - return framesize; - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java index 8756409f64..eed0cd6020 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java @@ -101,7 +101,7 @@ public class ExchangeDeclareHandler implements StateAwareMethodListener<Exchange exchange = exchangeFactory.createExchange(exchangeName == null ? null : exchangeName.intern(), body.getType() == null ? null : body.getType().intern(), body.getDurable(), - body.getPassive(), body.getTicket()); + body.getAutoDelete(), body.getTicket()); exchangeRegistry.registerExchange(exchange); if (exchange.isDurable()) diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java index ae725b9ec1..194c3d6351 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java @@ -38,7 +38,6 @@ import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; import org.apache.qpid.server.store.DurableConfigurationStore; @@ -59,8 +58,6 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar return _instance; } - private boolean autoRegister = ApplicationRegistry.getInstance().getConfiguration().getQueueAutoRegister(); - public void methodReceived(AMQStateManager stateManager, QueueDeclareBody body, int channelId) throws AMQException { final AMQProtocolSession protocolConnection = stateManager.getProtocolSession(); @@ -148,13 +145,11 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar }); } } - if (autoRegister) - { - Exchange defaultExchange = exchangeRegistry.getDefaultExchange(); + Exchange defaultExchange = exchangeRegistry.getDefaultExchange(); - virtualHost.getBindingFactory().addBinding(String.valueOf(queueName), queue, defaultExchange, Collections.EMPTY_MAP); - _logger.info("Queue " + queueName + " bound to default exchange(" + defaultExchange.getNameShortString() + ")"); - } + virtualHost.getBindingFactory().addBinding(String.valueOf(queueName), queue, defaultExchange, + Collections.<String, Object> emptyMap()); + _logger.info("Queue " + queueName + " bound to default exchange(" + defaultExchange.getNameShortString() + ")"); } } else if (queue.isExclusive() && !queue.isDurable() && (owningSession == null || owningSession.getConnectionModel() != protocolConnection)) diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java b/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java index 545f2adea2..98da9074ef 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java @@ -20,7 +20,6 @@ */ package org.apache.qpid.server.logging; -import org.apache.qpid.server.configuration.ServerConfiguration; public abstract class AbstractRootMessageLogger implements RootMessageLogger { @@ -33,9 +32,9 @@ public abstract class AbstractRootMessageLogger implements RootMessageLogger } - public AbstractRootMessageLogger(ServerConfiguration config) + public AbstractRootMessageLogger(boolean statusUpdatesEnabled) { - _enabled = config.getStatusUpdatesEnabled(); + _enabled = statusUpdatesEnabled; } public boolean isEnabled() diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java b/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java index ec506ab51c..b4e9f2f333 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java @@ -20,23 +20,18 @@ */ package org.apache.qpid.server.logging; -import org.apache.log4j.Level; import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.ServerConfiguration; - public class Log4jMessageLogger extends AbstractRootMessageLogger { - public static final Level LEVEL = Level.toLevel("INFO"); - public Log4jMessageLogger() { super(); } - public Log4jMessageLogger(ServerConfiguration config) + public Log4jMessageLogger(boolean statusUpdatesEnabled) { - super(config); + super(statusUpdatesEnabled); } @Override @@ -51,7 +46,7 @@ public class Log4jMessageLogger extends AbstractRootMessageLogger if(isEnabled()) { Logger logger = Logger.getLogger(logHierarchy); - return logger.isEnabledFor(LEVEL); + return logger.isInfoEnabled(); } else { @@ -69,7 +64,6 @@ public class Log4jMessageLogger extends AbstractRootMessageLogger public void rawMessage(String message, Throwable throwable, String logHierarchy) { Logger logger = Logger.getLogger(logHierarchy); - - logger.log(LEVEL, message, throwable); + logger.info(message, throwable); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java b/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java index a1065319d3..d053dd3fe2 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java @@ -90,7 +90,6 @@ public class LogRecorder implements Appender, Iterable<LogRecorder.Record> public LogRecorder() { - Logger.getRootLogger().addAppender(this); } @@ -109,7 +108,11 @@ public class LogRecorder implements Appender, Iterable<LogRecorder.Record> @Override public void close() { - //TODO - Implement + } + + public void closeLogRecorder() + { + Logger.getRootLogger().removeAppender(this); } @Override diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractManagementActor.java b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractManagementActor.java new file mode 100644 index 0000000000..8cf121b3d9 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractManagementActor.java @@ -0,0 +1,68 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.logging.actors; + +import java.security.AccessController; + +import javax.security.auth.Subject; + +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; + +public abstract class AbstractManagementActor extends AbstractActor +{ + /** + * Holds the principal name to display when principal subject is not available. + * <p> + * This is useful for cases when users invoke JMX operation over JConsole + * attached to the local JVM. + */ + protected static final String UNKNOWN_PRINCIPAL = "N/A"; + + /** used when the principal name cannot be discovered from the Subject */ + private final String _fallbackPrincipalName; + + public AbstractManagementActor(RootMessageLogger rootLogger, String fallbackPrincipalName) + { + super(rootLogger); + _fallbackPrincipalName = fallbackPrincipalName; + } + + /** + * Returns current {@link AuthenticatedPrincipal} name or {@link #_fallbackPrincipalName} + * if it can't be found. + */ + protected String getPrincipalName() + { + String identity = _fallbackPrincipalName; + + final Subject subject = Subject.getSubject(AccessController.getContext()); + if (subject != null) + { + AuthenticatedPrincipal authenticatedPrincipal = AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(subject); + if(authenticatedPrincipal != null) + { + identity = authenticatedPrincipal.getName(); + } + } + return identity; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java index 97134515a0..6251471139 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java @@ -105,6 +105,11 @@ public class CurrentActor { Stack<LogActor> stack = _currentActor.get(); stack.pop(); + + if (stack.isEmpty()) + { + _currentActor.remove(); + } } /** diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/HttpManagementActor.java b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/HttpManagementActor.java new file mode 100644 index 0000000000..9b445c2bd9 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/HttpManagementActor.java @@ -0,0 +1,62 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.logging.actors; + +import java.text.MessageFormat; + +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.logging.subjects.LogSubjectFormat; + +/** + * HttpManagement actor to use in {@link AbstractServlet} to log all http management operational logging. + * + * An instance is required per http Session. + */ +public class HttpManagementActor extends AbstractManagementActor +{ + private String _cachedLogString; + private String _lastPrincipalName; + private String _address; + + public HttpManagementActor(RootMessageLogger rootLogger, String ip, int port) + { + super(rootLogger, UNKNOWN_PRINCIPAL); + _address = ip + ":" + port; + } + + private synchronized String getAndCacheLogString() + { + String principalName = getPrincipalName(); + + if(!principalName.equals(_lastPrincipalName)) + { + _lastPrincipalName = principalName; + _cachedLogString = "[" + MessageFormat.format(LogSubjectFormat.MANAGEMENT_FORMAT, principalName, _address) + "] "; + } + + return _cachedLogString; + } + + public String getLogMessage() + { + return getAndCacheLogString(); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java index a2f3506502..ba5ea47fc1 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java @@ -21,58 +21,31 @@ package org.apache.qpid.server.logging.actors; import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.logging.subjects.LogSubjectFormat; -import javax.management.remote.JMXPrincipal; -import javax.security.auth.Subject; -import java.security.AccessController; -import java.security.Principal; import java.text.MessageFormat; -import java.util.Set; /** * Management actor to use in {@link MBeanInvocationHandlerImpl} to log all management operational logging. */ -public class ManagementActor extends AbstractActor +public class ManagementActor extends AbstractManagementActor { - /** - * Holds the principal name to display when principal subject is not available. - * <p> - * This is useful for cases when users invoke JMX operation over JConsole - * attached to the local JVM. - */ - private static final String UNKNOWN_PRINCIPAL = "N/A"; - private String _lastThreadName = null; /** - * LOG FORMAT for the ManagementActor, - * Uses a MessageFormat call to insert the required values according to - * these indices: - * - * 0 - User ID - * 1 - IP - */ - public static final String MANAGEMENT_FORMAT = "mng:{0}({1})"; - - /** * The logString to be used for logging */ private String _logStringContainingPrincipal; - /** used when the principal name cannot be discovered from the Subject */ - private final String _fallbackPrincipalName; - /** @param rootLogger The RootLogger to use for this Actor */ public ManagementActor(RootMessageLogger rootLogger) { - super(rootLogger); - _fallbackPrincipalName = UNKNOWN_PRINCIPAL; + super(rootLogger, UNKNOWN_PRINCIPAL); } public ManagementActor(RootMessageLogger rootLogger, String principalName) { - super(rootLogger); - _fallbackPrincipalName = principalName; + super(rootLogger, principalName); } private synchronized String getAndCacheLogString() @@ -96,7 +69,7 @@ public class ManagementActor extends AbstractActor if (split.length == 2) { String ip = currentName.split("-")[1]; - actor = MessageFormat.format(MANAGEMENT_FORMAT, principalName, ip); + actor = MessageFormat.format(LogSubjectFormat.MANAGEMENT_FORMAT, principalName, ip); } else { @@ -119,33 +92,8 @@ public class ManagementActor extends AbstractActor return logString; } - /** - * Returns current JMX principal name. - * - * @return principal name or null if principal can not be found - */ - private String getPrincipalName() - { - String identity = _fallbackPrincipalName; - - // retrieve Subject from current AccessControlContext - final Subject subject = Subject.getSubject(AccessController.getContext()); - if (subject != null) - { - // retrieve JMXPrincipal from Subject - final Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class); - if (principals != null && !principals.isEmpty()) - { - final Principal principal = principals.iterator().next(); - identity = principal.getName(); - } - } - return identity; - } - public String getLogMessage() { return getAndCacheLogString(); } - } diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingFacade.java b/java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingManagementFacade.java index 931171b175..6a961c8fa4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingFacade.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingManagementFacade.java @@ -58,49 +58,49 @@ import java.util.Random; * turn {@link Logger} on, off and control their {@link Level}, and the manipulation and reload * of the log4j configuration file. */ -public class LoggingFacade +public class LoggingManagementFacade { private static Logger LOGGER; - private static transient LoggingFacade _instance; + private static transient LoggingManagementFacade _instance; private final String _filename; private final int _delay; - public static LoggingFacade configure(String filename) throws LoggingFacadeException + public static LoggingManagementFacade configure(String filename) throws LoggingFacadeException { - _instance = new LoggingFacade(filename); + _instance = new LoggingManagementFacade(filename); return _instance; } - public static LoggingFacade configureAndWatch(String filename, int delay) throws LoggingFacadeException + public static LoggingManagementFacade configureAndWatch(String filename, int delay) throws LoggingFacadeException { - _instance = new LoggingFacade(filename, delay); + _instance = new LoggingManagementFacade(filename, delay); return _instance; } - public static LoggingFacade getCurrentInstance() + public static LoggingManagementFacade getCurrentInstance() { return _instance; } - private LoggingFacade(String filename) + private LoggingManagementFacade(String filename) { DOMConfigurator.configure(filename); if(LOGGER == null) { - LOGGER = Logger.getLogger(LoggingFacade.class); + LOGGER = Logger.getLogger(LoggingManagementFacade.class); } _filename = filename; _delay = 0; } - private LoggingFacade(String filename, int delay) + private LoggingManagementFacade(String filename, int delay) { DOMConfigurator.configureAndWatch(filename, delay); if(LOGGER == null) { - LOGGER = Logger.getLogger(LoggingFacade.class); + LOGGER = Logger.getLogger(LoggingManagementFacade.class); } _filename = filename; diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties b/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties index ac77f674f2..7924be28d3 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties @@ -18,16 +18,21 @@ # # Default File used for all non-defined locales. # -STARTUP = MNG-1001 : Startup +# 0 - Management Type +STARTUP = MNG-1001 : {0} Management Startup # 0 - Service # 1 - Port LISTENING = MNG-1002 : Starting : {0} : Listening on port {1,number,#} # 0 - Service # 1 - Port SHUTTING_DOWN = MNG-1003 : Shutting down : {0} : port {1,number,#} -READY = MNG-1004 : Ready[ : Using the platform JMX Agent] -STOPPED = MNG-1005 : Stopped +# 0 - Management Type +READY = MNG-1004 : {0} Management Ready +# 0 - Management Type +STOPPED = MNG-1005 : {0} Management Stopped # 0 - Path SSL_KEYSTORE = MNG-1006 : Using SSL Keystore : {0} +# 0 - Username OPEN = MNG-1007 : Open : User {0} +# 0 - Username CLOSE = MNG-1008 : Close : User {0}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java index 859d7e2a27..bcb9cb2ac4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java @@ -76,7 +76,7 @@ public class ChannelLogSubject extends AbstractLogSubject setLogStringWithFormat(CHANNEL_FORMAT, connection == null ? -1L : connection.getConnectionId(), session.getAuthorizedPrincipal() == null ? "?" : session.getAuthorizedPrincipal().getName(), - (connection == null || connection.getConfig() == null) ? "?" : connection.getConfig().getAddress(), + (connection == null || connection.getRemoteAddressString() == null) ? "?" : connection.getRemoteAddressString(), session.getVirtualHost().getName(), session.getChannel()); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java index 28c4f0d52a..7611ee1a88 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java @@ -32,11 +32,19 @@ package org.apache.qpid.server.logging.subjects; public class LogSubjectFormat { + private LogSubjectFormat() { } /** + * LOG FORMAT for the ManagementActors, + * 0 - User ID + * 1 - IP[:Port] + */ + public static final String MANAGEMENT_FORMAT = "mng:{0}({1})"; + + /** * LOG FORMAT for the Subscription Log Subject * 0 - Subscription ID */ diff --git a/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java b/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java index 2cc1a92853..e01f20d54f 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java +++ b/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java @@ -342,6 +342,14 @@ public class MessageMetaData_1_0 implements StorableMessageMetaData { private final AMQPDescribedTypeRegistry _typeRegistry = AMQPDescribedTypeRegistry.newInstance(); + private MetaDataFactory() + { + _typeRegistry.registerTransportLayer(); + _typeRegistry.registerMessagingLayer(); + _typeRegistry.registerTransactionLayer(); + _typeRegistry.registerSecurityLayer(); + } + public MessageMetaData_1_0 createMetaData(ByteBuffer buf) { ValueHandler valueHandler = new ValueHandler(_typeRegistry); @@ -354,7 +362,8 @@ public class MessageMetaData_1_0 implements StorableMessageMetaData try { ByteBuffer encodedBuf = buf.duplicate(); - sections.add((Section) valueHandler.parse(buf)); + Object parse = valueHandler.parse(buf); + sections.add((Section) parse); encodedBuf.limit(buf.position()); encodedSections.add(encodedBuf); diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java b/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java index 6000886956..417f6036ab 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java @@ -24,6 +24,9 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.security.group.GroupPrincipalAccessor; + public interface AuthenticationProvider extends ConfiguredObject { @@ -52,4 +55,15 @@ public interface AuthenticationProvider extends ConfiguredObject TYPE)); //children Collection<VirtualHostAlias> getVirtualHostPortBindings(); + + String getName(); + + /** + * A temporary method to create SubjectCreator. + * + * TODO: move all the functionality from SubjectCreator into AuthenticationProvider + */ + SubjectCreator getSubjectCreator(); + + void setGroupAccessor(GroupPrincipalAccessor groupPrincipalAccessor); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java b/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java index 08b01a1b65..fbecf1965b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java @@ -20,12 +20,20 @@ */ package org.apache.qpid.server.model; +import java.net.SocketAddress; import java.security.AccessControlException; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Map; +import org.apache.qpid.server.logging.LogRecorder; +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; + public interface Broker extends ConfiguredObject { @@ -44,9 +52,49 @@ public interface Broker extends ConfiguredObject String STATE = "state"; String TIME_TO_LIVE = "timeToLive"; String UPDATED = "updated"; + String DEFAULT_AUTHENTICATION_PROVIDER = "defaultAuthenticationProvider"; + String DEFAULT_VIRTUAL_HOST = "defaultVirtualHost"; + + String ALERT_THRESHOLD_MESSAGE_AGE = "alertThresholdMessageAge"; + String ALERT_THRESHOLD_MESSAGE_COUNT = "alertThresholdMessageCount"; + String ALERT_THRESHOLD_QUEUE_DEPTH = "alertThresholdQueueDepth"; + String ALERT_THRESHOLD_MESSAGE_SIZE = "alertThresholdMessageSize"; + String ALERT_REPEAT_GAP = "alertRepeatGap"; + String FLOW_CONTROL_SIZE_BYTES = "queueFlowControlSizeBytes"; + String FLOW_CONTROL_RESUME_SIZE_BYTES = "queueFlowResumeSizeBytes"; + String MAXIMUM_DELIVERY_ATTEMPTS = "maximumDeliveryAttempts"; + String DEAD_LETTER_QUEUE_ENABLED = "deadLetterQueueEnabled"; + String HOUSEKEEPING_CHECK_PERIOD = "housekeepingCheckPeriod"; + + String SESSION_COUNT_LIMIT = "sessionCountLimit"; + String HEART_BEAT_DELAY = "heartBeatDelay"; + String STATISTICS_REPORTING_PERIOD = "statisticsReportingPeriod"; + String STATISTICS_REPORTING_RESET_ENABLED = "statisticsReportingResetEnabled"; + + /* + * A temporary attribute to pass the path to ACL file. + * TODO: It should be a part of AuthorizationProvider. + */ + String ACL_FILE = "aclFile"; + + /* + * A temporary attributes to set the broker default key/trust stores. + * TODO: Remove them after adding a full support to configure KeyStore/TrustStore via management layers. + */ + String KEY_STORE_PATH = "keyStorePath"; + String KEY_STORE_PASSWORD = "keyStorePassword"; + String KEY_STORE_CERT_ALIAS = "keyStoreCertAlias"; + String TRUST_STORE_PATH = "trustStorePath"; + String TRUST_STORE_PASSWORD = "trustStorePassword"; + + /* + * A temporary attributes to set the broker group file. + * TODO: Remove them after adding a full support to configure authorization providers via management layers. + */ + String GROUP_FILE = "groupFile"; // Attributes - public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collection<String> AVAILABLE_ATTRIBUTES = Collections.unmodifiableList( Arrays.asList(BUILD_VERSION, BYTES_RETAINED, @@ -62,7 +110,32 @@ public interface Broker extends ConfiguredObject NAME, STATE, TIME_TO_LIVE, - UPDATED)); + UPDATED, + DEFAULT_AUTHENTICATION_PROVIDER, + DEFAULT_VIRTUAL_HOST, + ALERT_THRESHOLD_MESSAGE_AGE, + ALERT_THRESHOLD_MESSAGE_COUNT, + ALERT_THRESHOLD_QUEUE_DEPTH, + ALERT_THRESHOLD_MESSAGE_SIZE, + ALERT_REPEAT_GAP, + FLOW_CONTROL_SIZE_BYTES, + FLOW_CONTROL_RESUME_SIZE_BYTES, + MAXIMUM_DELIVERY_ATTEMPTS, + DEAD_LETTER_QUEUE_ENABLED, + HOUSEKEEPING_CHECK_PERIOD, + SESSION_COUNT_LIMIT, + HEART_BEAT_DELAY, + STATISTICS_REPORTING_PERIOD, + STATISTICS_REPORTING_RESET_ENABLED, + + ACL_FILE, + KEY_STORE_PATH, + KEY_STORE_PASSWORD, + KEY_STORE_CERT_ALIAS, + TRUST_STORE_PATH, + TRUST_STORE_PASSWORD, + GROUP_FILE + )); //children Collection < VirtualHost > getVirtualHosts(); @@ -75,6 +148,49 @@ public interface Broker extends ConfiguredObject LifetimePolicy lifetime, long ttl, Map<String, Object> attributes) throws AccessControlException, IllegalArgumentException; - void deleteVirtualHost(VirtualHost virtualHost) - throws AccessControlException, IllegalStateException; + AuthenticationProvider getDefaultAuthenticationProvider(); + + Collection<GroupProvider> getGroupProviders(); + + /** + * A temporary hack to expose root message logger via broker instance. + * TODO We need a better way to do operational logging, for example, via logging listeners + */ + RootMessageLogger getRootMessageLogger(); + + /** + * A temporary hack to expose security manager via broker instance. + * TODO We need to add and implement an authorization provider configured object instead + */ + SecurityManager getSecurityManager(); + + /** + * TODO: A temporary hack to expose log recorder via broker instance. + */ + LogRecorder getLogRecorder(); + + VirtualHost findVirtualHostByName(String name); + + /** + * Get the SubjectCreator for the given socket address. + * TODO: move the authentication related functionality into host aliases and AuthenticationProviders + * + * @param address The (listening) socket address for which the AuthenticationManager is required + */ + SubjectCreator getSubjectCreator(SocketAddress localAddress); + + Collection<KeyStore> getKeyStores(); + + Collection<TrustStore> getTrustStores(); + + /* + * TODO: Remove this method. Eventually the broker will become a registry. + */ + VirtualHostRegistry getVirtualHostRegistry(); + + KeyStore getDefaultKeyStore(); + + TrustStore getDefaultTrustStore(); + + TaskExecutor getTaskExecutor(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java b/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java index 78b98faffe..bd7da962ba 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java @@ -36,4 +36,5 @@ public interface ConfigurationChangeListener void childRemoved(ConfiguredObject object, ConfiguredObject child); + void attributeSet(ConfiguredObject object, String attributeName, Object oldAttributeValue, Object newAttributeValue); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java b/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java index 414b2d083a..d567a3aa44 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java @@ -25,6 +25,9 @@ import java.util.Collection; import java.util.Map; import java.util.UUID; +/** + * An object that can be "managed" (eg via the web interface) and usually read from configuration. + */ public interface ConfiguredObject { @@ -47,7 +50,7 @@ public interface ConfiguredObject * Attempt to change the name of the object * * Request a change to the name of the object. The caller must pass in the name it believes the object currently - * has. If the current name differes from this expected value, then no name change will occur + * has. If the current name differs from this expected value, then no name change will occur * * @param currentName the name the caller believes the object to have * @param desiredName the name the caller would like the object to have @@ -198,14 +201,25 @@ public interface ConfiguredObject /** - * Return the value for the given attribute + * Return the value for the given attribute name. The actual attribute value + * is returned if the configured object has such attribute set. If not, the + * value is looked default attributes. * - * @param name the name of the attribute - * @return the value of the attribute at the object (or null if the attribute is not set + * @param name + * the name of the attribute + * @return the value of the attribute at the object (or null if the + * attribute value is set neither on object itself no in defaults) */ Object getAttribute(String name); /** + * Return the map containing only explicitly set attributes + * + * @return the map with the attributes + */ + Map<String, Object> getActualAttributes(); + + /** * Set the value of an attribute * * @param name the name of the attribute to be set diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Group.java b/java/broker/src/main/java/org/apache/qpid/server/model/Group.java new file mode 100644 index 0000000000..aacd515107 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/Group.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +public interface Group extends ConfiguredObject +{ + String CREATED = "created"; + String DURABLE = "durable"; + String ID = "id"; + String LIFETIME_POLICY = "lifetimePolicy"; + String NAME = "name"; + String STATE = "state"; + String TIME_TO_LIVE = "timeToLive"; + String UPDATED = "updated"; + + // Attributes + public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collections.unmodifiableList( + Arrays.asList( + ID, + NAME, + STATE, + DURABLE, + LIFETIME_POLICY, + TIME_TO_LIVE, + CREATED, + UPDATED + )); + + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/GroupMember.java b/java/broker/src/main/java/org/apache/qpid/server/model/GroupMember.java new file mode 100644 index 0000000000..6832cc6fa6 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/GroupMember.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +public interface GroupMember extends ConfiguredObject +{ + String CREATED = "created"; + String DURABLE = "durable"; + String ID = "id"; + String LIFETIME_POLICY = "lifetimePolicy"; + String NAME = "name"; + String STATE = "state"; + String TIME_TO_LIVE = "timeToLive"; + String UPDATED = "updated"; + + // Attributes + public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collections.unmodifiableList( + Arrays.asList( + ID, + NAME, + STATE, + DURABLE, + LIFETIME_POLICY, + TIME_TO_LIVE, + CREATED, + UPDATED + )); + + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.java b/java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.java new file mode 100644 index 0000000000..9016f97927 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model; + +import java.security.Principal; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + +public interface GroupProvider extends ConfiguredObject +{ + public static final String ID = "id"; + public static final String DESCRIPTION = "description"; + public static final String NAME = "name"; + public static final String STATE = "state"; + public static final String DURABLE = "durable"; + public static final String LIFETIME_POLICY = "lifetimePolicy"; + public static final String TIME_TO_LIVE = "timeToLive"; + public static final String CREATED = "created"; + public static final String UPDATED = "updated"; + public static final String TYPE = "type"; + + public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collections.unmodifiableList( + Arrays.asList(ID, + NAME, + DESCRIPTION, + STATE, + DURABLE, + LIFETIME_POLICY, + TIME_TO_LIVE, + CREATED, + UPDATED, + TYPE)); + + Set<Principal> getGroupPrincipalsForUser(String username); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java b/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java new file mode 100644 index 0000000000..959714656b --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java @@ -0,0 +1,51 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +public interface KeyStore extends TrustStore +{ + + String CERTIFICATE_ALIAS = "certificateAlias"; + + public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collections.unmodifiableList( + Arrays.asList( + ID, + NAME, + STATE, + DURABLE, + LIFETIME_POLICY, + TIME_TO_LIVE, + CREATED, + UPDATED, + DESCRIPTION, + PATH, + PASSWORD, + TYPE, + KEY_MANAGER_FACTORY_ALGORITHM, + CERTIFICATE_ALIAS + )); + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Model.java b/java/broker/src/main/java/org/apache/qpid/server/model/Model.java index 36179fc105..2c05dce9cb 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/Model.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/Model.java @@ -47,6 +47,10 @@ public class Model addRelationship(Broker.class, VirtualHost.class); addRelationship(Broker.class, Port.class); addRelationship(Broker.class, AuthenticationProvider.class); + addRelationship(Broker.class, GroupProvider.class); + addRelationship(Broker.class, TrustStore.class); + addRelationship(Broker.class, KeyStore.class); + addRelationship(Broker.class, Plugin.class); addRelationship(VirtualHost.class, Exchange.class); addRelationship(VirtualHost.class, Queue.class); @@ -54,6 +58,10 @@ public class Model addRelationship(VirtualHost.class, VirtualHostAlias.class); addRelationship(AuthenticationProvider.class, User.class); + addRelationship(User.class, GroupMember.class); + + addRelationship(GroupProvider.class, Group.class); + addRelationship(Group.class, GroupMember.class); addRelationship(Connection.class, Session.class); diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Plugin.java b/java/broker/src/main/java/org/apache/qpid/server/model/Plugin.java new file mode 100644 index 0000000000..b9503a5841 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/Plugin.java @@ -0,0 +1,52 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +public interface Plugin extends ConfiguredObject +{ + //Hack, using it for the class name only for consistency with the other things. + String CREATED = "created"; + String DURABLE = "durable"; + String ID = "id"; + String LIFETIME_POLICY = "lifetimePolicy"; + String NAME = "name"; + String STATE = "state"; + String TIME_TO_LIVE = "timeToLive"; + String UPDATED = "updated"; + + // Attributes + public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collections.unmodifiableList( + Arrays.asList( + ID, + NAME, + STATE, + DURABLE, + LIFETIME_POLICY, + TIME_TO_LIVE, + CREATED, + UPDATED + )); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Port.java b/java/broker/src/main/java/org/apache/qpid/server/model/Port.java index 50c0ebcd14..2f94c3cab7 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/Port.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/Port.java @@ -39,6 +39,16 @@ public interface Port extends ConfiguredObject String PORT = "port"; String PROTOCOLS = "protocols"; String TRANSPORTS = "transports"; + String TCP_NO_DELAY = "tcpNoDelay"; + String SEND_BUFFER_SIZE = "sendBufferSize"; + String RECEIVE_BUFFER_SIZE = "receiveBufferSize"; + String NEED_CLIENT_AUTH = "needClientAuth"; + String WANT_CLIENT_AUTH = "wantClientAuth"; + + /** + * TODO: rename it to AUTHENTICATION_MANAGER_ID or introduce relationships + */ + String AUTHENTICATION_MANAGER = "authenticationManager"; // Attributes public static final Collection<String> AVAILABLE_ATTRIBUTES = @@ -55,7 +65,13 @@ public interface Port extends ConfiguredObject BINDING_ADDRESS, PORT, PROTOCOLS, - TRANSPORTS + TRANSPORTS, + TCP_NO_DELAY, + SEND_BUFFER_SIZE, + RECEIVE_BUFFER_SIZE, + NEED_CLIENT_AUTH, + WANT_CLIENT_AUTH, + AUTHENTICATION_MANAGER )); @@ -88,4 +104,8 @@ public interface Port extends ConfiguredObject //children Collection<VirtualHostAlias> getVirtualHostBindings(); Collection<Connection> getConnections(); + + AuthenticationProvider getAuthenticationProvider(); + + void setAuthenticationProvider(AuthenticationProvider authenticationProvider); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java b/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java index 5d9de69f9a..6cd5eb23a4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java @@ -20,14 +20,95 @@ */ package org.apache.qpid.server.model; +import java.util.Collection; +import java.util.EnumSet; + +import org.apache.qpid.server.protocol.AmqpProtocolVersion; + public enum Protocol { - AMQP_0_8, - AMQP_0_9, - AMQP_0_9_1, - AMQP_0_10, - AMQP_1_0, - JMX, - HTTP, - HTTPS + AMQP_0_8(ProtocolType.AMQP), + AMQP_0_9(ProtocolType.AMQP), + AMQP_0_9_1(ProtocolType.AMQP), + AMQP_0_10(ProtocolType.AMQP), + AMQP_1_0(ProtocolType.AMQP), + JMX_RMI(ProtocolType.JMX), + HTTP(ProtocolType.HTTP), + HTTPS(ProtocolType.HTTP), + RMI(ProtocolType.RMI); + + private final ProtocolType _protocolType; + + private Protocol(ProtocolType type) + { + _protocolType = type; + } + + public ProtocolType getProtocolType() + { + return _protocolType; + } + + public boolean isAMQP() + { + return _protocolType == ProtocolType.AMQP; + } + + public AmqpProtocolVersion toAmqpProtocolVersion() + { + switch(this) + { + case AMQP_0_8: + return AmqpProtocolVersion.v0_8; + case AMQP_0_9: + return AmqpProtocolVersion.v0_9; + case AMQP_0_9_1: + return AmqpProtocolVersion.v0_9_1; + case AMQP_0_10: + return AmqpProtocolVersion.v0_10; + case AMQP_1_0: + return AmqpProtocolVersion.v1_0_0; + default: + throw new IllegalArgumentException(this + " is not an known AMQP protocol"); + } + } + + public static Protocol valueOfObject(Object protocolObject) + { + Protocol protocol; + if (protocolObject instanceof Protocol) + { + protocol = (Protocol) protocolObject; + } + else + { + try + { + protocol = Protocol.valueOf(String.valueOf(protocolObject)); + } + catch (Exception e) + { + throw new IllegalArgumentException("Can't convert '" + protocolObject + + "' to one of the supported protocols: " + EnumSet.allOf(Protocol.class), e); + } + } + return protocol; + } + + public static boolean hasAmqpProtocol(Collection<Protocol> protocols) + { + for (Protocol protocol : protocols) + { + if (protocol.isAMQP()) + { + return true; + } + } + return false; + } + + public static enum ProtocolType + { + AMQP, HTTP, JMX, RMI; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java b/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java index 03cd46be01..ae6e5ac43a 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java @@ -20,8 +20,32 @@ */ package org.apache.qpid.server.model; +import java.util.EnumSet; + public enum Transport { TCP, - SSL + SSL; + + public static Transport valueOfObject(Object transportObject) + { + Transport transport; + if (transportObject instanceof Transport) + { + transport = (Transport) transportObject; + } + else + { + try + { + transport = Transport.valueOf(String.valueOf(transportObject)); + } + catch (Exception e) + { + throw new IllegalArgumentException("Can't convert '" + transportObject + + "' to one of the supported transports: " + EnumSet.allOf(Transport.class), e); + } + } + return transport; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java b/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java new file mode 100644 index 0000000000..0c322ae02f --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java @@ -0,0 +1,65 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +public interface TrustStore extends ConfiguredObject +{ + String ID = "id"; + String NAME = "name"; + String DURABLE = "durable"; + String LIFETIME_POLICY = "lifetimePolicy"; + String STATE = "state"; + String TIME_TO_LIVE = "timeToLive"; + String CREATED = "created"; + String UPDATED = "updated"; + String DESCRIPTION = "description"; + + String PATH = "path"; + String PASSWORD = "password"; + String TYPE = "type"; + String KEY_MANAGER_FACTORY_ALGORITHM = "keyManagerFactoryAlgorithm"; + + public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collections.unmodifiableList( + Arrays.asList( + ID, + NAME, + STATE, + DURABLE, + LIFETIME_POLICY, + TIME_TO_LIVE, + CREATED, + UPDATED, + DESCRIPTION, + PATH, + PASSWORD, + TYPE, + KEY_MANAGER_FACTORY_ALGORITHM + )); + + public String getPassword(); + + public void setPassword(String password); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java b/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java index 36b6a454dc..bcedd91596 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java @@ -63,6 +63,11 @@ public class UUIDGenerator return createUUID(User.class.getName(), authenticationProviderName, userName); } + public static UUID generateGroupUUID(String groupProviderName, String groupName) + { + return createUUID(Group.class.getName(), groupProviderName, groupName); + } + public static UUID generateVhostUUID(String virtualHostName) { return createUUID(VirtualHost.class.getName(), virtualHostName); @@ -77,4 +82,14 @@ public class UUIDGenerator { return createUUID(Consumer.class.getName(), virtualHostName, queueName, connectionRemoteAddress, channelNumber, consumerName); } + + public static UUID generateGroupMemberUUID(String groupProviderName, String groupName, String groupMemberName) + { + return createUUID(GroupMember.class.getName(), groupProviderName, groupName, groupMemberName); + } + + public static UUID generateBrokerChildUUID(String type, String childName) + { + return createUUID(type, childName); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/User.java b/java/broker/src/main/java/org/apache/qpid/server/model/User.java index d97bf46d31..675dc8f0d3 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/User.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/User.java @@ -52,8 +52,6 @@ public interface User extends ConfiguredObject PASSWORD )); - public String getPassword(); - public void setPassword(String password); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java b/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java index 24a3d43386..5f4ec1d3a8 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java @@ -21,6 +21,9 @@ package org.apache.qpid.server.model; import org.apache.qpid.server.queue.QueueEntry; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.store.MessageStore; + import java.security.AccessControlException; import java.util.Arrays; import java.util.Collection; @@ -60,17 +63,16 @@ public interface VirtualHost extends ConfiguredObject String ALERT_THRESHOLD_QUEUE_DEPTH_BYTES = "alertThresholdQueueDepthBytes"; String ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES = "alertThresholdQueueDepthMessages"; String DEAD_LETTER_QUEUE_ENABLED = "deadLetterQueueEnabled"; - String FEDERATION_TAG = "federationTag"; String HOUSEKEEPING_CHECK_PERIOD = "housekeepingCheckPeriod"; String MAXIMUM_DELIVERY_ATTEMPTS = "maximumDeliveryAttempts"; String QUEUE_FLOW_CONTROL_SIZE_BYTES = "queueFlowControlSizeBytes"; String QUEUE_FLOW_RESUME_SIZE_BYTES = "queueFlowResumeSizeBytes"; - String STORE_CONFIGURATION = "storeConfiguration"; String STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE = "storeTransactionIdleTimeoutClose"; String STORE_TRANSACTION_IDLE_TIMEOUT_WARN = "storeTransactionIdleTimeoutWarn"; String STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE = "storeTransactionOpenTimeoutClose"; String STORE_TRANSACTION_OPEN_TIMEOUT_WARN = "storeTransactionOpenTimeoutWarn"; String STORE_TYPE = "storeType"; + String STORE_PATH = "storePath"; String SUPPORTED_EXCHANGE_TYPES = "supportedExchangeTypes"; String SUPPORTED_QUEUE_TYPES = "supportedQueueTypes"; String CREATED = "created"; @@ -81,6 +83,8 @@ public interface VirtualHost extends ConfiguredObject String STATE = "state"; String TIME_TO_LIVE = "timeToLive"; String UPDATED = "updated"; + String CONFIG_PATH = "configPath"; + // Attributes public static final Collection<String> AVAILABLE_ATTRIBUTES = Collections.unmodifiableList( @@ -96,13 +100,12 @@ public interface VirtualHost extends ConfiguredObject SUPPORTED_EXCHANGE_TYPES, SUPPORTED_QUEUE_TYPES, DEAD_LETTER_QUEUE_ENABLED, - FEDERATION_TAG, HOUSEKEEPING_CHECK_PERIOD, MAXIMUM_DELIVERY_ATTEMPTS, QUEUE_FLOW_CONTROL_SIZE_BYTES, QUEUE_FLOW_RESUME_SIZE_BYTES, STORE_TYPE, - STORE_CONFIGURATION, + STORE_PATH, STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE, STORE_TRANSACTION_IDLE_TIMEOUT_WARN, STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE, @@ -111,7 +114,8 @@ public interface VirtualHost extends ConfiguredObject ALERT_THRESHOLD_MESSAGE_AGE, ALERT_THRESHOLD_MESSAGE_SIZE, ALERT_THRESHOLD_QUEUE_DEPTH_BYTES, - ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES)); + ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES, + CONFIG_PATH)); @@ -149,4 +153,12 @@ public interface VirtualHost extends ConfiguredObject } void executeTransaction(TransactionalOperation op); + + /** + * A temporary hack to expose host security manager. + * TODO We need to add and implement an authorization provider configured object instead + */ + SecurityManager getSecurityManager(); + + MessageStore getMessageStore(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java index 7d6aa9b2cb..73e1f1e970 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java @@ -24,12 +24,18 @@ import java.security.AccessControlException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; + import org.apache.qpid.server.model.ConfigurationChangeListener; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.IllegalStateTransitionException; import org.apache.qpid.server.model.State; +import org.apache.qpid.server.configuration.updater.ChangeStateTask; +import org.apache.qpid.server.configuration.updater.CreateChildTask; +import org.apache.qpid.server.configuration.updater.SetAttributeTask; +import org.apache.qpid.server.configuration.updater.TaskExecutor; abstract class AbstractAdapter implements ConfiguredObject { @@ -40,134 +46,78 @@ abstract class AbstractAdapter implements ConfiguredObject new ArrayList<ConfigurationChangeListener>(); private final UUID _id; + private final Map<String, Object> _defaultAttributes = new HashMap<String, Object>(); + private final TaskExecutor _taskExecutor; - protected AbstractAdapter(UUID id) + protected AbstractAdapter(UUID id, Map<String, Object> defaults, Map<String, Object> attributes, TaskExecutor taskExecutor) { + _taskExecutor = taskExecutor; _id = id; - } - - static String getStringAttribute(String name, Map<String,Object> attributes, String defaultVal) - { - final Object value = attributes.get(name); - return value == null ? defaultVal : String.valueOf(value); - } - - static Map getMapAttribute(String name, Map<String,Object> attributes, Map defaultVal) - { - final Object value = attributes.get(name); - if(value == null) - { - return defaultVal; - } - else if(value instanceof Map) + if (attributes != null) { - return (Map) value; + Collection<String> names = getAttributeNames(); + for (String name : names) + { + if (attributes.containsKey(name)) + { + _attributes.put(name, attributes.get(name)); + } + } } - else + if (defaults != null) { - throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Map"); + _defaultAttributes.putAll(defaults); } } - - static <E extends Enum> E getEnumAttribute(Class<E> clazz, String name, Map<String,Object> attributes, E defaultVal) + protected AbstractAdapter(UUID id, TaskExecutor taskExecutor) { - Object obj = attributes.get(name); - if(obj == null) - { - return defaultVal; - } - else if(clazz.isInstance(obj)) - { - return (E) obj; - } - else if(obj instanceof String) - { - return (E) Enum.valueOf(clazz, (String)obj); - } - else - { - throw new IllegalArgumentException("Value for attribute " + name + " is not of required type " + clazz.getSimpleName()); - } + this(id, null, null, taskExecutor); } - static Boolean getBooleanAttribute(String name, Map<String,Object> attributes, Boolean defaultValue) + public final UUID getId() { - Object obj = attributes.get(name); - if(obj == null) - { - return defaultValue; - } - else if(obj instanceof Boolean) - { - return (Boolean) obj; - } - else if(obj instanceof String) - { - return Boolean.parseBoolean((String) obj); - } - else - { - throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Boolean"); - } + return _id; } - static Integer getIntegerAttribute(String name, Map<String,Object> attributes, Integer defaultValue) + public State getDesiredState() { - Object obj = attributes.get(name); - if(obj == null) - { - return defaultValue; - } - else if(obj instanceof Number) - { - return ((Number) obj).intValue(); - } - else if(obj instanceof String) - { - return Integer.valueOf((String) obj); - } - else - { - throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Integer"); - } + return null; //TODO } - static Long getLongAttribute(String name, Map<String,Object> attributes, Long defaultValue) + @Override + public final State setDesiredState(final State currentState, final State desiredState) + throws IllegalStateTransitionException, AccessControlException { - Object obj = attributes.get(name); - if(obj == null) - { - return defaultValue; - } - else if(obj instanceof Number) + if (_taskExecutor.isTaskExecutorThread()) { - return ((Number) obj).longValue(); - } - else if(obj instanceof String) - { - return Long.valueOf((String) obj); + if (setState(currentState, desiredState)) + { + notifyStateChanged(currentState, desiredState); + } } else { - throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Long"); + _taskExecutor.submitAndWait(new ChangeStateTask(this, currentState, desiredState)); } + return getActualState(); } - public final UUID getId() - { - return _id; - } + /** + * @return true when the state has been successfully updated to desiredState or false otherwise + */ + protected abstract boolean setState(State currentState, State desiredState); - public State getDesiredState() + protected void notifyStateChanged(final State currentState, final State desiredState) { - return null; //TODO - } - - public State setDesiredState(final State currentState, final State desiredState) - throws IllegalStateTransitionException, AccessControlException - { - return null; //TODO + synchronized (_changeListeners) + { + List<ConfigurationChangeListener> copy = new ArrayList<ConfigurationChangeListener>(_changeListeners); + for(ConfigurationChangeListener listener : copy) + { + listener.stateChanged(this, currentState, desiredState); + } + } } public void addChangeListener(final ConfigurationChangeListener listener) @@ -176,7 +126,7 @@ abstract class AbstractAdapter implements ConfiguredObject { throw new NullPointerException("Cannot add a null listener"); } - synchronized (this) + synchronized (_changeListeners) { if(!_changeListeners.contains(listener)) { @@ -191,39 +141,76 @@ abstract class AbstractAdapter implements ConfiguredObject { throw new NullPointerException("Cannot remove a null listener"); } - synchronized (this) + synchronized (_changeListeners) { return _changeListeners.remove(listener); } } - protected void childAdded(ConfiguredObject child) { - synchronized (this) + synchronized (_changeListeners) { - for(ConfigurationChangeListener listener : _changeListeners) + List<ConfigurationChangeListener> copy = new ArrayList<ConfigurationChangeListener>(_changeListeners); + for(ConfigurationChangeListener listener : copy) { listener.childAdded(this, child); } } } - protected void childRemoved(ConfiguredObject child) { - synchronized (this) + synchronized (_changeListeners) { - for(ConfigurationChangeListener listener : _changeListeners) + List<ConfigurationChangeListener> copy = new ArrayList<ConfigurationChangeListener>(_changeListeners); + for(ConfigurationChangeListener listener : copy) { listener.childRemoved(this, child); } } } - public Object getAttribute(final String name) + protected void attributeSet(String attrinuteName, Object oldAttributeValue, Object newAttributeValue) { - synchronized (this) + synchronized (_changeListeners) + { + List<ConfigurationChangeListener> copy = new ArrayList<ConfigurationChangeListener>(_changeListeners); + for(ConfigurationChangeListener listener : copy) + { + listener.attributeSet(this, attrinuteName, oldAttributeValue, newAttributeValue); + } + } + } + + private final Object getDefaultAttribute(String name) + { + return _defaultAttributes.get(name); + } + + @Override + public Object getAttribute(String name) + { + Object value = getActualAttribute(name); + if (value == null) + { + value = getDefaultAttribute(name); + } + return value; + } + + @Override + public final Map<String, Object> getActualAttributes() + { + synchronized (_attributes) + { + return new HashMap<String, Object>(_attributes); + } + } + + private Object getActualAttribute(final String name) + { + synchronized (_attributes) { return _attributes.get(name); } @@ -232,25 +219,41 @@ abstract class AbstractAdapter implements ConfiguredObject public Object setAttribute(final String name, final Object expected, final Object desired) throws IllegalStateException, AccessControlException, IllegalArgumentException { - synchronized (this) + if (_taskExecutor.isTaskExecutorThread()) { - Object currentValue = _attributes.get(name); + if (changeAttribute(name, expected, desired)) + { + attributeSet(name, expected, desired); + } + } + else + { + _taskExecutor.submitAndWait(new SetAttributeTask(this, name, expected, desired)); + } + return getAttribute(name); + } + + protected boolean changeAttribute(final String name, final Object expected, final Object desired) + { + synchronized (_attributes) + { + Object currentValue = getAttribute(name); if((currentValue == null && expected == null) || (currentValue != null && currentValue.equals(expected))) { _attributes.put(name, desired); - return desired; + return true; } else { - return currentValue; + return false; } } } public <T extends ConfiguredObject> T getParent(final Class<T> clazz) { - synchronized (this) + synchronized (_parents) { return (T) _parents.get(clazz); } @@ -258,7 +261,7 @@ abstract class AbstractAdapter implements ConfiguredObject protected <T extends ConfiguredObject> void addParent(Class<T> clazz, T parent) { - synchronized (this) + synchronized (_parents) { _parents.put(clazz, parent); } @@ -280,4 +283,40 @@ abstract class AbstractAdapter implements ConfiguredObject } } + @Override + public String toString() + { + return getClass().getSimpleName() + " [id=" + _id + ", name=" + getName() + "]"; + } + + @SuppressWarnings("unchecked") + @Override + public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + { + if (_taskExecutor.isTaskExecutorThread()) + { + C child = addChild(childClass, attributes, otherParents); + if (child != null) + { + childAdded(child); + } + return child; + } + else + { + return (C)_taskExecutor.submitAndWait(new CreateChildTask(this, childClass, attributes, otherParents)); + } + } + + protected <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + { + throw new UnsupportedOperationException(); + } + + + protected TaskExecutor getTaskExecutor() + { + return _taskExecutor; + } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractKeyStoreAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractKeyStoreAdapter.java new file mode 100644 index 0000000000..ebd98f915d --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractKeyStoreAdapter.java @@ -0,0 +1,198 @@ +/* + * + * 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.model.adapter; + +import java.security.AccessControlException; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.KeyStore; +import org.apache.qpid.server.model.LifetimePolicy; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.Statistics; +import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.server.util.MapValueConverter; + +public abstract class AbstractKeyStoreAdapter extends AbstractAdapter +{ + private String _name; + private String _password; + + protected AbstractKeyStoreAdapter(UUID id, Broker broker, Map<String, Object> attributes) + { + super(id, broker.getTaskExecutor()); + addParent(Broker.class, broker); + _name = MapValueConverter.getStringAttribute(TrustStore.NAME, attributes); + _password = MapValueConverter.getStringAttribute(TrustStore.PASSWORD, attributes); + setMandatoryAttribute(TrustStore.PATH, attributes); + setOptionalAttribute(TrustStore.TYPE, attributes); + setOptionalAttribute(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM, attributes); + setOptionalAttribute(TrustStore.DESCRIPTION, attributes); + } + + @Override + public String getName() + { + return _name; + } + + @Override + public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException + { + throw new IllegalStateException(); + } + + @Override + public State getActualState() + { + return State.ACTIVE; + } + + @Override + public boolean isDurable() + { + return true; + } + + @Override + public void setDurable(boolean durable) throws IllegalStateException, AccessControlException, IllegalArgumentException + { + throw new IllegalStateException(); + } + + @Override + public LifetimePolicy getLifetimePolicy() + { + return LifetimePolicy.PERMANENT; + } + + @Override + public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) throws IllegalStateException, AccessControlException, + IllegalArgumentException + { + throw new IllegalStateException(); + } + + @Override + public long getTimeToLive() + { + return 0; + } + + @Override + public long setTimeToLive(long expected, long desired) throws IllegalStateException, AccessControlException, IllegalArgumentException + { + throw new IllegalStateException(); + } + + @Override + public Statistics getStatistics() + { + return NoStatistics.getInstance(); + } + + @Override + public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz) + { + return Collections.emptySet(); + } + + @Override + public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + { + throw new UnsupportedOperationException(); + } + + @Override + public Object getAttribute(String name) + { + if(KeyStore.ID.equals(name)) + { + return getId(); + } + else if(KeyStore.NAME.equals(name)) + { + return getName(); + } + else if(KeyStore.STATE.equals(name)) + { + return getActualState(); + } + else if(KeyStore.DURABLE.equals(name)) + { + return isDurable(); + } + else if(KeyStore.LIFETIME_POLICY.equals(name)) + { + return getLifetimePolicy(); + } + else if(KeyStore.TIME_TO_LIVE.equals(name)) + { + return getTimeToLive(); + } + else if(KeyStore.CREATED.equals(name)) + { + + } + else if(KeyStore.UPDATED.equals(name)) + { + + } + else if(KeyStore.PASSWORD.equals(name)) + { + return null; // for security reasons we don't expose the password + } + return super.getAttribute(name); + } + + @Override + protected boolean setState(State currentState, State desiredState) + { + return false; + } + + public String getPassword() + { + return _password; + } + + public void setPassword(String password) + { + _password = password; + } + + private void setMandatoryAttribute(String name, Map<String, Object> attributeValues) + { + changeAttribute(name, null, MapValueConverter.getStringAttribute(name, attributeValues)); + } + + private void setOptionalAttribute(String name, Map<String, Object> attributeValues) + { + if (attributeValues.get(name) != null) + { + changeAttribute(name, null, MapValueConverter.getStringAttribute(name, attributeValues)); + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.java new file mode 100644 index 0000000000..ed4af9881f --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.java @@ -0,0 +1,152 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model.adapter; + +import java.security.AccessControlException; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.LifetimePolicy; +import org.apache.qpid.server.model.Plugin; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.Statistics; + +public abstract class AbstractPluginAdapter extends AbstractAdapter implements Plugin +{ + + protected AbstractPluginAdapter(UUID id, Map<String, Object> defaults, Map<String, Object> attributes, TaskExecutor taskExecutor) + { + super(id, defaults, attributes, taskExecutor); + } + + @Override + public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException + { + throw new UnsupportedOperationException(); + } + + @Override + public State getActualState() + { + return null; + } + + @Override + public boolean isDurable() + { + return true; + } + + @Override + public void setDurable(boolean durable) throws IllegalStateException, AccessControlException, IllegalArgumentException + { + throw new UnsupportedOperationException(); + } + + @Override + public LifetimePolicy getLifetimePolicy() + { + return LifetimePolicy.PERMANENT; + } + + @Override + public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) throws IllegalStateException, + AccessControlException, IllegalArgumentException + { + throw new UnsupportedOperationException(); + } + + @Override + public long getTimeToLive() + { + return 0; + } + + @Override + public long setTimeToLive(long expected, long desired) throws IllegalStateException, AccessControlException, + IllegalArgumentException + { + throw new UnsupportedOperationException(); + } + + @Override + public Statistics getStatistics() + { + return null; + } + + @Override + public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz) + { + return Collections.emptyList(); + } + + @Override + public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, + ConfiguredObject... otherParents) + { + throw new UnsupportedOperationException(); + } + + @Override + public Collection<String> getAttributeNames() + { + return AVAILABLE_ATTRIBUTES; + } + + @Override + public Object getAttribute(String name) + { + if (ID.equals(name)) + { + return getId(); + } + else if (STATE.equals(name)) + { + return getActualState(); + } + else if (DURABLE.equals(name)) + { + return isDurable(); + } + else if (LIFETIME_POLICY.equals(name)) + { + return getLifetimePolicy(); + } + else if (TIME_TO_LIVE.equals(name)) + { + return getTimeToLive(); + } + else if (CREATED.equals(name)) + { + + } + else if (UPDATED.equals(name)) + { + + } + return super.getAttribute(name); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java new file mode 100644 index 0000000000..2f7e89bb2b --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java @@ -0,0 +1,251 @@ +/* + * 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.model.adapter; + +import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.security.GeneralSecurityException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import javax.net.ssl.SSLContext; + +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.logging.messages.BrokerMessages; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.KeyStore; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.Protocol; +import org.apache.qpid.server.model.Transport; +import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.protocol.AmqpProtocolVersion; +import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory; +import org.apache.qpid.ssl.SSLContextFactory; +import org.apache.qpid.transport.NetworkTransportConfiguration; +import org.apache.qpid.transport.network.IncomingNetworkTransport; + +public class AmqpPortAdapter extends PortAdapter +{ + private final Broker _broker; + private IncomingNetworkTransport _transport; + + public AmqpPortAdapter(UUID id, Broker broker, Map<String, Object> attributes, Map<String, Object> defaultAttributes, TaskExecutor taskExecutor) + { + super(id, broker, attributes, defaultAttributes, taskExecutor); + _broker = broker; + } + + @Override + protected void onActivate() + { + Collection<Transport> transports = getTransports(); + Set<AmqpProtocolVersion> supported = convertFromModelProtocolsToAmqp(getProtocols()); + + SSLContext sslContext = null; + if (transports.contains(Transport.SSL)) + { + sslContext = createSslContext(); + } + + AmqpProtocolVersion defaultSupportedProtocolReply = getDefaultAmqpSupportedReply(); + + String bindingAddress = (String) getAttribute(Port.BINDING_ADDRESS); + if (WILDCARD_ADDRESS.equals(bindingAddress)) + { + bindingAddress = null; + } + Integer port = (Integer) getAttribute(Port.PORT); + InetSocketAddress bindingSocketAddress = null; + if ( bindingAddress == null ) + { + bindingSocketAddress = new InetSocketAddress(port); + } + else + { + bindingSocketAddress = new InetSocketAddress(bindingAddress, port); + } + + final NetworkTransportConfiguration settings = new ServerNetworkTransportConfiguration( + bindingSocketAddress, (Boolean)getAttribute(TCP_NO_DELAY), + (Integer)getAttribute(SEND_BUFFER_SIZE), (Integer)getAttribute(RECEIVE_BUFFER_SIZE), + (Boolean)getAttribute(NEED_CLIENT_AUTH), (Boolean)getAttribute(WANT_CLIENT_AUTH)); + + _transport = org.apache.qpid.transport.network.Transport.getIncomingTransportInstance(); + final MultiVersionProtocolEngineFactory protocolEngineFactory = new MultiVersionProtocolEngineFactory( + _broker, supported, defaultSupportedProtocolReply); + + _transport.accept(settings, protocolEngineFactory, sslContext); + CurrentActor.get().message(BrokerMessages.LISTENING(getTransports().toString(), getPort())); + } + + @Override + protected void onStop() + { + if (_transport != null) + { + CurrentActor.get().message(BrokerMessages.SHUTTING_DOWN(getTransports().toString(), getPort())); + _transport.close(); + } + } + + private Set<AmqpProtocolVersion> convertFromModelProtocolsToAmqp(Collection<Protocol> modelProtocols) + { + Set<AmqpProtocolVersion> amqpProtocols = new HashSet<AmqpProtocolVersion>(); + for (Protocol protocol : modelProtocols) + { + amqpProtocols.add(protocol.toAmqpProtocolVersion()); + } + return amqpProtocols; + } + + private SSLContext createSslContext() + { + KeyStore keyStore = _broker.getDefaultKeyStore(); + if (keyStore == null) + { + throw new IllegalConfigurationException("SSL was requested on AMQP port '" + + this.getName() + "' but no key store defined"); + } + + TrustStore trustStore = _broker.getDefaultTrustStore(); + if (((Boolean)getAttribute(NEED_CLIENT_AUTH) || (Boolean)getAttribute(WANT_CLIENT_AUTH)) && trustStore == null) + { + throw new IllegalConfigurationException("Client certificate authentication is enabled on AMQP port '" + + this.getName() + "' but no trust store defined"); + } + + String keystorePath = (String)keyStore.getAttribute(KeyStore.PATH); + String keystorePassword = keyStore.getPassword(); + String keystoreType = (String)keyStore.getAttribute(KeyStore.TYPE); + String keyManagerFactoryAlgorithm = (String)keyStore.getAttribute(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM); + String certAlias = (String)keyStore.getAttribute(KeyStore.CERTIFICATE_ALIAS); + + final SSLContext sslContext; + try + { + if(trustStore != null) + { + String trustStorePassword = trustStore.getPassword(); + String trustStoreType = (String)trustStore.getAttribute(TrustStore.TYPE); + String trustManagerFactoryAlgorithm = (String)trustStore.getAttribute(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM); + String trustStorePath = (String)trustStore.getAttribute(TrustStore.PATH); + + sslContext = SSLContextFactory.buildClientContext(trustStorePath, + trustStorePassword, + trustStoreType, + trustManagerFactoryAlgorithm, + keystorePath, + keystorePassword, keystoreType, keyManagerFactoryAlgorithm, + certAlias); + } + else + { + sslContext = SSLContextFactory.buildServerContext(keystorePath, keystorePassword, keystoreType, keyManagerFactoryAlgorithm); + } + } + catch (GeneralSecurityException e) + { + throw new RuntimeException("Unable to create SSLContext for key or trust store", e); + } + catch (IOException e) + { + throw new RuntimeException("Unable to create SSLContext - unable to load key/trust store", e); + } + return sslContext; + } + + private AmqpProtocolVersion getDefaultAmqpSupportedReply() + { + String defaultAmqpSupportedReply = System.getProperty(BrokerProperties.PROPERTY_DEFAULT_SUPPORTED_PROTOCOL_REPLY); + if (defaultAmqpSupportedReply != null) + { + return AmqpProtocolVersion.valueOf(defaultAmqpSupportedReply); + } + return null; + } + + + class ServerNetworkTransportConfiguration implements NetworkTransportConfiguration + { + private final InetSocketAddress _bindingSocketAddress; + private final Boolean _tcpNoDelay; + private final Integer _sendBufferSize; + private final Integer _receiveBufferSize; + private final boolean _needClientAuth; + private final boolean _wantClientAuth; + + public ServerNetworkTransportConfiguration( + InetSocketAddress bindingSocketAddress, boolean tcpNoDelay, + int sendBufferSize, int receiveBufferSize, + boolean needClientAuth, boolean wantClientAuth) + { + _bindingSocketAddress = bindingSocketAddress; + _tcpNoDelay = tcpNoDelay; + _sendBufferSize = sendBufferSize; + _receiveBufferSize = receiveBufferSize; + _needClientAuth = needClientAuth; + _wantClientAuth = wantClientAuth; + } + + @Override + public boolean wantClientAuth() + { + return _wantClientAuth; + } + + @Override + public boolean needClientAuth() + { + return _needClientAuth; + } + + @Override + public Boolean getTcpNoDelay() + { + return _tcpNoDelay; + } + + @Override + public Integer getSendBufferSize() + { + return _sendBufferSize; + } + + @Override + public Integer getReceiveBufferSize() + { + return _receiveBufferSize; + } + + @Override + public InetSocketAddress getAddress() + { + return _bindingSocketAddress; + } + }; +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java index 8c2bc98ba7..ac4b0255d5 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java @@ -29,38 +29,50 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; + import javax.security.auth.login.AccountNotFoundException; import org.apache.log4j.Logger; -import org.apache.qpid.server.model.*; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.IllegalStateTransitionException; +import org.apache.qpid.server.model.LifetimePolicy; +import org.apache.qpid.server.model.PasswordCredentialManagingAuthenticationProvider; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.Statistics; +import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.model.User; +import org.apache.qpid.server.model.VirtualHostAlias; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.access.Operation; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.database.PrincipalDatabase; import org.apache.qpid.server.security.auth.manager.AuthenticationManager; import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.group.GroupPrincipalAccessor; +import org.apache.qpid.server.security.SecurityManager; public abstract class AuthenticationProviderAdapter<T extends AuthenticationManager> extends AbstractAdapter implements AuthenticationProvider { private static final Logger LOGGER = Logger.getLogger(AuthenticationProviderAdapter.class); - private final BrokerAdapter _broker; private final T _authManager; + protected final Broker _broker; - private AuthenticationProviderAdapter(BrokerAdapter brokerAdapter, - final T authManager) - { - super(UUIDGenerator.generateRandomUUID()); - _broker = brokerAdapter; - _authManager = authManager; - } + private GroupPrincipalAccessor _groupAccessor; - public static AuthenticationProviderAdapter createAuthenticationProviderAdapter(BrokerAdapter brokerAdapter, - final AuthenticationManager authManager) + private Object _type; + + private AuthenticationProviderAdapter(UUID id, Broker broker, final T authManager, Map<String, Object> attributes) { - return authManager instanceof PrincipalDatabaseAuthenticationManager - ? new PrincipalDatabaseAuthenticationManagerAdapter(brokerAdapter, (PrincipalDatabaseAuthenticationManager) authManager) - : new SimpleAuthenticationProviderAdapter(brokerAdapter, authManager); + super(id, null, attributes, broker.getTaskExecutor()); + _authManager = authManager; + _broker = broker; + _type = authManager instanceof PrincipalDatabaseAuthenticationManager? PrincipalDatabaseAuthenticationManager.class.getSimpleName() : AuthenticationManager.class.getSimpleName() ; + addParent(Broker.class, broker); } T getAuthManager() @@ -77,7 +89,7 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana @Override public String getName() { - return _authManager.getClass().getSimpleName(); + return (String)getAttribute(AuthenticationProvider.NAME); } @Override @@ -147,7 +159,7 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana { if(TYPE.equals(name)) { - return _authManager.getClass().getSimpleName(); + return _type; } else if(CREATED.equals(name)) { @@ -165,10 +177,6 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana { return LifetimePolicy.PERMANENT; } - else if(NAME.equals(name)) - { - return getName(); - } else if(STATE.equals(name)) { return State.ACTIVE; // TODO @@ -191,44 +199,86 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana } @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, - Map<String, Object> attributes, - ConfiguredObject... otherParents) + public boolean setState(State currentState, State desiredState) + throws IllegalStateTransitionException, AccessControlException { - return null; + if(desiredState == State.DELETED) + { + return true; + } + else if(desiredState == State.ACTIVE) + { + if (_groupAccessor == null) + { + throw new IllegalStateTransitionException("Cannot transit into ACTIVE state with null group accessor!"); + } + _authManager.initialise(); + return true; + } + else if(desiredState == State.STOPPED) + { + _authManager.close(); + return true; + } + return false; } - private static class SimpleAuthenticationProviderAdapter extends AuthenticationProviderAdapter<AuthenticationManager> + @Override + public SubjectCreator getSubjectCreator() { + return new SubjectCreator(_authManager, _groupAccessor); + } + + public void setGroupAccessor(GroupPrincipalAccessor groupAccessor) + { + _groupAccessor = groupAccessor; + } + + public static class SimpleAuthenticationProviderAdapter extends AuthenticationProviderAdapter<AuthenticationManager> + { + public SimpleAuthenticationProviderAdapter( - BrokerAdapter brokerAdapter, AuthenticationManager authManager) + UUID id, Broker broker, AuthenticationManager authManager, Map<String, Object> attributes) + { + super(id, broker,authManager, attributes); + } + + @Override + public <C extends ConfiguredObject> C createChild(Class<C> childClass, + Map<String, Object> attributes, + ConfiguredObject... otherParents) { - super(brokerAdapter,authManager); + throw new UnsupportedOperationException(); } } - private static class PrincipalDatabaseAuthenticationManagerAdapter + public static class PrincipalDatabaseAuthenticationManagerAdapter extends AuthenticationProviderAdapter<PrincipalDatabaseAuthenticationManager> implements PasswordCredentialManagingAuthenticationProvider { public PrincipalDatabaseAuthenticationManagerAdapter( - BrokerAdapter brokerAdapter, PrincipalDatabaseAuthenticationManager authManager) + UUID id, Broker broker, PrincipalDatabaseAuthenticationManager authManager, Map<String, Object> attributes) { - super(brokerAdapter, authManager); + super(id, broker, authManager, attributes); } @Override public boolean createUser(String username, String password, Map<String, String> attributes) { - return getPrincipalDatabase().createPrincipal(new UsernamePrincipal(username), password.toCharArray()); + if(getSecurityManager().authoriseUserOperation(Operation.CREATE, username)) + { + return getPrincipalDatabase().createPrincipal(new UsernamePrincipal(username), password.toCharArray()); + } + else + { + throw new AccessControlException("Do not have permission to create new user"); + } } @Override public void deleteUser(String username) throws AccountNotFoundException { - if(getSecurityManager().authoriseMethod(Operation.DELETE, - "UserManagement", - "deleteUser")) + if(getSecurityManager().authoriseUserOperation(Operation.DELETE, username)) { getPrincipalDatabase().deletePrincipal(new UsernamePrincipal(username)); @@ -239,9 +289,9 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana } } - private org.apache.qpid.server.security.SecurityManager getSecurityManager() + private SecurityManager getSecurityManager() { - return ApplicationRegistry.getInstance().getSecurityManager(); + return _broker.getSecurityManager(); } private PrincipalDatabase getPrincipalDatabase() @@ -252,18 +302,13 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana @Override public void setPassword(String username, String password) throws AccountNotFoundException { - getPrincipalDatabase().updatePassword(new UsernamePrincipal(username), password.toCharArray()); - } - - public void reload() throws IOException - { - if(getSecurityManager().authoriseMethod(Operation.UPDATE, "UserManagement", "reload")) + if(getSecurityManager().authoriseUserOperation(Operation.UPDATE, username)) { - getPrincipalDatabase().reload(); + getPrincipalDatabase().updatePassword(new UsernamePrincipal(username), password.toCharArray()); } else { - throw new AccessControlException("Do not have permission to reload principal database"); + throw new AccessControlException("Do not have permission to set password"); } } @@ -274,34 +319,41 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana Map<String, Map<String,String>> users = new HashMap<String, Map<String, String>>(); for(Principal principal : getPrincipalDatabase().getUsers()) { - users.put(principal.getName(), Collections.EMPTY_MAP); + users.put(principal.getName(), Collections.<String, String>emptyMap()); } return users; } + public void reload() throws IOException + { + getPrincipalDatabase().reload(); + } + @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, + public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) { if(childClass == User.class) { - Principal p = new UsernamePrincipal((String) attributes.get("name")); - if(getSecurityManager().authoriseMethod(Operation.UPDATE, "UserManagement", "createUser")) + String username = (String) attributes.get("name"); + String password = (String) attributes.get("password"); + Principal p = new UsernamePrincipal(username); + + if(createUser(username, password,null)) { - if(getPrincipalDatabase().createPrincipal(p, ((String)attributes.get("password")).toCharArray())) - { - return (C) new PrincipalAdapter(p); - } + @SuppressWarnings("unchecked") + C pricipalAdapter = (C) new PrincipalAdapter(p, getTaskExecutor()); + return pricipalAdapter; } else { - throw new AccessControlException("Do not have permission to create a new user"); + //TODO? Silly interface on the PrincipalDatabase at fault + throw new RuntimeException("Failed to create user"); } - } - return super.createChild(childClass, attributes, otherParents); + return super.addChild(childClass, attributes, otherParents); } @Override @@ -313,9 +365,11 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana Collection<User> principals = new ArrayList<User>(users.size()); for(Principal user : users) { - principals.add(new PrincipalAdapter(user)); + principals.add(new PrincipalAdapter(user, getTaskExecutor())); } - return (Collection<C>) Collections.unmodifiableCollection(principals); + @SuppressWarnings("unchecked") + Collection<C> unmodifiablePrincipals = (Collection<C>) Collections.unmodifiableCollection(principals); + return unmodifiablePrincipals; } else { @@ -328,20 +382,14 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana private final Principal _user; - public PrincipalAdapter(Principal user) + public PrincipalAdapter(Principal user, TaskExecutor taskExecutor) { - super(UUIDGenerator.generateUserUUID(PrincipalDatabaseAuthenticationManagerAdapter.this.getName(), user.getName())); + super(UUIDGenerator.generateUserUUID(PrincipalDatabaseAuthenticationManagerAdapter.this.getName(), user.getName()), taskExecutor); _user = user; } @Override - public String getPassword() - { - return null; - } - - @Override public void setPassword(String password) { try @@ -445,6 +493,10 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana { return getId(); } + else if(PASSWORD.equals(name)) + { + return null; // for security reasons we don't expose the password + } else if(NAME.equals(name)) { return getName(); @@ -453,20 +505,19 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana } @Override - public Object setAttribute(String name, Object expected, Object desired) + public boolean changeAttribute(String name, Object expected, Object desired) throws IllegalStateException, AccessControlException, IllegalArgumentException { if(name.equals(PASSWORD)) { setPassword((String)desired); + return true; } - return super.setAttribute(name, - expected, - desired); + return super.changeAttribute(name, expected, desired); } @Override - public State setDesiredState(State currentState, State desiredState) + protected boolean setState(State currentState, State desiredState) throws IllegalStateTransitionException, AccessControlException { if(desiredState == State.DELETED) @@ -479,9 +530,9 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana { LOGGER.warn("Failed to delete user " + _user, e); } - return State.DELETED; + return true; } - return super.setDesiredState(currentState, desiredState); + return false; } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java new file mode 100644 index 0000000000..e5108ebbcf --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java @@ -0,0 +1,77 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model.adapter; + +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager; +import org.apache.qpid.server.security.group.GroupPrincipalAccessor; +import org.apache.qpid.server.model.adapter.AuthenticationProviderAdapter.PrincipalDatabaseAuthenticationManagerAdapter; +import org.apache.qpid.server.model.adapter.AuthenticationProviderAdapter.SimpleAuthenticationProviderAdapter; + +public class AuthenticationProviderFactory +{ + private final Iterable<AuthenticationManagerFactory> _factories; + + public AuthenticationProviderFactory(QpidServiceLoader<AuthenticationManagerFactory> authManagerFactoryServiceLoader) + { + _factories = authManagerFactoryServiceLoader.atLeastOneInstanceOf(AuthenticationManagerFactory.class); + } + + /** + * Creates {@link AuthenticationProvider} for given ID, {@link Broker} and attributes. + * <p> + * The configured {@link AuthenticationManagerFactory}'s are used to try to create the {@link AuthenticationProvider}. + * The first non-null instance is returned. The factories are used in non-deterministic order. + * @param groupPrincipalAccessor TODO + */ + public AuthenticationProvider create(UUID id, Broker broker, Map<String, Object> attributes, GroupPrincipalAccessor groupPrincipalAccessor) + { + for (AuthenticationManagerFactory factory : _factories) + { + AuthenticationManager manager = factory.createInstance(attributes); + if (manager != null) + { + AuthenticationProviderAdapter<?> authenticationProvider; + if (manager instanceof PrincipalDatabaseAuthenticationManager) + { + authenticationProvider = new PrincipalDatabaseAuthenticationManagerAdapter(id, broker, + (PrincipalDatabaseAuthenticationManager) manager, attributes); + } + else + { + authenticationProvider = new SimpleAuthenticationProviderAdapter(id, broker, manager, attributes); + } + authenticationProvider.setGroupAccessor(groupPrincipalAccessor); + return authenticationProvider; + } + } + + throw new IllegalArgumentException("No authentication provider factory found for configuration attributes " + attributes); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java index abd3160686..eb2d0dd7e2 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java @@ -48,7 +48,7 @@ final class BindingAdapter extends AbstractAdapter implements Binding ExchangeAdapter exchangeAdapter, QueueAdapter queueAdapter) { - super(binding.getId()); + super(binding.getId(), queueAdapter.getTaskExecutor()); _binding = binding; _exchange = exchangeAdapter; _queue = queueAdapter; @@ -206,27 +206,20 @@ final class BindingAdapter extends AbstractAdapter implements Binding } @Override - public Object setAttribute(final String name, final Object expected, final Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - return super.setAttribute(name, expected, desired); //TODO - } - - @Override public Collection<String> getAttributeNames() { return Binding.AVAILABLE_ATTRIBUTES; } @Override - public State setDesiredState(State currentState, State desiredState) throws IllegalStateTransitionException, + protected boolean setState(State currentState, State desiredState) throws IllegalStateTransitionException, AccessControlException { if (desiredState == State.DELETED) { delete(); - return State.DELETED; + return true; } - return super.setDesiredState(currentState, desiredState); + return false; } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java index f1cce2d45c..533ecfe937 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java @@ -21,82 +21,211 @@ package org.apache.qpid.server.model.adapter; import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.security.AccessControlException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; +import java.util.UUID; + +import javax.net.ssl.KeyManagerFactory; + +import org.apache.log4j.Logger; import org.apache.qpid.common.QpidProperties; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.logging.LogRecorder; +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.logging.actors.BrokerActor; +import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.model.AuthenticationProvider; import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfigurationChangeListener; import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.model.KeyStore; import org.apache.qpid.server.model.LifetimePolicy; +import org.apache.qpid.server.model.Plugin; import org.apache.qpid.server.model.Port; -import org.apache.qpid.server.model.Protocol; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.Statistics; -import org.apache.qpid.server.model.Transport; +import org.apache.qpid.server.model.TrustStore; import org.apache.qpid.server.model.UUIDGenerator; import org.apache.qpid.server.model.VirtualHost; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; -import org.apache.qpid.server.security.auth.manager.IAuthenticationManagerRegistry; -import org.apache.qpid.server.transport.QpidAcceptor; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.security.group.FileGroupManager; +import org.apache.qpid.server.security.group.GroupManager; +import org.apache.qpid.server.security.group.GroupPrincipalAccessor; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.stats.StatisticsGatherer; +import org.apache.qpid.server.util.MapValueConverter; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; -public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHostRegistry.RegistryChangeListener, - IApplicationRegistry.PortBindingListener, - IAuthenticationManagerRegistry.RegistryChangeListener +public class BrokerAdapter extends AbstractAdapter implements Broker, ConfigurationChangeListener { - - private final IApplicationRegistry _applicationRegistry; - private String _name; - private final Map<org.apache.qpid.server.virtualhost.VirtualHost, VirtualHostAdapter> _vhostAdapters = - new HashMap<org.apache.qpid.server.virtualhost.VirtualHost, VirtualHostAdapter>(); - private final StatisticsAdapter _statistics; - private final Map<QpidAcceptor, PortAdapter> _portAdapters = new HashMap<QpidAcceptor, PortAdapter>(); - private Collection<HTTPPortAdapter> _httpManagementPorts; - - private final Map<AuthenticationManager, AuthenticationProviderAdapter> _authManagerAdapters = - new HashMap<AuthenticationManager, AuthenticationProviderAdapter>(); - - - public BrokerAdapter(final IApplicationRegistry instance) - { - super(UUIDGenerator.generateRandomUUID()); - _applicationRegistry = instance; - _name = "Broker"; - _statistics = new StatisticsAdapter(instance); - - instance.getVirtualHostRegistry().addRegistryChangeListener(this); - populateVhosts(); - instance.addPortBindingListener(this); - populatePorts(); - instance.addRegistryChangeListener(this); - populateAuthenticationManagers(); - } - - private void populateVhosts() - { - synchronized(_vhostAdapters) - { - Collection<org.apache.qpid.server.virtualhost.VirtualHost> actualVhosts = - _applicationRegistry.getVirtualHostRegistry().getVirtualHosts(); - for(org.apache.qpid.server.virtualhost.VirtualHost vh : actualVhosts) - { - if(!_vhostAdapters.containsKey(vh)) - { - _vhostAdapters.put(vh, new VirtualHostAdapter(this, vh)); - } - } - + private static final Logger LOGGER = Logger.getLogger(BrokerAdapter.class); + + @SuppressWarnings("serial") + public static final Map<String, Class<?>> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Class<?>>(){{ + put(ALERT_THRESHOLD_MESSAGE_AGE, Long.class); + put(ALERT_THRESHOLD_MESSAGE_COUNT, Long.class); + put(ALERT_THRESHOLD_QUEUE_DEPTH, Long.class); + put(ALERT_THRESHOLD_MESSAGE_SIZE, Long.class); + put(ALERT_REPEAT_GAP, Long.class); + put(FLOW_CONTROL_SIZE_BYTES, Long.class); + put(FLOW_CONTROL_RESUME_SIZE_BYTES, Long.class); + put(HOUSEKEEPING_CHECK_PERIOD, Long.class); + + put(DEAD_LETTER_QUEUE_ENABLED, Boolean.class); + put(STATISTICS_REPORTING_RESET_ENABLED, Boolean.class); + + put(MAXIMUM_DELIVERY_ATTEMPTS, Integer.class); + put(SESSION_COUNT_LIMIT, Integer.class); + put(HEART_BEAT_DELAY, Integer.class); + put(STATISTICS_REPORTING_PERIOD, Integer.class); + + put(ACL_FILE, String.class); + put(NAME, String.class); + put(DEFAULT_VIRTUAL_HOST, String.class); + put(DEFAULT_AUTHENTICATION_PROVIDER, String.class); + + put(KEY_STORE_PATH, String.class); + put(KEY_STORE_PASSWORD, String.class); + put(KEY_STORE_CERT_ALIAS, String.class); + put(TRUST_STORE_PATH, String.class); + put(TRUST_STORE_PASSWORD, String.class); + put(GROUP_FILE, String.class); + }}); + + public static final int DEFAULT_STATISTICS_REPORTING_PERIOD = 0; + public static final boolean DEFAULT_STATISTICS_REPORTING_RESET_ENABLED = false; + public static final long DEFAULT_ALERT_REPEAT_GAP = 30000l; + public static final long DEFAULT_ALERT_THRESHOLD_MESSAGE_AGE = 0l; + public static final long DEFAULT_ALERT_THRESHOLD_MESSAGE_COUNT = 0l; + public static final long DEFAULT_ALERT_THRESHOLD_MESSAGE_SIZE = 0l; + public static final long DEFAULT_ALERT_THRESHOLD_QUEUE_DEPTH = 0l; + public static final boolean DEFAULT_DEAD_LETTER_QUEUE_ENABLED = false; + public static final int DEFAULT_MAXIMUM_DELIVERY_ATTEMPTS = 0; + public static final long DEFAULT_FLOW_CONTROL_RESUME_SIZE_BYTES = 0l; + public static final long DEFAULT_FLOW_CONTROL_SIZE_BYTES = 0l; + public static final long DEFAULT_HOUSEKEEPING_CHECK_PERIOD = 30000l; + public static final int DEFAULT_HEART_BEAT_DELAY = 0; + public static final int DEFAULT_SESSION_COUNT_LIMIT = 256; + public static final String DEFAULT_NAME = "QpidBroker"; + private static final String DEFAULT_KEY_STORE_NAME = "defaultKeyStore"; + private static final String DEFAULT_TRUST_STORE_NAME = "defaultTrustStore"; + private static final String DEFAULT_GROUP_PROFIDER_NAME = "defaultGroupProvider"; + + private static final String DUMMY_PASSWORD_MASK = "********"; + + @SuppressWarnings("serial") + private static final Map<String, Object> DEFAULTS = Collections.unmodifiableMap(new HashMap<String, Object>(){{ + put(Broker.STATISTICS_REPORTING_PERIOD, DEFAULT_STATISTICS_REPORTING_PERIOD); + put(Broker.STATISTICS_REPORTING_RESET_ENABLED, DEFAULT_STATISTICS_REPORTING_RESET_ENABLED); + put(Broker.ALERT_REPEAT_GAP, DEFAULT_ALERT_REPEAT_GAP); + put(Broker.ALERT_THRESHOLD_MESSAGE_AGE, DEFAULT_ALERT_THRESHOLD_MESSAGE_AGE); + put(Broker.ALERT_THRESHOLD_MESSAGE_COUNT, DEFAULT_ALERT_THRESHOLD_MESSAGE_COUNT); + put(Broker.ALERT_THRESHOLD_MESSAGE_SIZE, DEFAULT_ALERT_THRESHOLD_MESSAGE_SIZE); + put(Broker.ALERT_THRESHOLD_QUEUE_DEPTH, DEFAULT_ALERT_THRESHOLD_QUEUE_DEPTH); + put(Broker.DEAD_LETTER_QUEUE_ENABLED, DEFAULT_DEAD_LETTER_QUEUE_ENABLED); + put(Broker.MAXIMUM_DELIVERY_ATTEMPTS, DEFAULT_MAXIMUM_DELIVERY_ATTEMPTS); + put(Broker.FLOW_CONTROL_RESUME_SIZE_BYTES, DEFAULT_FLOW_CONTROL_RESUME_SIZE_BYTES); + put(Broker.FLOW_CONTROL_SIZE_BYTES, DEFAULT_FLOW_CONTROL_SIZE_BYTES); + put(Broker.HOUSEKEEPING_CHECK_PERIOD, DEFAULT_HOUSEKEEPING_CHECK_PERIOD); + put(Broker.HEART_BEAT_DELAY, DEFAULT_HEART_BEAT_DELAY); + put(Broker.SESSION_COUNT_LIMIT, DEFAULT_SESSION_COUNT_LIMIT); + put(Broker.NAME, DEFAULT_NAME); + }}); + + + + + private final StatisticsGatherer _statisticsGatherer; + private final VirtualHostRegistry _virtualHostRegistry; + private final LogRecorder _logRecorder; + private final RootMessageLogger _rootMessageLogger; + private StatisticsAdapter _statistics; + + private final Map<String, VirtualHost> _vhostAdapters = new HashMap<String, VirtualHost>(); + private final Map<Integer, Port> _portAdapters = new HashMap<Integer, Port>(); + private final Map<String, AuthenticationProvider> _authenticationProviders = new HashMap<String, AuthenticationProvider>(); + private final Map<String, GroupProvider> _groupProviders = new HashMap<String, GroupProvider>(); + private final Map<UUID, ConfiguredObject> _plugins = new HashMap<UUID, ConfiguredObject>(); + private final Map<UUID, KeyStore> _keyStores = new HashMap<UUID, KeyStore>(); + private final Map<UUID, TrustStore> _trustStores = new HashMap<UUID, TrustStore>(); + + private final AuthenticationProviderFactory _authenticationProviderFactory; + private AuthenticationProvider _defaultAuthenticationProvider; + + private final PortFactory _portFactory; + private final SecurityManager _securityManager; + private final UUID _defaultKeyStoreId; + private final UUID _defaultTrustStoreId; + + public BrokerAdapter(UUID id, Map<String, Object> attributes, StatisticsGatherer statisticsGatherer, VirtualHostRegistry virtualHostRegistry, + LogRecorder logRecorder, RootMessageLogger rootMessageLogger, AuthenticationProviderFactory authenticationProviderFactory, + PortFactory portFactory, TaskExecutor taskExecutor) + { + super(id, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), taskExecutor); + _statisticsGatherer = statisticsGatherer; + _virtualHostRegistry = virtualHostRegistry; + _logRecorder = logRecorder; + _rootMessageLogger = rootMessageLogger; + _statistics = new StatisticsAdapter(statisticsGatherer); + _authenticationProviderFactory = authenticationProviderFactory; + _portFactory = portFactory; + _securityManager = new SecurityManager((String)getAttribute(ACL_FILE)); + + _defaultKeyStoreId = UUIDGenerator.generateBrokerChildUUID(KeyStore.class.getSimpleName(), DEFAULT_KEY_STORE_NAME); + _defaultTrustStoreId = UUIDGenerator.generateBrokerChildUUID(TrustStore.class.getSimpleName(), DEFAULT_TRUST_STORE_NAME); + createBrokerChildrenFromAttributes(); + } + + /* + * A temporary method to create broker children that can be only configured via broker attributes + */ + private void createBrokerChildrenFromAttributes() + { + String groupFile = (String) getAttribute(GROUP_FILE); + if (groupFile != null) + { + GroupManager groupManager = new FileGroupManager(groupFile); + UUID groupProviderId = UUIDGenerator.generateBrokerChildUUID(GroupProvider.class.getSimpleName(), + DEFAULT_GROUP_PROFIDER_NAME); + GroupProviderAdapter groupProviderAdapter = new GroupProviderAdapter(groupProviderId, groupManager, this); + addGroupProvider(groupProviderAdapter); + } + Map<String, Object> actualAttributes = getActualAttributes(); + String keyStorePath = (String) getAttribute(KEY_STORE_PATH); + if (keyStorePath != null) + { + Map<String, Object> keyStoreAttributes = new HashMap<String, Object>(); + keyStoreAttributes.put(KeyStore.NAME, DEFAULT_KEY_STORE_NAME); + keyStoreAttributes.put(KeyStore.PATH, keyStorePath); + keyStoreAttributes.put(KeyStore.PASSWORD, (String) actualAttributes.get(KEY_STORE_PASSWORD)); + keyStoreAttributes.put(KeyStore.TYPE, java.security.KeyStore.getDefaultType()); + keyStoreAttributes.put(KeyStore.CERTIFICATE_ALIAS, getAttribute(KEY_STORE_CERT_ALIAS)); + keyStoreAttributes.put(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM, KeyManagerFactory.getDefaultAlgorithm()); + KeyStoreAdapter KeyStoreAdapter = new KeyStoreAdapter(_defaultKeyStoreId, this, keyStoreAttributes); + addKeyStore(KeyStoreAdapter); + } + String trustStorePath = (String) getAttribute(TRUST_STORE_PATH); + if (trustStorePath != null) + { + Map<String, Object> trsustStoreAttributes = new HashMap<String, Object>(); + trsustStoreAttributes.put(TrustStore.NAME, DEFAULT_TRUST_STORE_NAME); + trsustStoreAttributes.put(TrustStore.PATH, trustStorePath); + trsustStoreAttributes.put(TrustStore.PASSWORD, (String) actualAttributes.get(TRUST_STORE_PASSWORD)); + trsustStoreAttributes.put(TrustStore.TYPE, java.security.KeyStore.getDefaultType()); + trsustStoreAttributes.put(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM, KeyManagerFactory.getDefaultAlgorithm()); + TrustStoreAdapter trustStore = new TrustStoreAdapter(_defaultTrustStoreId, this, trsustStoreAttributes); + addTrustStore(trustStore); } } - public Collection<VirtualHost> getVirtualHosts() { synchronized(_vhostAdapters) @@ -105,81 +234,57 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos } } - private void populatePorts() + + public Collection<Port> getPorts() { synchronized (_portAdapters) { - Map<InetSocketAddress, QpidAcceptor> acceptors = _applicationRegistry.getAcceptors(); - - for(Map.Entry<InetSocketAddress, QpidAcceptor> entry : acceptors.entrySet()) - { - if(!_portAdapters.containsKey(entry.getValue())) - { - _portAdapters.put(entry.getValue(), new PortAdapter(this, entry.getValue(), entry.getKey())); - } - } - if(_applicationRegistry.useHTTPManagement() || _applicationRegistry.useHTTPSManagement()) - { - ArrayList<HTTPPortAdapter> httpPorts = new ArrayList<HTTPPortAdapter>(); - if (_applicationRegistry.useHTTPManagement()) - { - httpPorts.add(new HTTPPortAdapter(this, _applicationRegistry.getHTTPManagementPort())); - } - if (_applicationRegistry.useHTTPSManagement()) - { - httpPorts.add(new HTTPPortAdapter(this, _applicationRegistry.getHTTPSManagementPort(), Protocol.HTTPS, Transport.SSL)); - } - _httpManagementPorts = Collections.unmodifiableCollection(httpPorts); - } + final ArrayList<Port> ports = new ArrayList<Port>(_portAdapters.values()); + return ports; } } - public Collection<Port> getPorts() + public Collection<AuthenticationProvider> getAuthenticationProviders() { - synchronized (_portAdapters) + synchronized (_authenticationProviders) { - final ArrayList<Port> ports = new ArrayList<Port>(_portAdapters.values()); - if(_httpManagementPorts != null) - { - ports.addAll(_httpManagementPorts); - } - return ports; + return new ArrayList<AuthenticationProvider>(_authenticationProviders.values()); } } - private void populateAuthenticationManagers() + public AuthenticationProvider getAuthenticationProviderByName(String authenticationProviderName) { - synchronized (_authManagerAdapters) + Collection<AuthenticationProvider> providers = getAuthenticationProviders(); + for (AuthenticationProvider authenticationProvider : providers) { - IAuthenticationManagerRegistry authenticationManagerRegistry = - _applicationRegistry.getAuthenticationManagerRegistry(); - if(authenticationManagerRegistry != null) + if (authenticationProvider.getName().equals(authenticationProviderName)) { - Map<String, AuthenticationManager> authenticationManagers = - authenticationManagerRegistry.getAvailableAuthenticationManagers(); - - for(Map.Entry<String, AuthenticationManager> entry : authenticationManagers.entrySet()) - { - if(!_authManagerAdapters.containsKey(entry.getValue())) - { - _authManagerAdapters.put(entry.getValue(), - AuthenticationProviderAdapter.createAuthenticationProviderAdapter(this, - entry.getValue())); - } - } + return authenticationProvider; } } + return null; } - public Collection<AuthenticationProvider> getAuthenticationProviders() + @Override + public AuthenticationProvider getDefaultAuthenticationProvider() + { + return _defaultAuthenticationProvider; + } + + public void setDefaultAuthenticationProvider(AuthenticationProvider provider) + { + _defaultAuthenticationProvider = provider; + } + + @Override + public Collection<GroupProvider> getGroupProviders() { - synchronized (_authManagerAdapters) + synchronized (_groupProviders) { - final ArrayList<AuthenticationProvider> authManagers = - new ArrayList<AuthenticationProvider>(_authManagerAdapters.values()); - return authManagers; + final ArrayList<GroupProvider> groupManagers = + new ArrayList<GroupProvider>(_groupProviders.values()); + return groupManagers; } - } public VirtualHost createVirtualHost(final String name, @@ -193,22 +298,29 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos return null; //TODO } - public VirtualHost createVirtualHost(final Map<String, Object> attributes) + private VirtualHost createVirtualHost(final Map<String, Object> attributes) throws AccessControlException, IllegalArgumentException { - return null; //TODO + final VirtualHostAdapter virtualHostAdapter = new VirtualHostAdapter(UUID.randomUUID(), attributes, this, + _statisticsGatherer, getTaskExecutor()); + addVirtualHost(virtualHostAdapter); + virtualHostAdapter.setDesiredState(State.INITIALISING, State.ACTIVE); + return virtualHostAdapter; } - public void deleteVirtualHost(final VirtualHost vhost) - throws AccessControlException, IllegalStateException + private boolean deleteVirtualHost(final VirtualHost vhost) throws AccessControlException, IllegalStateException { - //TODO - throw new UnsupportedOperationException("Not yet implemented"); + synchronized (_vhostAdapters) + { + _vhostAdapters.remove(vhost); + } + vhost.removeChangeListener(this); + return true; } public String getName() { - return _name; + return (String)getAttribute(NAME); } public String setName(final String currentName, final String desiredName) @@ -262,6 +374,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos return _statistics; } + @SuppressWarnings("unchecked") @Override public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz) { @@ -277,12 +390,30 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos { return (Collection<C>) getAuthenticationProviders(); } + else if(clazz == GroupProvider.class) + { + return (Collection<C>) getGroupProviders(); + } + else if(clazz == KeyStore.class) + { + return (Collection<C>) getKeyStores(); + } + else if(clazz == TrustStore.class) + { + return (Collection<C>) getTrustStores(); + } + else if(clazz == Plugin.class) + { + return (Collection<C>) getPlugins(); + } return Collections.emptySet(); } + //TODO: ACL + @SuppressWarnings("unchecked") @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) { if(childClass == VirtualHost.class) { @@ -302,111 +433,107 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos } } - private Port createPort(Map<String, Object> attributes) + private void addPort(Port port) { - // TODO - return null; + synchronized (_portAdapters) + { + int portNumber = port.getPort(); + if(_portAdapters.containsKey(portNumber)) + { + throw new IllegalArgumentException("Cannot add port " + port + " because port number " + portNumber + " already configured"); + } + _portAdapters.put(portNumber, port); + } + port.addChangeListener(this); } - private AuthenticationProvider createAuthenticationProvider(Map<String,Object> attributes) + private Port createPort(Map<String, Object> attributes) { - // TODO - return null; + Port port = _portFactory.createPort(UUID.randomUUID(), this, attributes); + addPort(port); + return port; } + private AuthenticationProvider createAuthenticationProvider(Map<String, Object> attributes) + { + // it's cheap to create the groupPrincipalAccessor on the fly + GroupPrincipalAccessor groupPrincipalAccessor = new GroupPrincipalAccessor(_groupProviders.values()); + + AuthenticationProvider authenticationProvider = _authenticationProviderFactory.create(UUID.randomUUID(), this, attributes, groupPrincipalAccessor); + addAuthenticationProvider(authenticationProvider); + return authenticationProvider; + } - public void virtualHostRegistered(org.apache.qpid.server.virtualhost.VirtualHost virtualHost) + /** + * @throws IllegalConfigurationException if an AuthenticationProvider with the same name already exists + */ + private void addAuthenticationProvider(AuthenticationProvider authenticationProvider) { - VirtualHostAdapter adapter = null; - synchronized (_vhostAdapters) + String name = authenticationProvider.getName(); + synchronized (_authenticationProviders) { - if(!_vhostAdapters.containsKey(virtualHost)) + if(_authenticationProviders.containsKey(name)) { - adapter = new VirtualHostAdapter(this, virtualHost); - _vhostAdapters.put(virtualHost, adapter); + throw new IllegalConfigurationException("Cannot add AuthenticationProvider because one with name " + name + " already exists"); } + _authenticationProviders.put(name, authenticationProvider); } - if(adapter != null) - { - childAdded(adapter); - } + authenticationProvider.addChangeListener(this); } - public void virtualHostUnregistered(org.apache.qpid.server.virtualhost.VirtualHost virtualHost) + private void addGroupProvider(GroupProvider groupProvider) { - VirtualHostAdapter adapter = null; - - synchronized (_vhostAdapters) - { - adapter = _vhostAdapters.remove(virtualHost); - } - if(adapter != null) + synchronized (_groupProviders) { - childRemoved(adapter); + String name = groupProvider.getName(); + if(_groupProviders.containsKey(name)) + { + throw new IllegalConfigurationException("Cannot add GroupProvider because one with name " + name + " already exists"); + } + _groupProviders.put(name, groupProvider); } + groupProvider.addChangeListener(this); } - @Override - public void authenticationManagerRegistered(AuthenticationManager authenticationManager) + private boolean deleteGroupProvider(GroupProvider object) + { + throw new UnsupportedOperationException("Not implemented yet!"); + } + + private void addKeyStore(KeyStore keyStore) { - AuthenticationProviderAdapter adapter = null; - synchronized (_authManagerAdapters) + synchronized (_keyStores) { - if(!_authManagerAdapters.containsKey(authenticationManager)) + if(_keyStores.containsKey(keyStore.getId())) { - adapter = - AuthenticationProviderAdapter.createAuthenticationProviderAdapter(this, authenticationManager); - _authManagerAdapters.put(authenticationManager, adapter); + throw new IllegalConfigurationException("Cannot add KeyStore because one with id " + keyStore.getId() + " already exists"); } + _keyStores.put(keyStore.getId(), keyStore); } - if(adapter != null) - { - childAdded(adapter); - } + keyStore.addChangeListener(this); } - @Override - public void authenticationManagerUnregistered(AuthenticationManager authenticationManager) + private boolean deleteKeyStore(KeyStore object) { - AuthenticationProviderAdapter adapter; - synchronized (_authManagerAdapters) - { - adapter = _authManagerAdapters.remove(authenticationManager); - } - if(adapter != null) - { - childRemoved(adapter); - } + throw new UnsupportedOperationException("Not implemented yet!"); } - - @Override - public void bound(QpidAcceptor acceptor, InetSocketAddress bindAddress) + private void addTrustStore(TrustStore trustStore) { - synchronized (_portAdapters) + synchronized (_trustStores) { - if(!_portAdapters.containsKey(acceptor)) + if(_trustStores.containsKey(trustStore.getId())) { - PortAdapter adapter = new PortAdapter(this, acceptor, bindAddress); - _portAdapters.put(acceptor, adapter); - childAdded(adapter); + throw new IllegalConfigurationException("Cannot add TrustStore because one with id " + trustStore.getId() + " already exists"); } + _trustStores.put(trustStore.getId(), trustStore); } + trustStore.addChangeListener(this); } - @Override - public void unbound(QpidAcceptor acceptor) + private boolean deleteTrustStore(TrustStore object) { - PortAdapter adapter = null; - - synchronized (_portAdapters) - { - adapter = _portAdapters.remove(acceptor); - } - if(adapter != null) - { - childRemoved(adapter); - } + throw new UnsupportedOperationException("Not implemented yet!"); } @Override @@ -422,10 +549,6 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos { return getId(); } - else if(NAME.equals(name)) - { - return getName(); - } else if(STATE.equals(name)) { return State.ACTIVE; @@ -481,14 +604,316 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos { // TODO } + else if (DEFAULT_AUTHENTICATION_PROVIDER.equals(name)) + { + return _defaultAuthenticationProvider == null ? null : _defaultAuthenticationProvider.getName(); + } + else if (KEY_STORE_PASSWORD.equals(name)) + { + return DUMMY_PASSWORD_MASK; + } + else if (TRUST_STORE_PASSWORD.equals(name)) + { + return DUMMY_PASSWORD_MASK; + } + return super.getAttribute(name); + } - return super.getAttribute(name); //TODO - Implement. + private boolean deletePort(Port portAdapter) + { + Port removedPort = null; + synchronized (_portAdapters) + { + removedPort = _portAdapters.remove(portAdapter.getPort()); + } + return removedPort != null; + } + + private boolean deleteAuthenticationProvider(AuthenticationProvider authenticationProvider) + { + AuthenticationProvider removedAuthenticationProvider = null; + synchronized (_authenticationProviders) + { + removedAuthenticationProvider = _authenticationProviders.remove(authenticationProvider.getName()); + } + return removedAuthenticationProvider != null; + } + + private void addVirtualHost(VirtualHost virtualHost) + { + synchronized (_vhostAdapters) + { + String name = virtualHost.getName(); + if (_vhostAdapters.containsKey(name)) + { + throw new IllegalConfigurationException("Virtual host with name " + name + " is already specified!"); + } + _vhostAdapters.put(name, virtualHost); + } + virtualHost.addChangeListener(this); } @Override - public Object setAttribute(String name, Object expected, Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException + public boolean setState(State currentState, State desiredState) + { + if (desiredState == State.ACTIVE) + { + changeState(_groupProviders, currentState, State.ACTIVE, false); + changeState(_authenticationProviders, currentState, State.ACTIVE, false); + + CurrentActor.set(new BrokerActor(getRootMessageLogger())); + try + { + changeState(_vhostAdapters, currentState, State.ACTIVE, false); + } + finally + { + CurrentActor.remove(); + } + + changeState(_portAdapters, currentState,State.ACTIVE, false); + changeState(_plugins, currentState,State.ACTIVE, false); + return true; + } + else if (desiredState == State.STOPPED) + { + changeState(_plugins, currentState,State.STOPPED, true); + changeState(_portAdapters, currentState, State.STOPPED, true); + changeState(_vhostAdapters,currentState, State.STOPPED, true); + changeState(_authenticationProviders, currentState, State.STOPPED, true); + changeState(_groupProviders, currentState, State.STOPPED, true); + return true; + } + return false; + } + + private void changeState(Map<?, ? extends ConfiguredObject> configuredObjectMap, State currentState, State desiredState, boolean swallowException) + { + synchronized(configuredObjectMap) + { + Collection<? extends ConfiguredObject> adapters = configuredObjectMap.values(); + for (ConfiguredObject configuredObject : adapters) + { + if (State.ACTIVE.equals(desiredState) && State.QUIESCED.equals(configuredObject.getActualState())) + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug(configuredObject + " cannot be activated as it is " +State.QUIESCED); + } + continue; + } + try + { + configuredObject.setDesiredState(currentState, desiredState); + } + catch(RuntimeException e) + { + if (swallowException) + { + LOGGER.error("Failed to stop " + configuredObject, e); + } + else + { + throw e; + } + } + } + } + } + + @Override + public void stateChanged(ConfiguredObject object, State oldState, State newState) + { + if(newState == State.DELETED) + { + boolean childDeleted = false; + if(object instanceof AuthenticationProvider) + { + childDeleted = deleteAuthenticationProvider((AuthenticationProvider)object); + } + else if(object instanceof Port) + { + childDeleted = deletePort((Port)object); + } + else if(object instanceof VirtualHost) + { + childDeleted = deleteVirtualHost((VirtualHost)object); + } + else if(object instanceof GroupProvider) + { + childDeleted = deleteGroupProvider((GroupProvider)object); + } + else if(object instanceof KeyStore) + { + childDeleted = deleteKeyStore((KeyStore)object); + } + else if(object instanceof TrustStore) + { + childDeleted = deleteTrustStore((TrustStore)object); + } + if(childDeleted) + { + childRemoved(object); + } + } + } + + @Override + public void childAdded(ConfiguredObject object, ConfiguredObject child) + { + // no-op + } + + @Override + public void childRemoved(ConfiguredObject object, ConfiguredObject child) + { + // no-op + } + + @Override + public void attributeSet(ConfiguredObject object, String attributeName, Object oldAttributeValue, Object newAttributeValue) + { + // no-op + } + + private void addPlugin(ConfiguredObject plugin) + { + synchronized(_plugins) + { + if (_plugins.containsKey(plugin.getId())) + { + throw new IllegalConfigurationException("Plugin with id '" + plugin.getId() + "' is already registered!"); + } + _plugins.put(plugin.getId(), plugin); + } + plugin.addChangeListener(this); + } + + + private Collection<ConfiguredObject> getPlugins() + { + synchronized(_plugins) + { + return Collections.unmodifiableCollection(_plugins.values()); + } + } + + public void recoverChild(ConfiguredObject object) + { + if(object instanceof AuthenticationProvider) + { + addAuthenticationProvider((AuthenticationProvider)object); + } + else if(object instanceof Port) + { + addPort((Port)object); + } + else if(object instanceof VirtualHost) + { + addVirtualHost((VirtualHost)object); + } + else if(object instanceof GroupProvider) + { + addGroupProvider((GroupProvider)object); + } + else if(object instanceof KeyStore) + { + addKeyStore((KeyStore)object); + } + else if(object instanceof TrustStore) + { + addTrustStore((TrustStore)object); + } + else if(object instanceof Plugin) + { + addPlugin(object); + } + else + { + throw new IllegalArgumentException("Attempted to recover unexpected type of configured object: " + object.getClass().getName()); + } + } + + @Override + public RootMessageLogger getRootMessageLogger() + { + return _rootMessageLogger; + } + + @Override + public SecurityManager getSecurityManager() + { + return _securityManager; + } + + @Override + public LogRecorder getLogRecorder() + { + return _logRecorder; + } + + @Override + public VirtualHost findVirtualHostByName(String name) + { + return _vhostAdapters.get(name); + } + + @Override + public SubjectCreator getSubjectCreator(SocketAddress localAddress) + { + InetSocketAddress inetSocketAddress = (InetSocketAddress)localAddress; + AuthenticationProvider provider = _defaultAuthenticationProvider; + Collection<Port> ports = getPorts(); + for (Port p : ports) + { + if (inetSocketAddress.getPort() == p.getPort()) + { + provider = p.getAuthenticationProvider(); + break; + } + } + return provider.getSubjectCreator(); + } + + @Override + public Collection<KeyStore> getKeyStores() + { + synchronized(_trustStores) + { + return Collections.unmodifiableCollection(_keyStores.values()); + } + } + + @Override + public Collection<TrustStore> getTrustStores() + { + synchronized(_trustStores) + { + return Collections.unmodifiableCollection(_trustStores.values()); + } + } + + @Override + public VirtualHostRegistry getVirtualHostRegistry() + { + return _virtualHostRegistry; + } + + @Override + public KeyStore getDefaultKeyStore() + { + return _keyStores.get(_defaultKeyStoreId); + } + + @Override + public TrustStore getDefaultTrustStore() + { + return _trustStores.get(_defaultTrustStoreId); + } + + @Override + public TaskExecutor getTaskExecutor() { - return super.setAttribute(name, expected, desired); //TODO - Implement. + return super.getTaskExecutor(); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java index 5439f6a560..84f99e1f17 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java @@ -38,6 +38,7 @@ import org.apache.qpid.server.model.Session; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.Statistics; import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.stats.StatisticsGatherer; @@ -50,9 +51,9 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection new HashMap<AMQSessionModel, SessionAdapter>(); private final Statistics _statistics; - public ConnectionAdapter(final AMQConnectionModel conn) + public ConnectionAdapter(final AMQConnectionModel conn, TaskExecutor taskExecutor) { - super(UUIDGenerator.generateRandomUUID()); + super(UUIDGenerator.generateRandomUUID(), taskExecutor); _connection = conn; _statistics = new ConnectionStatisticsAdapter(conn); } @@ -74,7 +75,7 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection { if(!_sessionAdapters.containsKey(session)) { - _sessionAdapters.put(session, new SessionAdapter(session)); + _sessionAdapters.put(session, new SessionAdapter(session, getTaskExecutor())); } } return new ArrayList<Session>(_sessionAdapters.values()); @@ -199,52 +200,6 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection } @Override - public Object setAttribute(String name, Object expected, Object desired) throws IllegalStateException, AccessControlException, IllegalArgumentException - { - if(name.equals(CLIENT_ID)) - { - - } - else if(name.equals(CLIENT_VERSION)) - { - - } - else if(name.equals(INCOMING)) - { - - } - else if(name.equals(LOCAL_ADDRESS)) - { - - } - else if(name.equals(PRINCIPAL)) - { - - } - else if(name.equals(PROPERTIES)) - { - - } - else if(name.equals(REMOTE_ADDRESS)) - { - - } - else if(name.equals(REMOTE_PROCESS_NAME)) - { - - } - else if(name.equals(REMOTE_PROCESS_PID)) - { - - } - else if(name.equals(SESSION_COUNT_LIMIT)) - { - - } - return super.setAttribute(name, expected, desired); - } - - @Override public Collection<String> getAttributeNames() { final HashSet<String> attrNames = new HashSet<String>(super.getAttributeNames()); @@ -270,7 +225,8 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection } } - public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + @Override + public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) { if(childClass == Session.class) { @@ -310,4 +266,11 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection return super.getStatistic(name); } } + + @Override + protected boolean setState(State currentState, State desiredState) + { + // TODO: add state management + return false; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java index 031d518670..e6d3fab2f8 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java @@ -45,7 +45,7 @@ public class ConsumerAdapter extends AbstractAdapter implements Consumer queueAdapter.getName(), subscription.getSessionModel().getConnectionModel().getRemoteAddressString(), String.valueOf(subscription.getSessionModel().getChannelId()), - subscription.getConsumerName())); + subscription.getConsumerName()), queueAdapter.getTaskExecutor()); _subscription = subscription; _queue = queueAdapter; _statistics = new ConsumerStatistics(); @@ -108,13 +108,6 @@ public class ConsumerAdapter extends AbstractAdapter implements Consumer } @Override - public Object setAttribute(final String name, final Object expected, final Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - return super.setAttribute(name, expected, desired); //TODO - } - - @Override public Object getAttribute(final String name) { if(ID.equals(name)) @@ -222,4 +215,11 @@ public class ConsumerAdapter extends AbstractAdapter implements Consumer return null; // TODO - Implement } } + + @Override + protected boolean setState(State currentState, State desiredState) + { + // TODO : Add state management + return false; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java index df0f29fbc3..5d5f3f7378 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java @@ -33,16 +33,15 @@ import org.apache.qpid.AMQSecurityException; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.exchange.ExchangeType; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.Exchange; -import org.apache.qpid.server.model.IllegalStateTransitionException; import org.apache.qpid.server.model.LifetimePolicy; import org.apache.qpid.server.model.Publisher; import org.apache.qpid.server.model.Queue; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.Statistics; import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.util.MapValueConverter; import org.apache.qpid.server.virtualhost.VirtualHost; final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apache.qpid.server.exchange.Exchange.BindingListener @@ -57,7 +56,7 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa public ExchangeAdapter(final VirtualHostAdapter virtualHostAdapter, final org.apache.qpid.server.exchange.Exchange exchange) { - super(exchange.getId()); + super(exchange.getId(), virtualHostAdapter.getTaskExecutor()); _statistics = new ExchangeStatistics(); _vhost = virtualHostAdapter; _exchange = exchange; @@ -113,8 +112,8 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa throws AccessControlException, IllegalStateException { attributes = new HashMap<String, Object>(attributes); - String bindingKey = getStringAttribute(org.apache.qpid.server.model.Binding.NAME, attributes, ""); - Map<String, Object> bindingArgs = getMapAttribute(org.apache.qpid.server.model.Binding.ARGUMENTS, attributes, Collections.EMPTY_MAP); + String bindingKey = MapValueConverter.getStringAttribute(org.apache.qpid.server.model.Binding.NAME, attributes, ""); + Map<String, Object> bindingArgs = MapValueConverter.getMapAttribute(org.apache.qpid.server.model.Binding.ARGUMENTS, attributes, Collections.<String,Object>emptyMap()); attributes.remove(org.apache.qpid.server.model.Binding.NAME); attributes.remove(org.apache.qpid.server.model.Binding.ARGUMENTS); @@ -257,7 +256,7 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa } @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) { if(childClass == org.apache.qpid.server.model.Binding.class) { @@ -369,28 +368,20 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa } @Override - public Object setAttribute(String name, Object expected, Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - return super.setAttribute(name, expected, desired); //TODO - Implement - } - - @Override public Collection<String> getAttributeNames() { return AVAILABLE_ATTRIBUTES; } @Override - public State setDesiredState(State currentState, State desiredState) throws IllegalStateTransitionException, - AccessControlException + protected boolean setState(State currentState, State desiredState) { if (desiredState == State.DELETED) { delete(); - return State.DELETED; + return true; } - return super.setDesiredState(currentState, desiredState); + return false; } private class ExchangeStatistics implements Statistics diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java new file mode 100644 index 0000000000..0fa834bc28 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java @@ -0,0 +1,550 @@ +/* + * 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.model.adapter; + +import java.security.AccessControlException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Group; +import org.apache.qpid.server.model.GroupMember; +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.model.IllegalStateTransitionException; +import org.apache.qpid.server.model.LifetimePolicy; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.Statistics; +import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.security.access.Operation; +import org.apache.qpid.server.security.group.GroupManager; +import org.apache.qpid.server.security.SecurityManager; + +public class GroupProviderAdapter extends AbstractAdapter implements + GroupProvider +{ + private final GroupManager _groupManager; + private final Broker _broker; + public GroupProviderAdapter(UUID id, GroupManager groupManager, Broker broker) + { + super(id, broker.getTaskExecutor()); + + if (groupManager == null) + { + throw new IllegalArgumentException("GroupManager must not be null"); + } + _groupManager = groupManager; + _broker = broker; + addParent(Broker.class, broker); + } + + @Override + public String getName() + { + return _groupManager.getClass().getSimpleName(); + } + + @Override + public String setName(String currentName, String desiredName) + throws IllegalStateException, AccessControlException + { + return null; + } + + @Override + public State getActualState() + { + return null; + } + + @Override + public boolean isDurable() + { + return true; + } + + @Override + public void setDurable(boolean durable) throws IllegalStateException, + AccessControlException, IllegalArgumentException + { + } + + @Override + public LifetimePolicy getLifetimePolicy() + { + return LifetimePolicy.PERMANENT; + } + + @Override + public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, + LifetimePolicy desired) throws IllegalStateException, + AccessControlException, IllegalArgumentException + { + return null; + } + + @Override + public long getTimeToLive() + { + return 0; + } + + @Override + public long setTimeToLive(long expected, long desired) + throws IllegalStateException, AccessControlException, + IllegalArgumentException + { + return 0; + } + + @Override + public Statistics getStatistics() + { + return NoStatistics.getInstance(); + } + + @Override + public Collection<String> getAttributeNames() + { + return GroupProvider.AVAILABLE_ATTRIBUTES; + } + + @Override + public Object getAttribute(String name) + { + if (TYPE.equals(name)) + { + return getName(); + } + else if (CREATED.equals(name)) + { + // TODO + } + else if (DURABLE.equals(name)) + { + return true; + } + else if (ID.equals(name)) + { + return getId(); + } + else if (LIFETIME_POLICY.equals(name)) + { + return LifetimePolicy.PERMANENT; + } + else if (NAME.equals(name)) + { + return getName(); + } + else if (STATE.equals(name)) + { + return State.ACTIVE; // TODO + } + else if (TIME_TO_LIVE.equals(name)) + { + // TODO + } + else if (UPDATED.equals(name)) + { + // TODO + } + return super.getAttribute(name); + } + + @Override + public <C extends ConfiguredObject> C addChild(Class<C> childClass, + Map<String, Object> attributes, ConfiguredObject... otherParents) + { + if (childClass == Group.class) + { + String groupName = (String) attributes.get(Group.NAME); + + if (getSecurityManager().authoriseGroupOperation(Operation.CREATE, groupName)) + { + _groupManager.createGroup(groupName); + return (C) new GroupAdapter(groupName, getTaskExecutor()); + } + else + { + throw new AccessControlException("Do not have permission" + + " to create new group"); + } + } + + throw new IllegalArgumentException( + "This group provider does not support creating children of type: " + + childClass); + } + + @SuppressWarnings("unchecked") + @Override + public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz) + { + if (clazz == Group.class) + { + Set<Principal> groups = _groupManager.getGroupPrincipals(); + Collection<Group> principals = new ArrayList<Group>(groups.size()); + for (Principal group : groups) + { + principals.add(new GroupAdapter(group.getName(), getTaskExecutor())); + } + return (Collection<C>) Collections + .unmodifiableCollection(principals); + } + else + { + return null; + } + } + + private SecurityManager getSecurityManager() + { + return _broker.getSecurityManager(); + } + + private class GroupAdapter extends AbstractAdapter implements Group + { + private final String _group; + + public GroupAdapter(String group, TaskExecutor taskExecutor) + { + super(UUIDGenerator.generateGroupUUID(GroupProviderAdapter.this.getName(), group), taskExecutor); + _group = group; + + } + + @Override + public String getName() + { + return _group; + } + + @Override + public String setName(String currentName, String desiredName) + throws IllegalStateException, AccessControlException + { + throw new IllegalStateException("Names cannot be updated"); + } + + @Override + public State getActualState() + { + return State.ACTIVE; + } + + @Override + public boolean isDurable() + { + return true; + } + + @Override + public void setDurable(boolean durable) throws IllegalStateException, + AccessControlException, IllegalArgumentException + { + throw new IllegalStateException("Durability cannot be updated"); + } + + @Override + public LifetimePolicy getLifetimePolicy() + { + return LifetimePolicy.PERMANENT; + } + + @Override + public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, + LifetimePolicy desired) throws IllegalStateException, + AccessControlException, IllegalArgumentException + { + throw new IllegalStateException("LifetimePolicy cannot be updated"); + } + + @Override + public long getTimeToLive() + { + return 0; + } + + @Override + public long setTimeToLive(long expected, long desired) + throws IllegalStateException, AccessControlException, + IllegalArgumentException + { + throw new IllegalStateException("ttl cannot be updated"); + } + + @Override + public Statistics getStatistics() + { + return NoStatistics.getInstance(); + } + + @Override + public <C extends ConfiguredObject> Collection<C> getChildren( + Class<C> clazz) + { + if (clazz == GroupMember.class) + { + Set<Principal> usersInGroup = _groupManager + .getUserPrincipalsForGroup(_group); + Collection<GroupMember> members = new ArrayList<GroupMember>(); + for (Principal principal : usersInGroup) + { + members.add(new GroupMemberAdapter(principal.getName(), getTaskExecutor())); + } + return (Collection<C>) Collections + .unmodifiableCollection(members); + } + else + { + return null; + } + + } + + @Override + public <C extends ConfiguredObject> C addChild(Class<C> childClass, + Map<String, Object> attributes, + ConfiguredObject... otherParents) + { + if (childClass == GroupMember.class) + { + String memberName = (String) attributes.get(GroupMember.NAME); + + if (getSecurityManager().authoriseGroupOperation(Operation.UPDATE, _group)) + { + _groupManager.addUserToGroup(memberName, _group); + return (C) new GroupMemberAdapter(memberName, getTaskExecutor()); + } + else + { + throw new AccessControlException("Do not have permission" + + " to add new group member"); + } + } + + throw new IllegalArgumentException( + "This group provider does not support creating children of type: " + + childClass); + } + + @Override + public Collection<String> getAttributeNames() + { + return Group.AVAILABLE_ATTRIBUTES; + } + + @Override + public Object getAttribute(String name) + { + if (ID.equals(name)) + { + return getId(); + } + else if (NAME.equals(name)) + { + return getName(); + } + return super.getAttribute(name); + } + + @Override + protected boolean setState(State currentState, State desiredState) + throws IllegalStateTransitionException, AccessControlException + { + if (desiredState == State.DELETED) + { + if (getSecurityManager().authoriseGroupOperation(Operation.DELETE, _group)) + { + _groupManager.removeGroup(_group); + return true; + } + else + { + throw new AccessControlException("Do not have permission to delete group"); + } + } + + return false; + } + + private class GroupMemberAdapter extends AbstractAdapter implements + GroupMember + { + private String _memberName; + + public GroupMemberAdapter(String memberName, TaskExecutor taskExecutor) + { + super(UUIDGenerator.generateGroupMemberUUID(GroupProviderAdapter.this.getName(), _group, memberName), taskExecutor); + _memberName = memberName; + } + + @Override + public Collection<String> getAttributeNames() + { + return GroupMember.AVAILABLE_ATTRIBUTES; + } + + @Override + public Object getAttribute(String name) + { + if (ID.equals(name)) + { + return getId(); + } + else if (NAME.equals(name)) + { + return getName(); + } + return super.getAttribute(name); + } + + @Override + public String getName() + { + return _memberName; + } + + @Override + public String setName(String currentName, String desiredName) + throws IllegalStateException, AccessControlException + { + return null; + } + + @Override + public State getActualState() + { + return null; + } + + @Override + public boolean isDurable() + { + return false; + } + + @Override + public void setDurable(boolean durable) + throws IllegalStateException, AccessControlException, + IllegalArgumentException + { + } + + @Override + public LifetimePolicy getLifetimePolicy() + { + return null; + } + + @Override + public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, + LifetimePolicy desired) throws IllegalStateException, + AccessControlException, IllegalArgumentException + { + return null; + } + + @Override + public long getTimeToLive() + { + return 0; + } + + @Override + public long setTimeToLive(long expected, long desired) + throws IllegalStateException, AccessControlException, + IllegalArgumentException + { + return 0; + } + + @Override + public Statistics getStatistics() + { + return NoStatistics.getInstance(); + } + + @Override + public <C extends ConfiguredObject> Collection<C> getChildren( + Class<C> clazz) + { + return null; + } + + @Override + public <C extends ConfiguredObject> C createChild( + Class<C> childClass, Map<String, Object> attributes, + ConfiguredObject... otherParents) + { + return null; + } + + @Override + protected boolean setState(State currentState, State desiredState) + throws IllegalStateTransitionException, + AccessControlException + { + if (desiredState == State.DELETED) + { + if (getSecurityManager().authoriseGroupOperation(Operation.UPDATE, _group)) + { + _groupManager.removeUserFromGroup(_memberName, _group); + return true; + } + else + { + throw new AccessControlException("Do not have permission to remove group member"); + } + } + return false; + } + + } + } + + @Override + protected boolean setState(State currentState, State desiredState) + { + if (desiredState == State.ACTIVE) + { + return true; + } + else if (desiredState == State.STOPPED) + { + return true; + } + // TODO: DELETE state is ignored for now + // in case if we need to delete group provider, then we need AuthenticationProvider to be a change listener of it + // in order to remove deleted group provider from its group provider list + return false; + } + + public Set<Principal> getGroupPrincipalsForUser(String username) + { + return _groupManager.getGroupPrincipalsForUser(username); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java deleted file mode 100644 index 823d27160b..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * - * 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.model.adapter; - -import java.security.AccessControlException; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import org.apache.qpid.server.model.ConfiguredObject; -import org.apache.qpid.server.model.Connection; -import org.apache.qpid.server.model.LifetimePolicy; -import org.apache.qpid.server.model.Port; -import org.apache.qpid.server.model.Protocol; -import org.apache.qpid.server.model.State; -import org.apache.qpid.server.model.Statistics; -import org.apache.qpid.server.model.Transport; -import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.model.VirtualHostAlias; - -public class HTTPPortAdapter extends AbstractAdapter implements Port -{ - private final BrokerAdapter _broker; - private final int _port; - private final Protocol _protocol; - private final Transport _transport; - - public HTTPPortAdapter(BrokerAdapter brokerAdapter, int port) - { - this(brokerAdapter, port, Protocol.HTTP, Transport.TCP); - } - - public HTTPPortAdapter(BrokerAdapter brokerAdapter, int port, Protocol protocol, Transport transport) - { - super(UUIDGenerator.generateRandomUUID()); - _broker = brokerAdapter; - _port = port; - _protocol = protocol; - _transport = transport; - } - - @Override - public String getBindingAddress() - { - return "0.0.0.0"; - } - - @Override - public int getPort() - { - return _port; - } - - @Override - public Collection<Transport> getTransports() - { - return Collections.singleton(_transport); - } - - @Override - public void addTransport(Transport transport) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - throw new IllegalStateException(); // TODO - Implement - } - - @Override - public Transport removeTransport(Transport transport) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - throw new IllegalStateException(); // TODO - Implement - } - - @Override - public Collection<Protocol> getProtocols() - { - return Collections.singleton(_protocol); - } - - @Override - public void addProtocol(Protocol protocol) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - throw new IllegalStateException(); // TODO - Implement - } - - @Override - public Protocol removeProtocol(Protocol protocol) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - throw new IllegalStateException(); // TODO - Implement - } - - @Override - public Collection<VirtualHostAlias> getVirtualHostBindings() - { - return Collections.emptySet(); - } - - @Override - public Collection<Connection> getConnections() - { - return Collections.emptySet(); // TODO - Implement - } - - @Override - public String getName() - { - return getBindingAddress() + ":" + getPort(); // TODO - Implement - } - - @Override - public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException - { - throw new IllegalStateException(); // TODO - Implement - } - - @Override - public State getActualState() - { - return State.ACTIVE; - } - - @Override - public boolean isDurable() - { - return false; // TODO - Implement - } - - @Override - public void setDurable(boolean durable) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - throw new IllegalStateException(); - } - - @Override - public LifetimePolicy getLifetimePolicy() - { - return LifetimePolicy.PERMANENT; - } - - @Override - public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - throw new IllegalStateException(); // TODO - Implement - } - - @Override - public long getTimeToLive() - { - return 0; // TODO - Implement - } - - @Override - public long setTimeToLive(long expected, long desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - throw new IllegalStateException(); // TODO - Implement - } - - @Override - public Statistics getStatistics() - { - return NoStatistics.getInstance(); - } - - @Override - public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz) - { - if(clazz == Connection.class) - { - return (Collection<C>) getConnections(); - } - else - { - return Collections.emptySet(); - } - } - - @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) - { - throw new UnsupportedOperationException(); - } - - @Override - public Object getAttribute(String name) - { - if(ID.equals(name)) - { - return getId(); - } - else if(NAME.equals(name)) - { - return getName(); - } - else if(STATE.equals(name)) - { - return getActualState(); - } - else if(DURABLE.equals(name)) - { - return isDurable(); - } - else if(LIFETIME_POLICY.equals(name)) - { - return getLifetimePolicy(); - } - else if(TIME_TO_LIVE.equals(name)) - { - return getTimeToLive(); - } - else if(CREATED.equals(name)) - { - - } - else if(UPDATED.equals(name)) - { - - } - else if(BINDING_ADDRESS.equals(name)) - { - return getBindingAddress(); - } - else if(PORT.equals(name)) - { - return getPort(); - } - else if(PROTOCOLS.equals(name)) - { - return getProtocols(); - } - else if(TRANSPORTS.equals(name)) - { - return getTransports(); - } - - return super.getAttribute(name); //TODO - Implement - } - - @Override - public Collection<String> getAttributeNames() - { - return AVAILABLE_ATTRIBUTES; - } - - @Override - public Object setAttribute(String name, Object expected, Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - return super.setAttribute(name, expected, desired); //TODO - Implement - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java new file mode 100644 index 0000000000..113d895e62 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java @@ -0,0 +1,48 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model.adapter; + +import java.util.Collection; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.KeyStore; + +public class KeyStoreAdapter extends AbstractKeyStoreAdapter implements KeyStore +{ + + public KeyStoreAdapter(UUID id, Broker broker, Map<String, Object> attributes) + { + super(id, broker, attributes); + if (attributes.get(CERTIFICATE_ALIAS) != null) + { + changeAttribute(CERTIFICATE_ALIAS, null, attributes.get(CERTIFICATE_ALIAS)); + } + } + + @Override + public Collection<String> getAttributeNames() + { + return AVAILABLE_ATTRIBUTES; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java index 7653fcc9b9..c4a531c923 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java @@ -21,7 +21,16 @@ package org.apache.qpid.server.model.adapter; +import java.security.AccessControlException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.Connection; import org.apache.qpid.server.model.LifetimePolicy; @@ -30,119 +39,82 @@ import org.apache.qpid.server.model.Protocol; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.Statistics; import org.apache.qpid.server.model.Transport; -import org.apache.qpid.server.model.UUIDGenerator; import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.model.VirtualHostAlias; -import org.apache.qpid.server.protocol.AmqpProtocolVersion; -import org.apache.qpid.server.transport.QpidAcceptor; - -import java.net.InetSocketAddress; -import java.security.AccessControlException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import org.apache.qpid.server.configuration.updater.TaskExecutor; public class PortAdapter extends AbstractAdapter implements Port { - private final BrokerAdapter _broker; - private final QpidAcceptor _acceptor; - private final InetSocketAddress _address; - private final Collection<Protocol> _protocols; - - public PortAdapter(BrokerAdapter brokerAdapter, QpidAcceptor acceptor, InetSocketAddress address) - { - super(UUIDGenerator.generateRandomUUID()); - _broker = brokerAdapter; - _acceptor = acceptor; - _address = address; - List<Protocol> protocols = new ArrayList<Protocol>(); + private final Broker _broker; + private AuthenticationProvider _authenticationProvider; - for(AmqpProtocolVersion pv : _acceptor.getSupported()) - { - switch(pv) - { - case v0_8: - protocols.add(Protocol.AMQP_0_8); - break; - case v0_9: - protocols.add(Protocol.AMQP_0_9); - break; - case v0_9_1: - protocols.add(Protocol.AMQP_0_9_1); - break; - case v0_10: - protocols.add(Protocol.AMQP_0_10); - break; - case v1_0_0: - protocols.add(Protocol.AMQP_1_0); - break; - } - } + /* + * TODO register PortAceptor as a listener. For supporting multiple + * protocols on the same port we need to introduce a special entity like + * PortAceptor which will be responsible for port binding/unbinding + */ + public PortAdapter(UUID id, Broker broker, Map<String, Object> attributes, Map<String, Object> defaults, TaskExecutor taskExecutor) + { + super(id, defaults, attributes, taskExecutor); + _broker = broker; - _protocols = Collections.unmodifiableCollection(protocols); + addParent(Broker.class, broker); } @Override public String getBindingAddress() { - return _address.getHostName(); + return (String)getAttribute(BINDING_ADDRESS); } @Override public int getPort() { - return _address.getPort(); + return (Integer)getAttribute(PORT); } + @SuppressWarnings("unchecked") @Override public Collection<Transport> getTransports() { - switch (_acceptor.getTransport()) - { - case TCP: - return Collections.singleton(Transport.TCP); - case SSL: - return Collections.singleton(Transport.SSL); - } - - return null; // TODO - Implement + return (Collection<Transport>)getAttribute(TRANSPORTS); } @Override public void addTransport(Transport transport) throws IllegalStateException, AccessControlException, IllegalArgumentException { - throw new IllegalStateException(); // TODO - Implement + throw new IllegalStateException(); } @Override public Transport removeTransport(Transport transport) throws IllegalStateException, AccessControlException, IllegalArgumentException { - throw new IllegalStateException(); // TODO - Implement + throw new IllegalStateException(); } + @SuppressWarnings("unchecked") @Override public Collection<Protocol> getProtocols() { - return _protocols; + return (Collection<Protocol>)getAttribute(PROTOCOLS); } @Override public void addProtocol(Protocol protocol) throws IllegalStateException, AccessControlException, IllegalArgumentException { - throw new IllegalStateException(); // TODO - Implement + throw new IllegalStateException(); } @Override public Protocol removeProtocol(Protocol protocol) throws IllegalStateException, AccessControlException, IllegalArgumentException { - throw new IllegalStateException(); // TODO - Implement + throw new IllegalStateException(); } @Override @@ -165,31 +137,36 @@ public class PortAdapter extends AbstractAdapter implements Port @Override public Collection<Connection> getConnections() { - return null; // TODO - Implement + return null; } @Override public String getName() { - return getBindingAddress() + ":" + getPort(); // TODO - Implement + return (String)getAttribute(NAME); } @Override public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException { - throw new IllegalStateException(); // TODO - Implement + throw new IllegalStateException(); } @Override public State getActualState() { - return State.ACTIVE; + State state = (State)super.getAttribute(STATE); + if (state == null) + { + return State.ACTIVE; + } + return state; } @Override public boolean isDurable() { - return false; // TODO - Implement + return false; } @Override @@ -209,20 +186,20 @@ public class PortAdapter extends AbstractAdapter implements Port public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) throws IllegalStateException, AccessControlException, IllegalArgumentException { - throw new IllegalStateException(); // TODO - Implement + throw new IllegalStateException(); } @Override public long getTimeToLive() { - return 0; // TODO - Implement + return 0; } @Override public long setTimeToLive(long expected, long desired) throws IllegalStateException, AccessControlException, IllegalArgumentException { - throw new IllegalStateException(); // TODO - Implement + throw new IllegalStateException(); } @Override @@ -257,10 +234,6 @@ public class PortAdapter extends AbstractAdapter implements Port { return getId(); } - else if(NAME.equals(name)) - { - return getName(); - } else if(STATE.equals(name)) { return getActualState(); @@ -285,36 +258,54 @@ public class PortAdapter extends AbstractAdapter implements Port { } - else if(BINDING_ADDRESS.equals(name)) - { - return getBindingAddress(); - } - else if(PORT.equals(name)) + return super.getAttribute(name); + } + + @Override + public Collection<String> getAttributeNames() + { + return AVAILABLE_ATTRIBUTES; + } + + @Override + public boolean setState(State currentState, State desiredState) + { + if (desiredState == State.DELETED) { - return getPort(); + return true; } - else if(PROTOCOLS.equals(name)) + else if (desiredState == State.ACTIVE) { - return getProtocols(); + onActivate(); + return true; } - else if(TRANSPORTS.equals(name)) + else if (desiredState == State.STOPPED) { - return getTransports(); + onStop(); + return true; } + return false; + } - return super.getAttribute(name); //TODO - Implement + protected void onActivate() + { + // no-op: expected to be overridden by subclass } - @Override - public Collection<String> getAttributeNames() + protected void onStop() { - return AVAILABLE_ATTRIBUTES; + // no-op: expected to be overridden by subclass } @Override - public Object setAttribute(String name, Object expected, Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException + public AuthenticationProvider getAuthenticationProvider() + { + return _authenticationProvider; + } + + public void setAuthenticationProvider(AuthenticationProvider authenticationProvider) { - return super.setAttribute(name, expected, desired); //TODO - Implement + _authenticationProvider = authenticationProvider; } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java new file mode 100644 index 0000000000..b7441b9f3b --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java @@ -0,0 +1,222 @@ +/* + * + * 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.model.adapter; + +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.Protocol; +import org.apache.qpid.server.model.Protocol.ProtocolType; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.Transport; +import org.apache.qpid.server.util.MapValueConverter; + +public class PortFactory +{ + public static final int DEFAULT_AMQP_SEND_BUFFER_SIZE = 262144; + public static final int DEFAULT_AMQP_RECEIVE_BUFFER_SIZE = 262144; + public static final boolean DEFAULT_AMQP_NEED_CLIENT_AUTH = false; + public static final boolean DEFAULT_AMQP_WANT_CLIENT_AUTH = false; + public static final boolean DEFAULT_AMQP_TCP_NO_DELAY = true; + public static final String DEFAULT_AMQP_BINDING = "*"; + public static final Transport DEFAULT_TRANSPORT = Transport.TCP; + + private final Collection<Protocol> _defaultProtocols; + + public PortFactory() + { + Set<Protocol> defaultProtocols = EnumSet.of(Protocol.AMQP_0_8, Protocol.AMQP_0_9, Protocol.AMQP_0_9_1, + Protocol.AMQP_0_10, Protocol.AMQP_1_0); + String excludedProtocols = System.getProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES); + if (excludedProtocols != null) + { + String[] excludes = excludedProtocols.split(","); + for (String exclude : excludes) + { + Protocol protocol = Protocol.valueOf(exclude); + defaultProtocols.remove(protocol); + } + } + String includedProtocols = System.getProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES); + if (includedProtocols != null) + { + String[] includes = includedProtocols.split(","); + for (String include : includes) + { + Protocol protocol = Protocol.valueOf(include); + defaultProtocols.add(protocol); + } + } + _defaultProtocols = Collections.unmodifiableCollection(defaultProtocols); + } + + public Port createPort(UUID id, Broker broker, Map<String, Object> objectAttributes) + { + Map<String, Object> attributes = retrieveAttributes(objectAttributes); + + final Port port; + Map<String, Object> defaults = new HashMap<String, Object>(); + defaults.put(Port.TRANSPORTS, Collections.singleton(DEFAULT_TRANSPORT)); + Object portValue = attributes.get(Port.PORT); + if (portValue == null) + { + throw new IllegalConfigurationException("Port attribute is not specified for port: " + attributes); + } + if (isAmqpProtocol(attributes)) + { + Object binding = attributes.get(Port.BINDING_ADDRESS); + if (binding == null) + { + binding = DEFAULT_AMQP_BINDING; + defaults.put(Port.BINDING_ADDRESS, DEFAULT_AMQP_BINDING); + } + defaults.put(Port.NAME, binding + ":" + portValue); + defaults.put(Port.PROTOCOLS, _defaultProtocols); + defaults.put(Port.TCP_NO_DELAY, DEFAULT_AMQP_TCP_NO_DELAY); + defaults.put(Port.WANT_CLIENT_AUTH, DEFAULT_AMQP_WANT_CLIENT_AUTH); + defaults.put(Port.NEED_CLIENT_AUTH, DEFAULT_AMQP_NEED_CLIENT_AUTH); + defaults.put(Port.RECEIVE_BUFFER_SIZE, DEFAULT_AMQP_RECEIVE_BUFFER_SIZE); + defaults.put(Port.SEND_BUFFER_SIZE, DEFAULT_AMQP_SEND_BUFFER_SIZE); + port = new AmqpPortAdapter(id, broker, attributes, defaults, broker.getTaskExecutor()); + } + else + { + @SuppressWarnings("unchecked") + Collection<Protocol> protocols = (Collection<Protocol>)attributes.get(Port.PROTOCOLS); + if (protocols.size() > 1) + { + throw new IllegalConfigurationException("Only one protocol can be used on non AMQP port"); + } + Protocol protocol = protocols.iterator().next(); + defaults.put(Port.NAME, portValue + "-" + protocol.name()); + port = new PortAdapter(id, broker, attributes, defaults, broker.getTaskExecutor()); + } + return port; + } + + private Map<String, Object> retrieveAttributes(Map<String, Object> objectAttributes) + { + Map<String, Object> attributes = new HashMap<String, Object>(objectAttributes); + + if (objectAttributes.containsKey(Port.PROTOCOLS)) + { + final Set<Protocol> protocolSet = MapValueConverter.getEnumSetAttribute(Port.PROTOCOLS, objectAttributes, Protocol.class); + attributes.put(Port.PROTOCOLS, protocolSet); + } + + if (objectAttributes.containsKey(Port.TRANSPORTS)) + { + final Set<Transport> transportSet = MapValueConverter.getEnumSetAttribute(Port.TRANSPORTS, objectAttributes, + Transport.class); + attributes.put(Port.TRANSPORTS, transportSet); + } + + if (objectAttributes.containsKey(Port.PORT)) + { + Integer port = MapValueConverter.getIntegerAttribute(Port.PORT, objectAttributes); + attributes.put(Port.PORT, port); + } + + if (objectAttributes.containsKey(Port.TCP_NO_DELAY)) + { + boolean tcpNoDelay = MapValueConverter.getBooleanAttribute(Port.TCP_NO_DELAY, objectAttributes); + attributes.put(Port.TCP_NO_DELAY, tcpNoDelay); + } + + if (objectAttributes.containsKey(Port.RECEIVE_BUFFER_SIZE)) + { + int receiveBufferSize = MapValueConverter.getIntegerAttribute(Port.RECEIVE_BUFFER_SIZE, objectAttributes); + attributes.put(Port.RECEIVE_BUFFER_SIZE, receiveBufferSize); + } + + if (objectAttributes.containsKey(Port.SEND_BUFFER_SIZE)) + { + int sendBufferSize = MapValueConverter.getIntegerAttribute(Port.SEND_BUFFER_SIZE, objectAttributes); + attributes.put(Port.SEND_BUFFER_SIZE, sendBufferSize); + } + + if (objectAttributes.containsKey(Port.NEED_CLIENT_AUTH)) + { + boolean needClientAuth = MapValueConverter.getBooleanAttribute(Port.NEED_CLIENT_AUTH, objectAttributes); + attributes.put(Port.NEED_CLIENT_AUTH, needClientAuth); + } + + if (objectAttributes.containsKey(Port.WANT_CLIENT_AUTH)) + { + boolean wantClientAuth = MapValueConverter.getBooleanAttribute(Port.WANT_CLIENT_AUTH, objectAttributes); + attributes.put(Port.WANT_CLIENT_AUTH, wantClientAuth); + } + + if (objectAttributes.containsKey(Port.BINDING_ADDRESS)) + { + String binding = MapValueConverter.getStringAttribute(Port.BINDING_ADDRESS, objectAttributes); + attributes.put(Port.BINDING_ADDRESS, binding); + } + + if (objectAttributes.containsKey(Port.STATE)) + { + State state = MapValueConverter.getEnumAttribute(State.class, Port.STATE, objectAttributes); + attributes.put(Port.STATE, state); + } + return attributes; + } + + private boolean isAmqpProtocol(Map<String, Object> portAttributes) + { + @SuppressWarnings("unchecked") + Set<Protocol> protocols = (Set<Protocol>) portAttributes.get(Port.PROTOCOLS); + if (protocols == null || protocols.isEmpty()) + { + // defaulting to AMQP if protocol is not specified + return true; + } + + Set<ProtocolType> protocolTypes = new HashSet<ProtocolType>(); + for (Protocol protocolObject : protocols) + { + protocolTypes.add(protocolObject.getProtocolType()); + } + + if (protocolTypes.size() > 1) + { + throw new IllegalConfigurationException("Found different protocol types '" + protocolTypes + + "' on port configuration: " + portAttributes); + } + + return protocolTypes.contains(ProtocolType.AMQP); + } + + public Collection<Protocol> getDefaultProtocols() + { + return _defaultProtocols; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java index 78f6d38d93..f3ddf32e5a 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java @@ -43,6 +43,7 @@ import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.Statistics; import org.apache.qpid.server.queue.*; import org.apache.qpid.server.subscription.Subscription; +import org.apache.qpid.server.util.MapValueConverter; final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.SubscriptionRegistrationListener, AMQQueue.NotificationListener { @@ -50,15 +51,16 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs static final Map<String, String> ATTRIBUTE_MAPPINGS = new HashMap<String, String>(); static { - QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_REPEAT_GAP, "x-qpid-minimum-alert-repeat-gap"); - QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_MESSAGE_AGE, "x-qpid-maximum-message-age"); - QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_MESSAGE_SIZE, "x-qpid-maximum-message-size"); - QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES, "x-qpid-maximum-message-count"); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_REPEAT_GAP, AMQQueueFactory.X_QPID_MINIMUM_ALERT_REPEAT_GAP); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_MESSAGE_AGE, AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_AGE); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_MESSAGE_SIZE, AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_SIZE); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES, AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_COUNT); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_QUEUE_DEPTH_BYTES, AMQQueueFactory.X_QPID_MAXIMUM_QUEUE_DEPTH); - QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.MAXIMUM_DELIVERY_ATTEMPTS, "x-qpid-maximum-delivery-count"); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.MAXIMUM_DELIVERY_ATTEMPTS, AMQQueueFactory.X_QPID_MAXIMUM_DELIVERY_COUNT); - QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, "x-qpid-capacity"); - QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, "x-qpid-flow-resume-capacity"); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, AMQQueueFactory.X_QPID_CAPACITY); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, AMQQueueFactory.X_QPID_FLOW_RESUME_CAPACITY); QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.SORT_KEY, AMQQueueFactory.QPID_QUEUE_SORT_KEY); QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.LVQ_KEY, AMQQueueFactory.QPID_LAST_VALUE_QUEUE_KEY); @@ -78,7 +80,7 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs public QueueAdapter(final VirtualHostAdapter virtualHostAdapter, final AMQQueue queue) { - super(queue.getId()); + super(queue.getId(), virtualHostAdapter.getTaskExecutor()); _vhost = virtualHostAdapter; addParent(org.apache.qpid.server.model.VirtualHost.class, virtualHostAdapter); @@ -205,47 +207,47 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs } @Override - public Object setAttribute(String name, Object expected, Object desired) throws IllegalStateException, AccessControlException, IllegalArgumentException + public boolean changeAttribute(String name, Object expected, Object desired) throws IllegalStateException, AccessControlException, IllegalArgumentException { try { if(ALERT_REPEAT_GAP.equals(name)) { _queue.setMinimumAlertRepeatGap((Long)desired); - return desired; + return true; } else if(ALERT_THRESHOLD_MESSAGE_AGE.equals(name)) { _queue.setMaximumMessageAge((Long)desired); - return desired; + return true; } else if(ALERT_THRESHOLD_MESSAGE_SIZE.equals(name)) { _queue.setMaximumMessageSize((Long)desired); - return desired; + return true; } else if(ALERT_THRESHOLD_QUEUE_DEPTH_BYTES.equals(name)) { _queue.setMaximumQueueDepth((Long)desired); - return desired; + return true; } else if(ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES.equals(name)) { _queue.setMaximumMessageCount((Long)desired); - return desired; + return true; } else if(ALTERNATE_EXCHANGE.equals(name)) { // In future we may want to accept a UUID as an alternative way to identifying the exchange ExchangeAdapter alternateExchange = (ExchangeAdapter) desired; _queue.setAlternateExchange(alternateExchange == null ? null : alternateExchange.getExchange()); - return desired; + return true; } else if(EXCLUSIVE.equals(name)) { Boolean exclusiveFlag = (Boolean) desired; _queue.setExclusive(exclusiveFlag); - return desired; + return true; } else if(MESSAGE_GROUP_KEY.equals(name)) { @@ -266,7 +268,7 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs else if(MAXIMUM_DELIVERY_ATTEMPTS.equals(name)) { _queue.setMaximumDeliveryCount((Integer)desired); - return desired; + return true; } else if(NO_LOCAL.equals(name)) { @@ -279,12 +281,12 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs else if(QUEUE_FLOW_CONTROL_SIZE_BYTES.equals(name)) { _queue.setCapacity((Long)desired); - return desired; + return true; } else if(QUEUE_FLOW_RESUME_SIZE_BYTES.equals(name)) { _queue.setFlowResumeCapacity((Long)desired); - return desired; + return true; } else if(QUEUE_FLOW_STOPPED.equals(name)) { @@ -301,10 +303,10 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs else if (DESCRIPTION.equals(name)) { _queue.setDescription((String) desired); - return desired; + return true; } - return super.setAttribute(name, expected, desired); + return super.changeAttribute(name, expected, desired); } finally { @@ -495,8 +497,8 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs throws AccessControlException, IllegalStateException { attributes = new HashMap<String, Object>(attributes); - String bindingKey = getStringAttribute(org.apache.qpid.server.model.Binding.NAME, attributes, ""); - Map<String, Object> bindingArgs = getMapAttribute(org.apache.qpid.server.model.Binding.ARGUMENTS, attributes, Collections.EMPTY_MAP); + String bindingKey = MapValueConverter.getStringAttribute(org.apache.qpid.server.model.Binding.NAME, attributes, ""); + Map<String, Object> bindingArgs = MapValueConverter.getMapAttribute(org.apache.qpid.server.model.Binding.ARGUMENTS, attributes, Collections.<String,Object>emptyMap()); attributes.remove(org.apache.qpid.server.model.Binding.NAME); attributes.remove(org.apache.qpid.server.model.Binding.ARGUMENTS); @@ -508,7 +510,7 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) { if(childClass == org.apache.qpid.server.model.Binding.class) { @@ -712,15 +714,15 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs } @Override - public State setDesiredState(State currentState, State desiredState) throws IllegalStateTransitionException, + protected boolean setState(State currentState, State desiredState) throws IllegalStateTransitionException, AccessControlException { if (desiredState == State.DELETED) { delete(); - return State.DELETED; + return true; } - return super.setDesiredState(currentState, desiredState); + return false; } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java index d802697d67..2fffdb32f8 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java @@ -34,6 +34,7 @@ import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.Statistics; import org.apache.qpid.server.model.Consumer; import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.protocol.AMQSessionModel; final class SessionAdapter extends AbstractAdapter implements Session @@ -44,9 +45,9 @@ final class SessionAdapter extends AbstractAdapter implements Session private AMQSessionModel _session; private SessionStatistics _statistics; - public SessionAdapter(final AMQSessionModel session) + public SessionAdapter(final AMQSessionModel session, TaskExecutor taskExecutor) { - super(UUIDGenerator.generateRandomUUID()); + super(UUIDGenerator.generateRandomUUID(), taskExecutor); _session = session; _statistics = new SessionStatistics(); } @@ -141,13 +142,6 @@ final class SessionAdapter extends AbstractAdapter implements Session return super.getAttribute(name); //TODO - Implement } - @Override - public Object setAttribute(String name, Object expected, Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - return super.setAttribute(name, expected, desired); //TODO - Implement - } - public Statistics getStatistics() { return _statistics; @@ -237,4 +231,11 @@ final class SessionAdapter extends AbstractAdapter implements Session return null; // TODO - Implement } } + + @Override + protected boolean setState(State currentState, State desiredState) + { + // TODO : add state management + return false; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfig.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java index 233134abc5..bdffe605ec 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfig.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java @@ -18,24 +18,26 @@ * under the License. * */ +package org.apache.qpid.server.model.adapter; -package org.apache.qpid.server.configuration; - +import java.util.Collection; import java.util.Map; +import java.util.UUID; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.TrustStore; -public interface BindingConfig extends ConfiguredObject<BindingConfigType, BindingConfig> +public class TrustStoreAdapter extends AbstractKeyStoreAdapter implements TrustStore { - - ExchangeConfig getExchange(); - - QueueConfig getQueue(); - - String getBindingKey(); - - Map<String, Object> getArguments(); - - String getOrigin(); - - long getMatches(); -}
\ No newline at end of file + public TrustStoreAdapter(UUID id, Broker broker, Map<String, Object> attributes) + { + super(id, broker, attributes); + } + + @Override + public Collection<String> getAttributeNames() + { + return AVAILABLE_ATTRIBUTES; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java index 35838e51d2..1d50be279f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.server.model.adapter; +import java.io.File; import java.security.AccessControlException; import java.security.Principal; import java.util.ArrayList; @@ -31,17 +32,27 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; + +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.configuration.SystemConfiguration; import org.apache.qpid.AMQException; import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; +import org.apache.qpid.server.configuration.XmlConfigurationUtilities.MyConfiguration; import org.apache.qpid.server.connection.IConnectionRegistry; import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.exchange.ExchangeType; import org.apache.qpid.server.message.ServerMessage; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.Connection; import org.apache.qpid.server.model.Exchange; import org.apache.qpid.server.model.LifetimePolicy; import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.Protocol; import org.apache.qpid.server.model.Queue; import org.apache.qpid.server.model.QueueType; import org.apache.qpid.server.model.State; @@ -49,22 +60,38 @@ import org.apache.qpid.server.model.Statistics; import org.apache.qpid.server.model.UUIDGenerator; import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.model.VirtualHostAlias; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; +import org.apache.qpid.server.stats.StatisticsGatherer; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.txn.LocalTransaction; import org.apache.qpid.server.txn.ServerTransaction; +import org.apache.qpid.server.util.MapValueConverter; +import org.apache.qpid.server.virtualhost.VirtualHostImpl; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; -final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, ExchangeRegistry.RegistryChangeListener, +public final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, ExchangeRegistry.RegistryChangeListener, QueueRegistry.RegistryChangeListener, IConnectionRegistry.RegistryChangeListener { - private final org.apache.qpid.server.virtualhost.VirtualHost _virtualHost; + @SuppressWarnings("serial") + public static final Map<String, Class<?>> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Class<?>>(){{ + put(NAME, String.class); + put(STORE_PATH, String.class); + put(STORE_TYPE, String.class); + put(CONFIG_PATH, String.class); + put(STATE, State.class); + }}); + + private org.apache.qpid.server.virtualhost.VirtualHost _virtualHost; private final Map<AMQConnectionModel, ConnectionAdapter> _connectionAdapters = new HashMap<AMQConnectionModel, ConnectionAdapter>(); @@ -74,37 +101,52 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E private final Map<org.apache.qpid.server.exchange.Exchange, ExchangeAdapter> _exchangeAdapters = new HashMap<org.apache.qpid.server.exchange.Exchange, ExchangeAdapter>(); - - private final StatisticsAdapter _statistics; - - private final BrokerAdapter _broker; - + private StatisticsAdapter _statistics; + private final Broker _broker; private final List<VirtualHostAlias> _aliases = new ArrayList<VirtualHostAlias>(); + private StatisticsGatherer _brokerStatisticsGatherer; - - VirtualHostAdapter(BrokerAdapter brokerAdapter, - final org.apache.qpid.server.virtualhost.VirtualHost virtualHost) + public VirtualHostAdapter(UUID id, Map<String, Object> attributes, Broker broker, StatisticsGatherer brokerStatisticsGatherer, TaskExecutor taskExecutor) { - super(virtualHost.getId()); - _broker = brokerAdapter; - _virtualHost = virtualHost; - _statistics = new VirtualHostStatisticsAdapter(virtualHost); - virtualHost.getQueueRegistry().addRegistryChangeListener(this); - populateQueues(); - virtualHost.getExchangeRegistry().addRegistryChangeListener(this); - populateExchanges(); - virtualHost.getConnectionRegistry().addRegistryChangeListener(this); - populateConnections(); - + super(id, null, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), taskExecutor); + validateAttributes(); + _broker = broker; + _brokerStatisticsGatherer = brokerStatisticsGatherer; + addParent(Broker.class, broker); + } + private void validateAttributes() + { + String name = getName(); + if (name == null || "".equals(name.trim())) + { + throw new IllegalConfigurationException("Virtual host name must be specified"); + } - for(Port port :_broker.getPorts()) + String configurationFile = (String) getAttribute(CONFIG_PATH); + String storePath = (String) getAttribute(STORE_PATH); + String storeType = (String) getAttribute(STORE_TYPE); + boolean invalidAttributes = false; + if (configurationFile == null) + { + if (storePath == null || storeType == null) + { + invalidAttributes = true; + } + } + else + { + if (storePath != null || storeType != null) + { + invalidAttributes = true; + } + } + if (invalidAttributes) { - _aliases.add(new VirtualHostAliasAdapter(this, port)); + throw new IllegalConfigurationException("Please specify either the 'configPath' attribute or both 'storePath' and 'storeType' attributes"); } } - private void populateExchanges() { Collection<org.apache.qpid.server.exchange.Exchange> actualExchanges = @@ -126,37 +168,22 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E private void populateQueues() { Collection<AMQQueue> actualQueues = _virtualHost.getQueueRegistry().getQueues(); - - synchronized(_queueAdapters) - { - for(AMQQueue queue : actualQueues) - { - if(!_queueAdapters.containsKey(queue)) - { - _queueAdapters.put(queue, new QueueAdapter(this,queue)); - } - } - } - } - - private void populateConnections() - { - - List<AMQConnectionModel> actualConnections = _virtualHost.getConnectionRegistry().getConnections(); - - synchronized(_connectionAdapters) + if ( actualQueues != null ) { - for(AMQConnectionModel conn : actualConnections) + synchronized(_queueAdapters) { - if(!_connectionAdapters.containsKey(conn)) + for(AMQQueue queue : actualQueues) { - _connectionAdapters.put(conn, new ConnectionAdapter(conn)); + if(!_queueAdapters.containsKey(queue)) + { + _queueAdapters.put(queue, new QueueAdapter(this, queue)); + } } } } - } + @Override public String getReplicationGroupName() { return null; //TODO @@ -198,12 +225,12 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E { attributes = new HashMap<String, Object>(attributes); - String name = getStringAttribute(Exchange.NAME, attributes, null); - State state = getEnumAttribute(State.class, Exchange.STATE, attributes, State.ACTIVE); - boolean durable = getBooleanAttribute(Exchange.DURABLE, attributes, false); - LifetimePolicy lifetime = getEnumAttribute(LifetimePolicy.class, Exchange.LIFETIME_POLICY, attributes, LifetimePolicy.PERMANENT); - String type = getStringAttribute(Exchange.TYPE, attributes, null); - long ttl = getLongAttribute(Exchange.TIME_TO_LIVE, attributes, 0l); + String name = MapValueConverter.getStringAttribute(Exchange.NAME, attributes, null); + State state = MapValueConverter.getEnumAttribute(State.class, Exchange.STATE, attributes, State.ACTIVE); + boolean durable = MapValueConverter.getBooleanAttribute(Exchange.DURABLE, attributes, false); + LifetimePolicy lifetime = MapValueConverter.getEnumAttribute(LifetimePolicy.class, Exchange.LIFETIME_POLICY, attributes, LifetimePolicy.PERMANENT); + String type = MapValueConverter.getStringAttribute(Exchange.TYPE, attributes, null); + long ttl = MapValueConverter.getLongAttribute(Exchange.TIME_TO_LIVE, attributes, 0l); attributes.remove(Exchange.NAME); attributes.remove(Exchange.STATE); @@ -266,7 +293,7 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E if (attributes.containsKey(Queue.TYPE)) { - String typeAttribute = getStringAttribute(Queue.TYPE, attributes, null); + String typeAttribute = MapValueConverter.getStringAttribute(Queue.TYPE, attributes, null); QueueType queueType = null; try { @@ -289,12 +316,12 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E throw new IllegalArgumentException("Sort key is not specified for sorted queue"); } } - String name = getStringAttribute(Queue.NAME, attributes, null); - State state = getEnumAttribute(State.class, Queue.STATE, attributes, State.ACTIVE); - boolean durable = getBooleanAttribute(Queue.DURABLE, attributes, false); - LifetimePolicy lifetime = getEnumAttribute(LifetimePolicy.class, Queue.LIFETIME_POLICY, attributes, LifetimePolicy.PERMANENT); - long ttl = getLongAttribute(Queue.TIME_TO_LIVE, attributes, 0l); - boolean exclusive= getBooleanAttribute(Queue.EXCLUSIVE, attributes, false); + String name = MapValueConverter.getStringAttribute(Queue.NAME, attributes, null); + State state = MapValueConverter.getEnumAttribute(State.class, Queue.STATE, attributes, State.ACTIVE); + boolean durable = MapValueConverter.getBooleanAttribute(Queue.DURABLE, attributes, false); + LifetimePolicy lifetime = MapValueConverter.getEnumAttribute(LifetimePolicy.class, Queue.LIFETIME_POLICY, attributes, LifetimePolicy.PERMANENT); + long ttl = MapValueConverter.getLongAttribute(Queue.TIME_TO_LIVE, attributes, 0l); + boolean exclusive= MapValueConverter.getBooleanAttribute(Queue.EXCLUSIVE, attributes, false); attributes.remove(Queue.NAME); attributes.remove(Queue.STATE); @@ -328,11 +355,10 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E String owner = null; if(exclusive) { - Set<Principal> principals = - SecurityManager.getThreadSubject().getPrincipals(); - if(principals != null && !principals.isEmpty()) + Principal authenticatedPrincipal = AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(SecurityManager.getThreadSubject()); + if(authenticatedPrincipal != null) { - owner = principals.iterator().next().getName(); + owner = authenticatedPrincipal.getName(); } } try @@ -370,7 +396,7 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E public String getName() { - return _virtualHost.getName(); + return (String)getAttribute(NAME); } public String setName(final String currentName, final String desiredName) @@ -379,9 +405,36 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E throw new IllegalStateException(); } + @Override public State getActualState() { - return getDesiredState(); + if (_virtualHost == null) + { + State state = (State)super.getAttribute(STATE); + if (state == null) + { + return State.INITIALISING; + } + return state; + } + else + { + org.apache.qpid.server.virtualhost.State implementationState = _virtualHost.getState(); + switch(implementationState) + { + case INITIALISING: + return State.INITIALISING; + case ACTIVE: + return State.ACTIVE; + case PASSIVE: + return State.QUIESCED; + case STOPPED: + return State.STOPPED; + default: + // unexpected state + return null; + } + } } public boolean isDurable() @@ -448,7 +501,7 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E } @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) { if(childClass == Exchange.class) { @@ -548,7 +601,7 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E { if(!_connectionAdapters.containsKey(connection)) { - adapter = new ConnectionAdapter(connection); + adapter = new ConnectionAdapter(connection, getTaskExecutor()); _connectionAdapters.put(connection, adapter); } @@ -709,13 +762,9 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E { return getId(); } - else if(NAME.equals(name)) - { - return getName(); - } else if(STATE.equals(name)) { - return State.ACTIVE; + return getActualState(); } else if(DURABLE.equals(name)) { @@ -737,10 +786,19 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E { // TODO } - else if(SUPPORTED_EXCHANGE_TYPES.equals(name)) + else if (_virtualHost != null) + { + return getAttributeFromVirtualHostImplementation(name); + } + return super.getAttribute(name); + } + + private Object getAttributeFromVirtualHostImplementation(String name) + { + if(SUPPORTED_EXCHANGE_TYPES.equals(name)) { List<String> types = new ArrayList<String>(); - for(ExchangeType type : _virtualHost.getExchangeFactory().getRegisteredTypes()) + for(@SuppressWarnings("rawtypes") ExchangeType type : _virtualHost.getExchangeFactory().getRegisteredTypes()) { types.add(type.getName().asString()); } @@ -754,10 +812,6 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E { return _virtualHost.getConfiguration().isDeadLetterQueueEnabled(); } - else if(FEDERATION_TAG.equals(name)) - { - return _virtualHost.getFederationTag(); - } else if(HOUSEKEEPING_CHECK_PERIOD.equals(name)) { return _virtualHost.getConfiguration().getHousekeepingCheckPeriod(); @@ -778,9 +832,9 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E { return _virtualHost.getMessageStore().getStoreType(); } - else if(STORE_CONFIGURATION.equals(name)) + else if(STORE_PATH.equals(name)) { - // TODO + return _virtualHost.getMessageStore().getStoreLocation(); } else if(STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE.equals(name)) { @@ -822,13 +876,6 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E } @Override - public Object setAttribute(String name, Object expected, Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - return super.setAttribute(name, expected, desired); //TODO - Implement - } - - @Override public Collection<String> getAttributeNames() { return AVAILABLE_ATTRIBUTES; @@ -889,4 +936,111 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E } } + + @Override + protected boolean setState(State currentState, State desiredState) + { + if (desiredState == State.ACTIVE) + { + activate(); + return true; + } + else if (desiredState == State.STOPPED) + { + if (_virtualHost != null) + { + try + { + _virtualHost.close(); + } + finally + { + _broker.getVirtualHostRegistry().unregisterVirtualHost(_virtualHost); + } + } + return true; + } + else if (desiredState == State.DELETED) + { + //TODO: add ACL check to authorize the operation + if (_virtualHost != null && _virtualHost.getState() == org.apache.qpid.server.virtualhost.State.ACTIVE) + { + setDesiredState(currentState, State.STOPPED); + } + return true; + } + return false; + } + + private void activate() + { + VirtualHostRegistry virtualHostRegistry = _broker.getVirtualHostRegistry(); + String virtualHostName = getName(); + try + { + VirtualHostConfiguration configuration = createVirtualHostConfiguration(virtualHostName); + _virtualHost = new VirtualHostImpl(_broker.getVirtualHostRegistry(), _brokerStatisticsGatherer, _broker.getSecurityManager(), configuration); + } + catch (Exception e) + { + throw new RuntimeException("Failed to create virtual host " + virtualHostName, e); + } + + virtualHostRegistry.registerVirtualHost(_virtualHost); + + _statistics = new VirtualHostStatisticsAdapter(_virtualHost); + _virtualHost.getQueueRegistry().addRegistryChangeListener(this); + populateQueues(); + _virtualHost.getExchangeRegistry().addRegistryChangeListener(this); + populateExchanges(); + _virtualHost.getConnectionRegistry().addRegistryChangeListener(this); + + synchronized(_aliases) + { + for(Port port :_broker.getPorts()) + { + if (Protocol.hasAmqpProtocol(port.getProtocols())) + { + _aliases.add(new VirtualHostAliasAdapter(this, port)); + } + } + } + } + + private VirtualHostConfiguration createVirtualHostConfiguration(String virtualHostName) throws ConfigurationException + { + VirtualHostConfiguration configuration; + String configurationFile = (String)getAttribute(CONFIG_PATH); + if (configurationFile == null) + { + final MyConfiguration basicConfiguration = new MyConfiguration(); + PropertiesConfiguration config = new PropertiesConfiguration(); + config.addProperty("store.type", (String)getAttribute(STORE_TYPE)); + config.addProperty("store.environment-path", (String)getAttribute(STORE_PATH)); + basicConfiguration.addConfiguration(config); + + CompositeConfiguration compositeConfiguration = new CompositeConfiguration(); + compositeConfiguration.addConfiguration(new SystemConfiguration()); + compositeConfiguration.addConfiguration(basicConfiguration); + configuration = new VirtualHostConfiguration(virtualHostName, compositeConfiguration , _broker); + } + else + { + configuration = new VirtualHostConfiguration(virtualHostName, new File(configurationFile) , _broker); + } + return configuration; + } + + @Override + public SecurityManager getSecurityManager() + { + return _virtualHost.getSecurityManager(); + } + + @Override + public MessageStore getMessageStore() + { + return _virtualHost.getMessageStore(); + } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java index 367d1ff518..91b705b004 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java @@ -43,7 +43,7 @@ public class VirtualHostAliasAdapter extends AbstractAdapter implements Virtual public VirtualHostAliasAdapter(VirtualHostAdapter virtualHostAdapter, Port port) { - super(UUIDGenerator.generateVhostAliasUUID(virtualHostAdapter.getName(), port.getName())); + super(UUIDGenerator.generateVhostAliasUUID(virtualHostAdapter.getName(), port.getName()), virtualHostAdapter.getTaskExecutor()); _vhost = virtualHostAdapter; _port = port; } @@ -140,4 +140,11 @@ public class VirtualHostAliasAdapter extends AbstractAdapter implements Virtual { throw new UnsupportedOperationException(); } + + @Override + protected boolean setState(State currentState, State desiredState) + { + // TODO: state is not supported at the moment + return false; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java b/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java index a68ac5439c..917215a42f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java +++ b/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java @@ -218,55 +218,71 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter final boolean isRedelivered = entry.isRedelivered(); - final AMQBody returnBlock = new AMQBody() - { - - private AMQBody _underlyingBody; - - public AMQBody createAMQBody() - { - return _methodRegistry.createBasicDeliverBody(consumerTag, - deliveryTag, - isRedelivered, - exchangeName, - routingKey); - - + final AMQBody returnBlock = new EncodedDeliveryBody(deliveryTag, routingKey, exchangeName, consumerTag, isRedelivered); + return returnBlock; + } + private class EncodedDeliveryBody implements AMQBody + { + private final long _deliveryTag; + private final AMQShortString _routingKey; + private final AMQShortString _exchangeName; + private final AMQShortString _consumerTag; + private final boolean _isRedelivered; + private AMQBody _underlyingBody; + + private EncodedDeliveryBody(long deliveryTag, AMQShortString routingKey, AMQShortString exchangeName, AMQShortString consumerTag, boolean isRedelivered) + { + _deliveryTag = deliveryTag; + _routingKey = routingKey; + _exchangeName = exchangeName; + _consumerTag = consumerTag; + _isRedelivered = isRedelivered; + } + public AMQBody createAMQBody() + { + return _methodRegistry.createBasicDeliverBody(_consumerTag, + _deliveryTag, + _isRedelivered, + _exchangeName, + _routingKey); + } - } + public byte getFrameType() + { + return AMQMethodBody.TYPE; + } - public byte getFrameType() + public int getSize() + { + if(_underlyingBody == null) { - return AMQMethodBody.TYPE; + _underlyingBody = createAMQBody(); } + return _underlyingBody.getSize(); + } - public int getSize() + public void writePayload(DataOutput buffer) throws IOException + { + if(_underlyingBody == null) { - if(_underlyingBody == null) - { - _underlyingBody = createAMQBody(); - } - return _underlyingBody.getSize(); + _underlyingBody = createAMQBody(); } + _underlyingBody.writePayload(buffer); + } - public void writePayload(DataOutput buffer) throws IOException - { - if(_underlyingBody == null) - { - _underlyingBody = createAMQBody(); - } - _underlyingBody.writePayload(buffer); - } + public void handle(final int channelId, final AMQVersionAwareProtocolSession amqMinaProtocolSession) + throws AMQException + { + throw new AMQException("This block should never be dispatched!"); + } - public void handle(final int channelId, final AMQVersionAwareProtocolSession amqMinaProtocolSession) - throws AMQException - { - throw new AMQException("This block should never be dispatched!"); - } - }; - return returnBlock; + @Override + public String toString() + { + return "[" + getClass().getSimpleName() + " underlyingBody: " + String.valueOf(_underlyingBody) + "]"; + } } private AMQBody createEncodedGetOkBody(QueueEntry entry, long deliveryTag, int queueSize) @@ -368,7 +384,6 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter _methodBody = methodBody; _headerBody = headerBody; _contentBody = contentBody; - } public long getSize() @@ -380,6 +395,19 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter { AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody, _contentBody); } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder(); + builder.append("[").append(getClass().getSimpleName()) + .append(" methodBody=").append(_methodBody) + .append(", headerBody=").append(_headerBody) + .append(", contentBody=").append(_contentBody) + .append(", channel=").append(_channel).append("]"); + return builder.toString(); + } + } public static final class SmallCompositeAMQBodyBlock extends AMQDataBlock @@ -408,6 +436,17 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter { AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody); } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder(); + builder.append(getClass().getSimpleName()) + .append("methodBody=").append(_methodBody) + .append(", headerBody=").append(_headerBody) + .append(", channel=").append(_channel).append("]"); + return builder.toString(); + } } }
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/AccessControlFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/AccessControlFactory.java new file mode 100644 index 0000000000..7708b90efc --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/AccessControlFactory.java @@ -0,0 +1,28 @@ +/* + * 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.plugin; + +import java.util.Map; + +import org.apache.qpid.server.security.AccessControl; + +public interface AccessControlFactory +{ + AccessControl createInstance(Map<String, Object> attributes); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java new file mode 100644 index 0000000000..95e6b4feb0 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.plugin; + +import java.util.Map; + +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; + + +public interface AuthenticationManagerFactory +{ + public static final String ATTRIBUTE_TYPE = "authenticationProviderType"; + + AuthenticationManager createInstance(Map<String, Object> attributes); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeType.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/ExchangeType.java index a01e41f039..40ef6ad6a2 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeType.java +++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/ExchangeType.java @@ -18,19 +18,18 @@ * under the License. * */ -package org.apache.qpid.server.exchange; +package org.apache.qpid.server.plugin; import java.util.UUID; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.virtualhost.VirtualHost; - public interface ExchangeType<T extends Exchange> { public AMQShortString getName(); - public Class<T> getExchangeClass(); public T newInstance(UUID id, VirtualHost host, AMQShortString name, boolean durable, int ticket, boolean autoDelete) throws AMQException; public AMQShortString getDefaultExchangeName(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/GroupManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/GroupManagerFactory.java new file mode 100644 index 0000000000..5d80ca24fd --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/GroupManagerFactory.java @@ -0,0 +1,28 @@ +/* + * 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.plugin; + +import java.util.Map; + +import org.apache.qpid.server.security.group.GroupManager; + +public interface GroupManagerFactory +{ + GroupManager createInstance(Map<String, Object> attributes); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/PluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/PluginFactory.java new file mode 100644 index 0000000000..af24f62e28 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/PluginFactory.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.plugin; + +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.Plugin; + +public interface PluginFactory +{ + static final String PLUGIN_TYPE = "pluginType"; + + Plugin createInstance(UUID id, Map<String, Object> attributes, Broker broker); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java new file mode 100644 index 0000000000..a0e0346ce0 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.plugin; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.ServiceLoader; + +import org.apache.log4j.Logger; + +/** + * Simple facade over a {@link ServiceLoader} to instantiate all configured implementations of an interface. + */ +public class QpidServiceLoader<C> +{ + private static final Logger _logger = Logger.getLogger(QpidServiceLoader.class); + + public Iterable<C> instancesOf(Class<C> clazz) + { + return instancesOf(clazz, false); + } + + /** + * @throws RuntimeException if at least one implementation is not found. + */ + public Iterable<C> atLeastOneInstanceOf(Class<C> clazz) + { + return instancesOf(clazz, true); + } + + private Iterable<C> instancesOf(Class<C> clazz, boolean atLeastOne) + { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Iterator<C> serviceLoaderIterator = ServiceLoader.load(clazz, classLoader).iterator(); + + // create a new list so we can log the count + List<C> serviceImplementations = new ArrayList<C>(); + while(serviceLoaderIterator.hasNext()) + { + serviceImplementations.add(serviceLoaderIterator.next()); + } + + if(atLeastOne && serviceImplementations.isEmpty()) + { + throw new RuntimeException("At least one implementation of " + clazz + " expected"); + } + + if(_logger.isDebugEnabled()) + { + _logger.debug("Found " + serviceImplementations.size() + " implementations of " + clazz); + } + + return serviceImplementations; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/Activator.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/Activator.java deleted file mode 100644 index 12e1eee9ca..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/plugins/Activator.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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.plugins; - -import org.apache.log4j.Logger; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; - -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.registry.ApplicationRegistry; - -public class Activator implements BundleActivator -{ - private static final Logger _logger = Logger.getLogger(Activator.class); - - private BundleContext _context = null; - - public void start(BundleContext ctx) throws Exception - { - _context = ctx; - _logger.info("Registering bundle: " + _context.getBundle().getSymbolicName()); - ctx.registerService(ServerConfiguration.class.getName(), ApplicationRegistry.getInstance().getConfiguration(), null); - } - - public void stop(BundleContext ctx) throws Exception - { - _logger.info("Stopping bundle: " + _context.getBundle().getSymbolicName()); - _context = null; - } - - public BundleContext getContext() - { - return _context; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtil.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtil.java deleted file mode 100644 index d2bb3e037c..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtil.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.plugins; - -import org.osgi.framework.Version; - -import java.util.Iterator; -import java.util.Map; - -/** - * Utility class to convert a map of package name to version numbers into the string - * with the format expected of a OSGi system package declaration: - * - * <code> - * org.xyz; version=1.0.0, org.xyz.xyz; version=1.0.0,... - * </code> - * - * Additionally, if the caller has provided a qpidPackageReleaseNumber and the package - * begins org.apache.qpid, this release number will be used, in preference to the one - * found in the Map. - * - * @see org.osgi.framework.Constants#FRAMEWORK_SYSTEMPACKAGES - * - */ -public class OsgiSystemPackageUtil -{ - private static final String APACHE_QPID_PKG_PREFIX = "org.apache.qpid"; - - private final Map<String, String> _packageNameVersionMap; - private final Version _qpidPackageReleaseNumber; - - public OsgiSystemPackageUtil(final Version qpidPackageReleaseNumber, final Map<String, String> packageNameVersionMap) - { - _qpidPackageReleaseNumber = qpidPackageReleaseNumber; - _packageNameVersionMap = packageNameVersionMap; - } - - public String getFormattedSystemPackageString() - { - if (_packageNameVersionMap == null || _packageNameVersionMap.size() == 0) - { - return null; - } - - final StringBuilder packages = new StringBuilder(); - - for(Iterator<String> itr = _packageNameVersionMap.keySet().iterator(); itr.hasNext();) - { - final String packageName = itr.next(); - final String packageVersion; - - if (_qpidPackageReleaseNumber != null && packageName.startsWith(APACHE_QPID_PKG_PREFIX)) - { - packageVersion = _qpidPackageReleaseNumber.toString(); - } - else - { - packageVersion = _packageNameVersionMap.get(packageName); - } - - packages.append(packageName); - packages.append("; "); - packages.append("version="); - packages.append(packageVersion); - - if (itr.hasNext()) - { - packages.append(", "); - } - } - - return packages.toString(); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties b/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties deleted file mode 100644 index 6479546355..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties +++ /dev/null @@ -1,135 +0,0 @@ -# -# 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. -# - -# -# OSGi framework system package list -# -# PluginManager uses these properties to construct the FRAMEWORK_SYSTEMPACKAGES list -# - -# Format is: -# <package>=<version> -# and PluginManager will convert this into: -# <package>; version=<version> -# e.g. org.osgi.framework; version=1.3.0 - -javax.management.openmbean=1.0.0 -javax.management=1.0.0 -javax.management.remote.rmi=1.0.0 -javax.management.remote=1.0.0 -javax.management.monitor=1.0.0 - -javax.crypto=1 -javax.crypto.spec=1 - -javax.servlet=2 -javax.servlet.http=2 - -javax.security.auth=1.0.0 -javax.security.auth.callback=1.0.0 -javax.security.auth.login=1.0.0 -javax.security.sasl=1.0.0 -javax.security=1.0.0 - -javax.rmi.ssl=1.0.0 - -org.xml.sax=1.0.0 -org.xml.sax.helpers=1.0.0 - -org.osgi.framework=1.3.0 -org.osgi.service.packageadmin=1.2.0 -org.osgi.service.startlevel=1.0.0 -org.osgi.service.url=1.0.0 -org.osgi.util.tracker=1.0.0 - -org.apache.commons.codec=1.3.0 -org.apache.commons.codec.binary=1.3.0 - -org.apache.commons.configuration=1.0.0 - -org.apache.commons.lang=1.0.0 -org.apache.commons.lang.builder=1.0.0 -org.apache.commons.lang.time=1.0.0 -org.apache.commons.logging=1.0.0 - -org.apache.log4j=1.2.16 - -org.slf4j=1.6.1 - -org.eclipse.jetty=7.6.3 -org.eclipse.jetty.http=7.6.3 -org.eclipse.jetty.io=7.6.3 -org.eclipse.jetty.io.nio=7.6.3 -org.eclipse.jetty.security=7.6.3 -org.eclipse.jetty.server=7.6.3 -org.eclipse.jetty.server.session=7.6.3 -org.eclipse.jetty.server.ssl=7.6.3 -org.eclipse.jetty.server.nio=7.6.3 -org.eclipse.jetty.servlet=7.6.3 -org.eclipse.jetty.util.ssl=7.6.3 - -org.codehaus.jackson=1.9.0 -org.codehaus.jackson.map=1.9.0 - -# For Qpid packages (org.apache.qpid), the version number is automatically overridden by QpidPropertis#getReleaseVersion() - -org.apache.qpid=0.0.0 -org.apache.qpid.common=0.0.0 -org.apache.qpid.exchange=0.0.0 -org.apache.qpid.framing=0.0.0 -org.apache.qpid.management.common.mbeans.annotations=0.0.0 -org.apache.qpid.management.common.mbeans=0.0.0 -org.apache.qpid.protocol=0.0.0 -org.apache.qpid.transport=0.0.0 -org.apache.qpid.transport.codec=0.0.0 -org.apache.qpid.server.binding=0.0.0 -org.apache.qpid.server.model=0.0.0 -org.apache.qpid.server.model.adapter=0.0.0 -org.apache.qpid.server.model.impl=0.0.0 -org.apache.qpid.server.configuration=0.0.0 -org.apache.qpid.server.configuration.plugins=0.0.0 -org.apache.qpid.server.configuration.management=0.0.0 -org.apache.qpid.server.connection=0.0.0 -org.apache.qpid.server.exchange=0.0.0 -org.apache.qpid.server.logging=0.0.0 -org.apache.qpid.server.logging.log4j=0.0.0 -org.apache.qpid.server.logging.actors=0.0.0 -org.apache.qpid.server.logging.messages=0.0.0 -org.apache.qpid.server.logging.subjects=0.0.0 -org.apache.qpid.server.message=0.0.0 -org.apache.qpid.server.persistent=0.0.0 -org.apache.qpid.server.plugins=0.0.0 -org.apache.qpid.server.protocol=0.0.0 -org.apache.qpid.server.queue=0.0.0 -org.apache.qpid.server.subscription=0.0.0 -org.apache.qpid.server.registry=0.0.0 -org.apache.qpid.server.security=0.0.0 -org.apache.qpid.server.security.access=0.0.0 -org.apache.qpid.server.security.access.plugins=0.0.0 -org.apache.qpid.server.security.auth=0.0.0 -org.apache.qpid.server.security.auth.sasl=0.0.0 -org.apache.qpid.server.security.auth.manager=0.0.0 -org.apache.qpid.server.security.auth.rmi=0.0.0 -org.apache.qpid.server.stats=0.0.0 -org.apache.qpid.server.virtualhost=0.0.0 -org.apache.qpid.server.virtualhost.plugins=0.0.0 -org.apache.qpid.util=0.0.0 - -org.apache.qpid.server.store.berkeleydb=0.0.0 - diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java deleted file mode 100644 index 6dcf688f2a..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.plugins; - -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; - -public interface Plugin -{ - - /** - * Provide Configuration to this plugin - */ - public void configure(ConfigurationPlugin config) throws ConfigurationException; -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginFactory.java deleted file mode 100644 index 7ea2b95b89..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.plugins; - -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; - -public interface PluginFactory<P extends Plugin> -{ - public Class<P> getPluginClass(); - - public String getPluginName(); - - public P newInstance(ConfigurationPlugin config) throws ConfigurationException; -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java deleted file mode 100644 index 74abbccd2b..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java +++ /dev/null @@ -1,403 +0,0 @@ -/* - * 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.plugins; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.felix.framework.Felix; -import org.apache.felix.framework.util.StringMap; -import org.apache.log4j.Logger; -import org.apache.qpid.common.Closeable; -import org.apache.qpid.common.QpidProperties; -import org.apache.qpid.server.configuration.TopicConfiguration; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionConfiguration.SlowConsumerDetectionConfigurationFactory; -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionPolicyConfiguration.SlowConsumerDetectionPolicyConfigurationFactory; -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionQueueConfiguration.SlowConsumerDetectionQueueConfigurationFactory; -import org.apache.qpid.server.exchange.ExchangeType; -import org.apache.qpid.server.security.SecurityManager; -import org.apache.qpid.server.security.SecurityPluginFactory; -import org.apache.qpid.server.security.access.plugins.LegacyAccess; -import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager; -import org.apache.qpid.server.security.auth.manager.AuthenticationManagerPluginFactory; -import org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManager; -import org.apache.qpid.server.security.auth.manager.KerberosAuthenticationManager; -import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager; -import org.apache.qpid.server.security.auth.manager.SimpleLDAPAuthenticationManager; -import org.apache.qpid.server.virtualhost.plugins.SlowConsumerDetection; -import org.apache.qpid.server.virtualhost.plugins.VirtualHostPluginFactory; -import org.apache.qpid.server.virtualhost.plugins.policies.TopicDeletePolicy; -import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPluginFactory; -import org.apache.qpid.util.FileUtils; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.BundleException; -import org.osgi.framework.Version; -import org.osgi.framework.launch.Framework; -import org.osgi.util.tracker.ServiceTracker; - -import static org.apache.felix.framework.util.FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP; -import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_ACTION_PROPERY; -import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_DIR_PROPERY; -import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_INSTALL_VALUE; -import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_START_VALUE; -import static org.apache.felix.main.AutoProcessor.process; -import static org.osgi.framework.Constants.FRAMEWORK_STORAGE; -import static org.osgi.framework.Constants.FRAMEWORK_STORAGE_CLEAN; -import static org.osgi.framework.Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT; -import static org.osgi.framework.Constants.FRAMEWORK_SYSTEMPACKAGES; - -/** - * Provides access to pluggable elements, such as exchanges - */ -@SuppressWarnings("unchecked") -public class PluginManager implements Closeable -{ - private static final Logger _logger = Logger.getLogger(PluginManager.class); - - private static final int FELIX_STOP_TIMEOUT = 30000; - - private Framework _felix; - - private ServiceTracker _exchangeTracker = null; - private ServiceTracker _securityTracker = null; - private ServiceTracker _configTracker = null; - private ServiceTracker _virtualHostTracker = null; - private ServiceTracker _policyTracker = null; - private ServiceTracker _authenticationManagerTracker = null; - - private Activator _activator; - - private final List<ServiceTracker> _trackers = new ArrayList<ServiceTracker>(); - private Map<String, SecurityPluginFactory> _securityPlugins = new HashMap<String, SecurityPluginFactory>(); - private Map<List<String>, ConfigurationPluginFactory> _configPlugins = new IdentityHashMap<List<String>, ConfigurationPluginFactory>(); - private Map<String, VirtualHostPluginFactory> _vhostPlugins = new HashMap<String, VirtualHostPluginFactory>(); - private Map<String, SlowConsumerPolicyPluginFactory> _policyPlugins = new HashMap<String, SlowConsumerPolicyPluginFactory>(); - private Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> _authenticationManagerPlugins = new HashMap<String, AuthenticationManagerPluginFactory<? extends Plugin>>(); - - /** The default name of the OSGI system package list. */ - private static final String DEFAULT_RESOURCE_NAME = "org/apache/qpid/server/plugins/OsgiSystemPackages.properties"; - - /** The name of the override system property that holds the name of the OSGI system package list. */ - private static final String FILE_PROPERTY = "qpid.osgisystempackages.properties"; - - private static final String OSGI_SYSTEM_PACKAGES; - - static - { - final String filename = System.getProperty(FILE_PROPERTY); - final InputStream is = FileUtils.openFileOrDefaultResource(filename, DEFAULT_RESOURCE_NAME, - PluginManager.class.getClassLoader()); - - try - { - Version qpidReleaseVersion; - try - { - qpidReleaseVersion = Version.parseVersion(QpidProperties.getReleaseVersion()); - } - catch (IllegalArgumentException iae) - { - qpidReleaseVersion = null; - } - - final Properties p = new Properties(); - p.load(is); - - final OsgiSystemPackageUtil osgiSystemPackageUtil = new OsgiSystemPackageUtil(qpidReleaseVersion, (Map)p); - - OSGI_SYSTEM_PACKAGES = osgiSystemPackageUtil.getFormattedSystemPackageString(); - - _logger.debug("List of OSGi system packages to be added: " + OSGI_SYSTEM_PACKAGES); - } - catch (IOException e) - { - _logger.error("Error reading OSGI system package list", e); - throw new ExceptionInInitializerError(e); - } - } - - - public PluginManager(String pluginPath, String cachePath, BundleContext bundleContext) throws Exception - { - // Store all non-OSGi plugins - // A little gross that we have to add them here, but not all the plugins are OSGIfied - for (SecurityPluginFactory<?> pluginFactory : Arrays.asList(LegacyAccess.FACTORY)) - { - _securityPlugins.put(pluginFactory.getPluginName(), pluginFactory); - } - for (ConfigurationPluginFactory configFactory : Arrays.asList( - TopicConfiguration.FACTORY, - SecurityManager.SecurityConfiguration.FACTORY, - LegacyAccess.LegacyAccessConfiguration.FACTORY, - new SlowConsumerDetectionConfigurationFactory(), - new SlowConsumerDetectionPolicyConfigurationFactory(), - new SlowConsumerDetectionQueueConfigurationFactory(), - PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration.FACTORY, - AnonymousAuthenticationManager.AnonymousAuthenticationManagerConfiguration.FACTORY, - KerberosAuthenticationManager.KerberosAuthenticationManagerConfiguration.FACTORY, - SimpleLDAPAuthenticationManager.SimpleLDAPAuthenticationManagerConfiguration.FACTORY, - ExternalAuthenticationManager.ExternalAuthenticationManagerConfiguration.FACTORY - )) - { - _configPlugins.put(configFactory.getParentPaths(), configFactory); - } - for (SlowConsumerPolicyPluginFactory pluginFactory : Arrays.asList( - new TopicDeletePolicy.TopicDeletePolicyFactory())) - { - _policyPlugins.put(pluginFactory.getPluginName(), pluginFactory); - } - for (VirtualHostPluginFactory pluginFactory : Arrays.asList( - new SlowConsumerDetection.SlowConsumerFactory())) - { - _vhostPlugins.put(pluginFactory.getClass().getName(), pluginFactory); - } - - for (AuthenticationManagerPluginFactory<? extends Plugin> pluginFactory : Arrays.asList( - PrincipalDatabaseAuthenticationManager.FACTORY, AnonymousAuthenticationManager.FACTORY, - KerberosAuthenticationManager.FACTORY, SimpleLDAPAuthenticationManager.FACTORY, - ExternalAuthenticationManager.FACTORY)) - { - _authenticationManagerPlugins.put(pluginFactory.getPluginName(), pluginFactory); - } - - if(bundleContext == null) - { - // Check the plugin directory path is set and exist - if (pluginPath == null) - { - _logger.info("No plugin path specified, no plugins will be loaded."); - return; - } - File pluginDir = new File(pluginPath); - if (!pluginDir.exists()) - { - _logger.warn("Plugin dir : " + pluginDir + " does not exist."); - return; - } - - // Add the bundle provided service interface package and the core OSGi - // packages to be exported from the class path via the system bundle. - - // Setup OSGi configuration property map - final StringMap configMap = new StringMap(false); - configMap.put(FRAMEWORK_SYSTEMPACKAGES, OSGI_SYSTEM_PACKAGES); - - // No automatic shutdown hook - configMap.put("felix.shutdown.hook", "false"); - - // Add system activator - List<BundleActivator> activators = new ArrayList<BundleActivator>(); - _activator = new Activator(); - activators.add(_activator); - configMap.put(SYSTEMBUNDLE_ACTIVATORS_PROP, activators); - - if (cachePath != null) - { - File cacheDir = new File(cachePath); - if (!cacheDir.exists() && cacheDir.canWrite()) - { - _logger.info("Creating plugin cache directory: " + cachePath); - cacheDir.mkdir(); - } - - // Set plugin cache directory and empty it - _logger.info("Cache bundles in directory " + cachePath); - configMap.put(FRAMEWORK_STORAGE, cachePath); - } - configMap.put(FRAMEWORK_STORAGE_CLEAN, FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT); - - // Set directory with plugins to auto-deploy - _logger.info("Auto deploying bundles from directory " + pluginPath); - configMap.put(AUTO_DEPLOY_DIR_PROPERY, pluginPath); - configMap.put(AUTO_DEPLOY_ACTION_PROPERY, AUTO_DEPLOY_INSTALL_VALUE + "," + AUTO_DEPLOY_START_VALUE); - - // Start plugin manager - _felix = new Felix(configMap); - try - { - _logger.info("Starting plugin manager framework"); - _felix.init(); - process(configMap, _felix.getBundleContext()); - _felix.start(); - _logger.info("Started plugin manager framework"); - } - catch (BundleException e) - { - throw new ConfigurationException("Could not start plugin manager: " + e.getMessage(), e); - } - - bundleContext = _activator.getContext(); - } - else - { - _logger.info("Using the specified external BundleContext"); - } - - _exchangeTracker = new ServiceTracker(bundleContext, ExchangeType.class.getName(), null); - _exchangeTracker.open(); - _trackers.add(_exchangeTracker); - - _securityTracker = new ServiceTracker(bundleContext, SecurityPluginFactory.class.getName(), null); - _securityTracker.open(); - _trackers.add(_securityTracker); - - _configTracker = new ServiceTracker(bundleContext, ConfigurationPluginFactory.class.getName(), null); - _configTracker.open(); - _trackers.add(_configTracker); - - _virtualHostTracker = new ServiceTracker(bundleContext, VirtualHostPluginFactory.class.getName(), null); - _virtualHostTracker.open(); - _trackers.add(_virtualHostTracker); - - _policyTracker = new ServiceTracker(bundleContext, SlowConsumerPolicyPluginFactory.class.getName(), null); - _policyTracker.open(); - _trackers.add(_policyTracker); - - _authenticationManagerTracker = new ServiceTracker(bundleContext, AuthenticationManagerPluginFactory.class.getName(), null); - _authenticationManagerTracker.open(); - _trackers.add(_authenticationManagerTracker); - - _logger.info("Opened service trackers"); - } - - private static <T> Map<String, T> getServices(ServiceTracker tracker) - { - Map<String, T> services = new HashMap<String, T>(); - - if ((tracker != null) && (tracker.getServices() != null)) - { - for (Object service : tracker.getServices()) - { - if (service instanceof PluginFactory<?>) - { - services.put(((PluginFactory<?>) service).getPluginName(), (T) service); - } - else - { - services.put(service.getClass().getName(), (T) service); - } - } - } - - return services; - } - - public static <T> Map<String, T> getServices(ServiceTracker tracker, Map<String, T> plugins) - { - Map<String, T> services = getServices(tracker); - services.putAll(plugins); - return services; - } - - public Map<List<String>, ConfigurationPluginFactory> getConfigurationPlugins() - { - Map<List<String>, ConfigurationPluginFactory> services = new IdentityHashMap<List<String>, ConfigurationPluginFactory>(); - - if (_configTracker != null && _configTracker.getServices() != null) - { - for (Object service : _configTracker.getServices()) - { - ConfigurationPluginFactory factory = (ConfigurationPluginFactory) service; - services.put(factory.getParentPaths(), factory); - } - } - - services.putAll(_configPlugins); - - return services; - } - - public Map<String, VirtualHostPluginFactory> getVirtualHostPlugins() - { - return getServices(_virtualHostTracker, _vhostPlugins); - } - - public Map<String, SlowConsumerPolicyPluginFactory> getSlowConsumerPlugins() - { - return getServices(_policyTracker, _policyPlugins); - } - - public Map<String, ExchangeType<?>> getExchanges() - { - return getServices(_exchangeTracker); - } - - public Map<String, SecurityPluginFactory> getSecurityPlugins() - { - return getServices(_securityTracker, _securityPlugins); - } - - public Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> getAuthenticationManagerPlugins() - { - return getServices(_authenticationManagerTracker, _authenticationManagerPlugins); - } - - public void close() - { - try - { - // Close all bundle trackers - for(ServiceTracker tracker : _trackers) - { - tracker.close(); - } - } - finally - { - if (_felix != null) - { - _logger.info("Stopping plugin manager framework"); - try - { - // FIXME should be stopAndWait() but hangs VM, need upgrade in felix - _felix.stop(); - } - catch (BundleException e) - { - // Ignore - } - - try - { - _felix.waitForStop(FELIX_STOP_TIMEOUT); - } - catch (InterruptedException e) - { - // Ignore - } - _logger.info("Stopped plugin manager framework"); - } - else - { - _logger.info("Plugin manager was started with an external BundleContext, " + - "skipping remaining shutdown tasks"); - } - } - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java index 1e649c3cb7..ee1ef2418a 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java @@ -29,11 +29,11 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -52,10 +52,7 @@ import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; import org.apache.qpid.protocol.ServerProtocolEngine; import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.ConnectionConfig; -import org.apache.qpid.server.configuration.ConnectionConfigType; +import org.apache.qpid.server.configuration.BrokerProperties; import org.apache.qpid.server.handler.ServerMethodDispatcherImpl; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.LogSubject; @@ -64,10 +61,11 @@ import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.actors.ManagementActor; import org.apache.qpid.server.logging.messages.ConnectionMessages; import org.apache.qpid.server.logging.subjects.ConnectionLogSubject; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.output.ProtocolOutputConverter; import org.apache.qpid.server.output.ProtocolOutputConverterRegistry; import org.apache.qpid.server.queue.QueueEntry; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; import org.apache.qpid.server.state.AMQState; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.stats.StatisticsCounter; @@ -75,13 +73,12 @@ import org.apache.qpid.server.subscription.ClientDeliveryMethod; import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.subscription.SubscriptionImpl; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.virtualhost.VirtualHostRegistry; import org.apache.qpid.transport.Sender; import org.apache.qpid.transport.TransportException; import org.apache.qpid.transport.network.NetworkConnection; import org.apache.qpid.util.BytesDataOutput; -public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSession, ConnectionConfig +public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSession { private static final Logger _logger = Logger.getLogger(AMQProtocolEngine.class); @@ -115,7 +112,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi private volatile boolean _closed; // maximum number of channels this session should have - private long _maxNoOfChannels = ApplicationRegistry.getInstance().getConfiguration().getMaxChannelCount(); + private long _maxNoOfChannels; /* AMQP Version for this session */ private ProtocolVersion _protocolVersion = ProtocolVersion.getLatestSupportedVersion(); @@ -142,8 +139,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi private long _maxFrameSize; private final AtomicBoolean _closing = new AtomicBoolean(false); - private final UUID _qmfId; - private final ConfigStore _configStore; private long _createTime = System.currentTimeMillis(); private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived; @@ -156,23 +151,25 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi private boolean _blocking; private final Lock _receivedLock; + private AtomicLong _lastWriteTime = new AtomicLong(System.currentTimeMillis()); + private final Broker _broker; - public AMQProtocolEngine(VirtualHostRegistry virtualHostRegistry, NetworkConnection network, final long connectionId) + + public AMQProtocolEngine(Broker broker, NetworkConnection network, final long connectionId) { + _broker = broker; + _maxNoOfChannels = (Integer)broker.getAttribute(Broker.SESSION_COUNT_LIMIT); _receivedLock = new ReentrantLock(); - _stateManager = new AMQStateManager(virtualHostRegistry, this); + _stateManager = new AMQStateManager(broker, this); _codecFactory = new AMQCodecFactory(true, this); setNetworkConnection(network); _connectionID = connectionId; - _actor = new AMQPConnectionActor(this, virtualHostRegistry.getApplicationRegistry().getRootMessageLogger()); + _actor = new AMQPConnectionActor(this, _broker.getRootMessageLogger()); _logSubject = new ConnectionLogSubject(this); - _configStore = virtualHostRegistry.getConfigStore(); - _qmfId = _configStore.createId(); - _actor.message(ConnectionMessages.OPEN(null, null, null, false, false, false)); initialiseStatistics(); @@ -309,9 +306,13 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi try { + long startTime = 0; + String frameToString = null; if (_logger.isDebugEnabled()) { - _logger.debug("Frame Received: " + frame); + startTime = System.currentTimeMillis(); + frameToString = frame.toString(); + _logger.debug("RECV: " + frame); } // Check that this channel is not closing @@ -346,6 +347,11 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi closeChannel(channelId); throw e; } + + if(_logger.isDebugEnabled()) + { + _logger.debug("Frame handled in " + (System.currentTimeMillis() - startTime) + " ms. Frame: " + frameToString); + } } finally { @@ -367,7 +373,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi // This sets the protocol version (and hence framing classes) for this session. setProtocolVersion(pv); - String mechanisms = ApplicationRegistry.getInstance().getAuthenticationManager(getLocalAddress()).getMechanisms(); + String mechanisms = _broker.getSubjectCreator(getLocalAddress()).getMechanisms(); String locales = "en_US"; @@ -549,8 +555,17 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi final ByteBuffer buf = asByteBuffer(frame); _writtenBytes += buf.remaining(); + + if(_logger.isDebugEnabled()) + { + _logger.debug("SEND: " + frame); + } + _sender.send(buf); - _lastIoTime = System.currentTimeMillis(); + final long time = System.currentTimeMillis(); + _lastIoTime = time; + _lastWriteTime.set(time); + if(!_deferFlush) { _sender.flush(); @@ -749,7 +764,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi if (delay > 0) { _network.setMaxWriteIdle(delay); - _network.setMaxReadIdle((int) (ApplicationRegistry.getInstance().getConfiguration().getHeartBeatTimeout() * delay)); + _network.setMaxReadIdle(BrokerProperties.DEFAULT_HEART_BEAT_TIMEOUT_FACTOR * delay); } } @@ -796,8 +811,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi closeAllChannels(); - getConfigStore().removeConfiguredObject(this); - for (Task task : _taskList) { task.doTask(this); @@ -983,7 +996,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi _virtualHost.getConnectionRegistry().registerConnection(this); - _configStore.addConfiguredObject(this); } public void addSessionCloseTask(Task task) @@ -1017,7 +1029,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi public Principal getAuthorizedPrincipal() { - return _authorizedSubject == null ? null : _authorizedSubject.getPrincipals().iterator().next(); + return _authorizedSubject == null ? null : AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(_authorizedSubject); } public SocketAddress getRemoteAddress() @@ -1070,12 +1082,12 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi public void readerIdle() { - // Nothing + // TODO - enforce disconnect on lack of inbound data } public synchronized void writerIdle() { - _sender.send(asByteBuffer(HeartbeatBody.FRAME)); + writeFrame(HeartbeatBody.FRAME); } public void exception(Throwable throwable) @@ -1185,32 +1197,11 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi return null; } - public ConfigStore getConfigStore() - { - return _configStore; - } - - public ConnectionConfigType getConfigType() - { - return ConnectionConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getVirtualHost(); - } - public boolean isDurable() { return false; } - @Override - public UUID getQMFId() - { - return _qmfId; - } - public long getConnectionId() { return getSessionID(); @@ -1494,4 +1485,16 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi { return _receivedLock; } + + @Override + public long getLastReadTime() + { + return _lastReceivedTime; + } + + @Override + public long getLastWriteTime() + { + return _lastWriteTime.get(); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java index a8f62b0fa2..9d9bbe807b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java @@ -36,8 +36,7 @@ import org.apache.qpid.server.queue.SimpleAMQQueue; */ public interface AMQSessionModel extends Comparable<AMQSessionModel> { - /** Unique session ID across entire broker*/ - public UUID getQMFId(); + public UUID getId(); public AMQConnectionModel getConnectionModel(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java index 5c92aa95b6..d9e5e1c473 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java @@ -28,7 +28,7 @@ import java.util.Set; import org.apache.log4j.Logger; import org.apache.qpid.protocol.ServerProtocolEngine; -import org.apache.qpid.server.registry.IApplicationRegistry; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.transport.ServerConnection; import org.apache.qpid.transport.ConnectionDelegate; import org.apache.qpid.transport.Sender; @@ -42,24 +42,24 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine private Set<AmqpProtocolVersion> _supported; private String _fqdn; - private IApplicationRegistry _appRegistry; + private final Broker _broker; private NetworkConnection _network; private Sender<ByteBuffer> _sender; private final AmqpProtocolVersion _defaultSupportedReply; private volatile ServerProtocolEngine _delegate = new SelfDelegateProtocolEngine(); - public MultiVersionProtocolEngine(final IApplicationRegistry appRegistry, + public MultiVersionProtocolEngine(final Broker broker, final Set<AmqpProtocolVersion> supported, final AmqpProtocolVersion defaultSupportedReply, final long id, final NetworkConnection network) { - this(appRegistry, supported, defaultSupportedReply, id); + this(broker, supported, defaultSupportedReply, id); setNetworkConnection(network); } - public MultiVersionProtocolEngine(final IApplicationRegistry appRegistry, + public MultiVersionProtocolEngine(final Broker broker, final Set<AmqpProtocolVersion> supported, final AmqpProtocolVersion defaultSupportedReply, final long id) @@ -71,7 +71,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine } _id = id; - _appRegistry = appRegistry; + _broker = broker; _supported = supported; _defaultSupportedReply = defaultSupportedReply; } @@ -217,6 +217,18 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine _sender = sender; } + @Override + public long getLastReadTime() + { + return _delegate.getLastReadTime(); + } + + @Override + public long getLastWriteTime() + { + return _delegate.getLastWriteTime(); + } + private static interface DelegateCreator { @@ -240,7 +252,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public ServerProtocolEngine getProtocolEngine() { - return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network, _id); + return new AMQProtocolEngine(_broker, _network, _id); } }; @@ -260,7 +272,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public ServerProtocolEngine getProtocolEngine() { - return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network, _id); + return new AMQProtocolEngine(_broker, _network, _id); } }; @@ -280,7 +292,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public ServerProtocolEngine getProtocolEngine() { - return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network, _id); + return new AMQProtocolEngine(_broker, _network, _id); } }; @@ -301,13 +313,15 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public ServerProtocolEngine getProtocolEngine() { - final ConnectionDelegate connDelegate = - new org.apache.qpid.server.transport.ServerConnectionDelegate(_appRegistry, _fqdn, _appRegistry.getAuthenticationManager(getLocalAddress())); + final ConnectionDelegate connDelegate = new org.apache.qpid.server.transport.ServerConnectionDelegate(_broker, + _fqdn, _broker.getSubjectCreator(getLocalAddress())); ServerConnection conn = new ServerConnection(_id); - conn.setConnectionDelegate(connDelegate); - return new ProtocolEngine_0_10( conn, _network, _appRegistry); + conn.setConnectionDelegate(connDelegate); + conn.setRemoteAddress(_network.getRemoteAddress()); + conn.setLocalAddress(_network.getLocalAddress()); + return new ProtocolEngine_0_10( conn, _network); } }; @@ -327,7 +341,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public ServerProtocolEngine getProtocolEngine() { - return new ProtocolEngine_1_0_0(_appRegistry,_id); + return new ProtocolEngine_1_0_0(_network, _broker, _id); } }; @@ -347,7 +361,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public ServerProtocolEngine getProtocolEngine() { - return new ProtocolEngine_1_0_0_SASL(_network, _appRegistry, _id); + return new ProtocolEngine_1_0_0_SASL(_network, _broker, _id); } }; @@ -407,6 +421,18 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine } + @Override + public long getLastReadTime() + { + return 0; + } + + @Override + public long getLastWriteTime() + { + return 0; + } + public long getConnectionId() { return _id; @@ -547,7 +573,29 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public void closed() { - + try + { + _delegate = new ClosedDelegateProtocolEngine(); + if(_logger.isDebugEnabled()) + { + _logger.debug("Connection from " + getRemoteAddress() + " was closed before any protocol version was established."); + } + } + catch(Exception e) + { + //ignore + } + finally + { + try + { + _network.close(); + } + catch(Exception e) + { + //ignore + } + } } public void writerIdle() @@ -564,5 +612,17 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine { } + + @Override + public long getLastReadTime() + { + return 0; + } + + @Override + public long getLastWriteTime() + { + return 0; + } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java index 552b1c7054..9f078c8999 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java @@ -22,8 +22,7 @@ package org.apache.qpid.server.protocol; import org.apache.qpid.protocol.ProtocolEngineFactory; import org.apache.qpid.protocol.ServerProtocolEngine; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.registry.IApplicationRegistry; +import org.apache.qpid.server.model.Broker; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; @@ -32,11 +31,12 @@ public class MultiVersionProtocolEngineFactory implements ProtocolEngineFactory { private static final AtomicLong ID_GENERATOR = new AtomicLong(0); - private final IApplicationRegistry _appRegistry; + private final Broker _broker; private final Set<AmqpProtocolVersion> _supported; private final AmqpProtocolVersion _defaultSupportedReply; - public MultiVersionProtocolEngineFactory(final Set<AmqpProtocolVersion> supportedVersions, final AmqpProtocolVersion defaultSupportedReply) + public MultiVersionProtocolEngineFactory(Broker broker, + final Set<AmqpProtocolVersion> supportedVersions, final AmqpProtocolVersion defaultSupportedReply) { if(defaultSupportedReply != null && !supportedVersions.contains(defaultSupportedReply)) { @@ -44,14 +44,14 @@ public class MultiVersionProtocolEngineFactory implements ProtocolEngineFactory + ") to an unsupported protocol version initiation is itself not supported!"); } - _appRegistry = ApplicationRegistry.getInstance(); + _broker = broker; _supported = supportedVersions; _defaultSupportedReply = defaultSupportedReply; } public ServerProtocolEngine newProtocolEngine() { - return new MultiVersionProtocolEngine(_appRegistry, _supported, _defaultSupportedReply, ID_GENERATOR.getAndIncrement()); + return new MultiVersionProtocolEngine(_broker, _supported, _defaultSupportedReply, ID_GENERATOR.getAndIncrement()); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java index fd6e9300ec..d5f7fe486c 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java @@ -21,13 +21,7 @@ package org.apache.qpid.server.protocol; import org.apache.qpid.protocol.ServerProtocolEngine; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.ConnectionConfig; -import org.apache.qpid.server.configuration.ConnectionConfigType; -import org.apache.qpid.server.configuration.VirtualHostConfig; import org.apache.qpid.server.logging.messages.ConnectionMessages; -import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.transport.ServerConnection; import org.apache.qpid.transport.Sender; import org.apache.qpid.transport.network.Assembler; @@ -37,9 +31,9 @@ import org.apache.qpid.transport.network.NetworkConnection; import java.net.SocketAddress; import java.nio.ByteBuffer; -import java.util.UUID; -public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocolEngine, ConnectionConfig + +public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocolEngine { public static final int MAX_FRAME_SIZE = 64 * 1024 - 1; @@ -47,20 +41,17 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol private long _readBytes; private long _writtenBytes; private ServerConnection _connection; - private final UUID _qmfId; - private final IApplicationRegistry _appRegistry; + private long _createTime = System.currentTimeMillis(); + private long _lastReadTime; + private long _lastWriteTime; public ProtocolEngine_0_10(ServerConnection conn, - NetworkConnection network, - final IApplicationRegistry appRegistry) + NetworkConnection network) { super(new Assembler(conn)); _connection = conn; - _connection.setConnectionConfig(this); - _qmfId = appRegistry.getConfigStore().createId(); - _appRegistry = appRegistry; if(network != null) { @@ -68,14 +59,6 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol } - _connection.onOpen(new Runnable() - { - public void run() - { - getConfigStore().addConfiguredObject(ProtocolEngine_0_10.this); - } - }); - } public void setNetworkConnection(NetworkConnection network) @@ -87,13 +70,61 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol { _network = network; - _connection.setSender(new Disassembler(sender, MAX_FRAME_SIZE)); + _connection.setNetworkConnection(network); + _connection.setSender(new Disassembler(wrapSender(sender), MAX_FRAME_SIZE)); _connection.setPeerPrincipal(_network.getPeerPrincipal()); // FIXME Two log messages to maintain compatibility with earlier protocol versions _connection.getLogActor().message(ConnectionMessages.OPEN(null, null, null, false, false, false)); _connection.getLogActor().message(ConnectionMessages.OPEN(null, "0-10", null, false, true, false)); } + private Sender<ByteBuffer> wrapSender(final Sender<ByteBuffer> sender) + { + return new Sender<ByteBuffer>() + { + @Override + public void setIdleTimeout(int i) + { + sender.setIdleTimeout(i); + + } + + @Override + public void send(ByteBuffer msg) + { + _lastWriteTime = System.currentTimeMillis(); + sender.send(msg); + + } + + @Override + public void flush() + { + sender.flush(); + + } + + @Override + public void close() + { + sender.close(); + + } + }; + } + + @Override + public long getLastReadTime() + { + return _lastReadTime; + } + + @Override + public long getLastWriteTime() + { + return _lastWriteTime; + } + public SocketAddress getRemoteAddress() { return _network.getRemoteAddress(); @@ -106,6 +137,7 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol public void received(final ByteBuffer buf) { + _lastReadTime = System.currentTimeMillis(); super.received(buf); _connection.receivedComplete(); } @@ -122,7 +154,7 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol public void writerIdle() { - //Todo + _connection.doHeartbeat(); } public void readerIdle() @@ -130,72 +162,16 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol //Todo } - public VirtualHostConfig getVirtualHost() - { - return _connection.getVirtualHost(); - } - public String getAddress() { return getRemoteAddress().toString(); } - public Boolean isIncoming() - { - return true; - } - - public Boolean isSystemConnection() - { - return false; - } - - public Boolean isFederationLink() - { - return false; - } - public String getAuthId() { return _connection.getAuthorizedPrincipal() == null ? null : _connection.getAuthorizedPrincipal().getName(); } - public String getRemoteProcessName() - { - return null; - } - - public Integer getRemotePID() - { - return null; - } - - public Integer getRemoteParentPID() - { - return null; - } - - public ConfigStore getConfigStore() - { - return _appRegistry.getConfigStore(); - } - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public ConnectionConfigType getConfigType() - { - return ConnectionConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getVirtualHost(); - } - public boolean isDurable() { return false; @@ -205,7 +181,6 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol public void closed() { super.closed(); - getConfigStore().removeConfiguredObject(this); } public long getCreateTime() @@ -213,16 +188,6 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol return _createTime; } - public Boolean isShadow() - { - return false; - } - - public void mgmtClose() - { - _connection.mgmtClose(); - } - public long getConnectionId() { return _connection.getConnectionId(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java index e6282315c6..f6b8e1e5c9 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java @@ -22,7 +22,6 @@ package org.apache.qpid.server.protocol; import java.net.SocketAddress; import java.nio.ByteBuffer; -import java.util.UUID; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import java.util.logging.Logger; @@ -39,11 +38,10 @@ import org.apache.qpid.amqp_1_0.transport.FrameOutputHandler; import org.apache.qpid.amqp_1_0.type.Binary; import org.apache.qpid.amqp_1_0.type.FrameBody; import org.apache.qpid.protocol.ServerProtocolEngine; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConnectionConfigType; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.protocol.v1_0.Connection_1_0; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.Sender; import org.apache.qpid.transport.network.NetworkConnection; @@ -54,8 +52,9 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa //private NetworkConnection _networkDriver; private long _readBytes; private long _writtenBytes; - private final UUID _id; - private final IApplicationRegistry _appRegistry; + private long _lastReadTime; + private long _lastWriteTime; + private final Broker _broker; private long _createTime = System.currentTimeMillis(); private ConnectionEndpoint _conn; private final long _connectionId; @@ -99,11 +98,14 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa - public ProtocolEngine_1_0_0(final IApplicationRegistry appRegistry, long id) + public ProtocolEngine_1_0_0(final NetworkConnection networkDriver, final Broker broker, long id) { - _id = appRegistry.getConfigStore().createId(); - _appRegistry = appRegistry; + _broker = broker; _connectionId = id; + if(networkDriver != null) + { + setNetworkConnection(networkDriver, networkDriver.getSender()); + } } @@ -142,13 +144,15 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa _network = network; _sender = sender; - Container container = new Container(_appRegistry.getBrokerId().toString()); + Container container = new Container(_broker.getId().toString()); + + VirtualHost virtualHost = _broker.getVirtualHostRegistry().getVirtualHost((String)_broker.getAttribute(Broker.DEFAULT_VIRTUAL_HOST)); - _conn = new ConnectionEndpoint(container, asSaslServerProvider(_appRegistry.getAuthenticationManager( + _conn = new ConnectionEndpoint(container, asSaslServerProvider(_broker.getSubjectCreator( getLocalAddress()))); - _conn.setConnectionEventListener(new Connection_1_0(_appRegistry, _conn, _connectionId)); - _conn.setFrameOutputHandler(this); _conn.setRemoteAddress(_network.getRemoteAddress()); + _conn.setConnectionEventListener(new Connection_1_0(virtualHost, _conn, _connectionId)); + _conn.setFrameOutputHandler(this); _frameWriter = new FrameWriter(_conn.getDescribedTypeRegistry()); _frameHandler = new FrameHandler(_conn); @@ -157,14 +161,14 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa _sender.flush(); } - private SaslServerProvider asSaslServerProvider(final AuthenticationManager authenticationManager) + private SaslServerProvider asSaslServerProvider(final SubjectCreator subjectCreator) { return new SaslServerProvider() { @Override public SaslServer getSaslServer(String mechanism, String fqdn) throws SaslException { - return authenticationManager.createSaslServer(mechanism, fqdn, null); + return subjectCreator.createSaslServer(mechanism, fqdn, null); } }; } @@ -174,22 +178,6 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa return getRemoteAddress().toString(); } - - public ConfigStore getConfigStore() - { - return _appRegistry.getConfigStore(); - } - - public UUID getId() - { - return _id; - } - - public ConnectionConfigType getConfigType() - { - return ConnectionConfigType.getInstance(); - } - public boolean isDurable() { return false; @@ -197,6 +185,7 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa public synchronized void received(ByteBuffer msg) { + _lastReadTime = System.currentTimeMillis(); if(RAW_LOGGER.isLoggable(Level.FINE)) { ByteBuffer dup = msg.duplicate(); @@ -339,6 +328,7 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa synchronized(_sendLock) { + _lastWriteTime = System.currentTimeMillis(); if(FRAME_LOGGER.isLoggable(Level.FINE)) { FRAME_LOGGER.fine("SEND[" + getRemoteAddress() + "|" + amqFrame.getChannel() + "] : " + amqFrame.getFrameBody()); @@ -393,4 +383,13 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa return _connectionId; } + public long getLastReadTime() + { + return _lastReadTime; + } + + public long getLastWriteTime() + { + return _lastWriteTime; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java index a48441bf30..3b02ef2e5b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java @@ -23,7 +23,6 @@ package org.apache.qpid.server.protocol; import java.io.PrintWriter; import java.net.SocketAddress; import java.nio.ByteBuffer; -import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; import javax.security.sasl.SaslException; @@ -40,12 +39,10 @@ import org.apache.qpid.amqp_1_0.transport.FrameOutputHandler; import org.apache.qpid.amqp_1_0.type.Binary; import org.apache.qpid.amqp_1_0.type.FrameBody; import org.apache.qpid.protocol.ServerProtocolEngine; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConnectionConfigType; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.protocol.v1_0.Connection_1_0; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.Sender; import org.apache.qpid.transport.network.NetworkConnection; @@ -53,8 +50,10 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut { private long _readBytes; private long _writtenBytes; - private final UUID _id; - private final IApplicationRegistry _appRegistry; + + private long _lastReadTime; + private long _lastWriteTime; + private final Broker _broker; private long _createTime = System.currentTimeMillis(); private ConnectionEndpoint _conn; private long _connectionId; @@ -113,13 +112,11 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut private State _state = State.A; - public ProtocolEngine_1_0_0_SASL(final NetworkConnection networkDriver, final IApplicationRegistry appRegistry, + public ProtocolEngine_1_0_0_SASL(final NetworkConnection networkDriver, final Broker broker, long id) { - _id = appRegistry.getConfigStore().createId(); _connectionId = id; - _appRegistry = appRegistry; - + _broker = broker; if(networkDriver != null) { setNetworkConnection(networkDriver, networkDriver.getSender()); @@ -162,21 +159,17 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut _network = network; _sender = sender; - Container container = new Container(_appRegistry.getBrokerId().toString()); + Container container = new Container(_broker.getId().toString()); - _conn = new ConnectionEndpoint(container, asSaslServerProvider(ApplicationRegistry.getInstance() - .getAuthenticationManager(getLocalAddress()))); - _conn.setConnectionEventListener(new Connection_1_0(_appRegistry, _conn, _connectionId)); + VirtualHost virtualHost = _broker.getVirtualHostRegistry().getVirtualHost((String)_broker.getAttribute(Broker.DEFAULT_VIRTUAL_HOST)); + _conn = new ConnectionEndpoint(container, asSaslServerProvider(_broker.getSubjectCreator(getLocalAddress()))); _conn.setRemoteAddress(getRemoteAddress()); - - + _conn.setConnectionEventListener(new Connection_1_0(virtualHost, _conn, _connectionId)); _conn.setFrameOutputHandler(this); _conn.setSaslFrameOutput(this); _conn.setOnSaslComplete(new Runnable() { - - public void run() { if(_conn.isAuthenticated()) @@ -201,14 +194,14 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut } - private SaslServerProvider asSaslServerProvider(final AuthenticationManager authenticationManager) + private SaslServerProvider asSaslServerProvider(final SubjectCreator subjectCreator) { return new SaslServerProvider() { @Override public SaslServer getSaslServer(String mechanism, String fqdn) throws SaslException { - return authenticationManager.createSaslServer(mechanism, fqdn, null); + return subjectCreator.createSaslServer(mechanism, fqdn, null); } }; } @@ -218,22 +211,6 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut return getRemoteAddress().toString(); } - - public ConfigStore getConfigStore() - { - return _appRegistry.getConfigStore(); - } - - public UUID getId() - { - return _id; - } - - public ConnectionConfigType getConfigType() - { - return ConnectionConfigType.getInstance(); - } - public boolean isDurable() { return false; @@ -244,6 +221,7 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut public synchronized void received(ByteBuffer msg) { + _lastReadTime = System.currentTimeMillis(); if(RAW_LOGGER.isLoggable(Level.FINE)) { ByteBuffer dup = msg.duplicate(); @@ -386,17 +364,14 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut synchronized(_sendLock) { - + _lastWriteTime = System.currentTimeMillis(); if(FRAME_LOGGER.isLoggable(Level.FINE)) { FRAME_LOGGER.fine("SEND[" + getRemoteAddress() + "|" + amqFrame.getChannel() + "] : " + amqFrame.getFrameBody()); } - _frameWriter.setValue(amqFrame); - - ByteBuffer dup = ByteBuffer.allocate(_conn.getMaxFrameSize()); int size = _frameWriter.writeToBuffer(dup); @@ -447,4 +422,13 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut return _connectionId; } + public long getLastReadTime() + { + return _lastReadTime; + } + + public long getLastWriteTime() + { + return _lastWriteTime; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java index f429d8ba9f..cf4164c244 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java @@ -31,7 +31,6 @@ import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.protocol.AMQSessionModel; -import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.stats.StatisticsCounter; import org.apache.qpid.server.virtualhost.VirtualHost; @@ -44,7 +43,6 @@ import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CONNECTIO public class Connection_1_0 implements ConnectionEventListener { - private IApplicationRegistry _appRegistry; private VirtualHost _vhost; private final ConnectionEndpoint _conn; private final long _connectionId; @@ -62,10 +60,9 @@ public class Connection_1_0 implements ConnectionEventListener - public Connection_1_0(IApplicationRegistry appRegistry, ConnectionEndpoint conn, long connectionId) + public Connection_1_0(VirtualHost virtualHost, ConnectionEndpoint conn, long connectionId) { - _appRegistry = appRegistry; - _vhost = _appRegistry.getVirtualHostRegistry().getDefaultVirtualHost(); + _vhost = virtualHost; _conn = conn; _connectionId = connectionId; _vhost.getConnectionRegistry().registerConnection(_model); @@ -74,7 +71,7 @@ public class Connection_1_0 implements ConnectionEventListener public void remoteSessionCreation(SessionEndpoint endpoint) { - Session_1_0 session = new Session_1_0(_vhost, _appRegistry, this); + Session_1_0 session = new Session_1_0(_vhost, this); _sessions.add(session); endpoint.setSessionEventListener(session); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java index ba1a1ca45c..2cef27267b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java @@ -80,7 +80,7 @@ public class ExchangeDestination implements ReceivingDestination, SendingDestina { // NO-OP } - }, System.currentTimeMillis()); + }); return ACCEPTED; } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java index 140a815f57..fbce1666b7 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java @@ -23,9 +23,10 @@ package org.apache.qpid.server.protocol.v1_0; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.List; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.configuration.SessionConfig; import org.apache.qpid.server.message.InboundMessage; import org.apache.qpid.server.message.MessageMetaData_1_0; import org.apache.qpid.server.message.MessageReference; @@ -34,11 +35,45 @@ import org.apache.qpid.server.store.StoredMessage; public class Message_1_0 implements ServerMessage, InboundMessage { + + + private static final AtomicIntegerFieldUpdater<Message_1_0> _refCountUpdater = + AtomicIntegerFieldUpdater.newUpdater(Message_1_0.class, "_referenceCount"); + + private volatile int _referenceCount = 0; + private final StoredMessage<MessageMetaData_1_0> _storedMessage; private List<ByteBuffer> _fragments; private WeakReference<Session_1_0> _session; + public Message_1_0(final StoredMessage<MessageMetaData_1_0> storedMessage) + { + _storedMessage = storedMessage; + _session = null; + _fragments = restoreFragments(storedMessage); + } + + private static List<ByteBuffer> restoreFragments(StoredMessage<MessageMetaData_1_0> storedMessage) + { + ArrayList<ByteBuffer> fragments = new ArrayList<ByteBuffer>(); + final int FRAGMENT_SIZE = 2048; + int offset = 0; + ByteBuffer b; + do + { + + b = storedMessage.getContent(offset,FRAGMENT_SIZE); + if(b.hasRemaining()) + { + fragments.add(b); + offset+= b.remaining(); + } + } + while(b.hasRemaining()); + return fragments; + } + public Message_1_0(final StoredMessage<MessageMetaData_1_0> storedMessage, final List<ByteBuffer> fragments, final Session_1_0 session) @@ -136,11 +171,6 @@ public class Message_1_0 implements ServerMessage, InboundMessage return buf; } - public SessionConfig getSessionConfig() - { - return null; //TODO - } - public List<ByteBuffer> getFragments() { return _fragments; @@ -148,7 +178,61 @@ public class Message_1_0 implements ServerMessage, InboundMessage public Session_1_0 getSession() { - return _session.get(); + return _session == null ? null : _session.get(); + } + + + public boolean incrementReference() + { + if(_refCountUpdater.incrementAndGet(this) <= 0) + { + _refCountUpdater.decrementAndGet(this); + return false; + } + else + { + return true; + } + } + + /** + * Threadsafe. This will decrement the reference count and when it reaches zero will remove the message from the + * message store. + * + * + * @throws org.apache.qpid.server.queue.MessageCleanupException when an attempt was made to remove the message from the message store and that + * failed + */ + public void decrementReference() + { + int count = _refCountUpdater.decrementAndGet(this); + + // note that the operation of decrementing the reference count and then removing the message does not + // have to be atomic since the ref count starts at 1 and the exchange itself decrements that after + // the message has been passed to all queues. i.e. we are + // not relying on the all the increments having taken place before the delivery manager decrements. + if (count == 0) + { + // set the reference count way below 0 so that we can detect that the message has been deleted + // this is to guard against the message being spontaneously recreated (from the mgmt console) + // by copying from other queues at the same time as it is being removed. + _refCountUpdater.set(this,Integer.MIN_VALUE/2); + + // must check if the handle is null since there may be cases where we decide to throw away a message + // and the handle has not yet been constructed + if (_storedMessage != null) + { + _storedMessage.remove(); + } + } + else + { + if (count < 0) + { + throw new RuntimeException("Reference count for message id " + getMessageNumber() + + " has gone below 0."); + } + } } public static class Reference extends MessageReference<Message_1_0> @@ -160,13 +244,13 @@ public class Message_1_0 implements ServerMessage, InboundMessage protected void onReference(Message_1_0 message) { - + message.incrementReference(); } protected void onRelease(Message_1_0 message) { - + message.decrementReference(); } -} + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java index 999ffc55e5..a0ed824c58 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java @@ -36,7 +36,6 @@ import org.apache.qpid.amqp_1_0.type.transport.*; import org.apache.qpid.amqp_1_0.type.transport.Error; import org.apache.qpid.AMQException; import org.apache.qpid.AMQSecurityException; -import org.apache.qpid.protocol.ProtocolEngine; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.message.InboundMessage; @@ -45,8 +44,6 @@ import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.transport.ServerConnection; import org.apache.qpid.server.txn.AutoCommitTransaction; import org.apache.qpid.server.txn.ServerTransaction; import org.apache.qpid.server.virtualhost.VirtualHost; @@ -58,7 +55,6 @@ import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_F public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSubject { private static final Symbol LIFETIME_POLICY = Symbol.valueOf("lifetime-policy"); - private IApplicationRegistry _appRegistry; private VirtualHost _vhost; private AutoCommitTransaction _transaction; @@ -68,9 +64,8 @@ public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSu private UUID _id = UUID.randomUUID(); - public Session_1_0(VirtualHost vhost, IApplicationRegistry appRegistry, final Connection_1_0 connection) + public Session_1_0(VirtualHost vhost, final Connection_1_0 connection) { - _appRegistry = appRegistry; _vhost = vhost; _transaction = new AutoCommitTransaction(vhost.getMessageStore()); _connection = connection; @@ -456,8 +451,9 @@ public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSu { } + @Override - public UUID getQMFId() + public UUID getId() { return _id; } @@ -580,13 +576,6 @@ public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSu return 0; } - @Override - public int compareTo(AMQSessionModel o) - { - return getQMFId().compareTo(o.getQMFId()); - } - - public String toLogString() { @@ -604,4 +593,9 @@ public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSu + "] "; } + @Override + public int compareTo(AMQSessionModel o) + { + return getId().compareTo(o.getId()); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java index d3efd63ee0..4f610cc925 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java @@ -23,8 +23,7 @@ package org.apache.qpid.server.queue; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.QueueConfig; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; +import org.apache.qpid.server.configuration.QueueConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeReferrer; import org.apache.qpid.server.logging.LogSubject; @@ -39,9 +38,10 @@ import java.util.List; import java.util.Map; import java.util.Set; -public interface AMQQueue extends Comparable<AMQQueue>, ExchangeReferrer, TransactionLogResource, BaseQueue, - QueueConfig +public interface AMQQueue extends Comparable<AMQQueue>, ExchangeReferrer, TransactionLogResource, BaseQueue { + String getName(); + public interface NotificationListener { void notifyClients(NotificationCheck notification, AMQQueue queue, String notificationMsg); @@ -277,9 +277,7 @@ public interface AMQQueue extends Comparable<AMQQueue>, ExchangeReferrer, Transa public void doTask(AMQQueue queue) throws AMQException; } - void configure(ConfigurationPlugin config); - - ConfigurationPlugin getConfiguration(); + void configure(QueueConfiguration config); void setExclusive(boolean exclusive); @@ -315,4 +313,18 @@ public interface AMQQueue extends Comparable<AMQQueue>, ExchangeReferrer, Transa */ String getDescription(); + long getPersistentByteDequeues(); + + long getPersistentMsgDequeues(); + + long getPersistentByteEnqueues(); + + long getPersistentMsgEnqueues(); + + long getTotalDequeueSize(); + + long getTotalEnqueueSize(); + + long getUnackedMessageCount(); + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java index 3a18fae2ec..a65a6a8eb2 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java @@ -30,17 +30,25 @@ import org.apache.qpid.AMQSecurityException; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.server.configuration.BrokerProperties; import org.apache.qpid.server.configuration.QueueConfiguration; -import org.apache.qpid.server.configuration.ServerConfiguration; +import org.apache.qpid.server.exchange.DefaultExchangeFactory; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.exchange.ExchangeRegistry; import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.virtualhost.VirtualHost; public class AMQQueueFactory { + public static final String X_QPID_FLOW_RESUME_CAPACITY = "x-qpid-flow-resume-capacity"; + public static final String X_QPID_CAPACITY = "x-qpid-capacity"; + public static final String X_QPID_MINIMUM_ALERT_REPEAT_GAP = "x-qpid-minimum-alert-repeat-gap"; + public static final String X_QPID_MAXIMUM_MESSAGE_COUNT = "x-qpid-maximum-message-count"; + public static final String X_QPID_MAXIMUM_MESSAGE_SIZE = "x-qpid-maximum-message-size"; + public static final String X_QPID_MAXIMUM_MESSAGE_AGE = "x-qpid-maximum-message-age"; + public static final String X_QPID_MAXIMUM_QUEUE_DEPTH = "x-qpid-maximum-queue-depth"; + public static final String X_QPID_PRIORITIES = "x-qpid-priorities"; public static final String X_QPID_DESCRIPTION = "x-qpid-description"; public static final String QPID_LVQ_KEY = "qpid.LVQ_key"; @@ -119,42 +127,49 @@ public class AMQQueueFactory } private static final QueueProperty[] DECLAREABLE_PROPERTIES = { - new QueueLongProperty("x-qpid-maximum-message-age") + new QueueLongProperty(X_QPID_MAXIMUM_MESSAGE_AGE) { public void setPropertyValue(AMQQueue queue, long value) { queue.setMaximumMessageAge(value); } }, - new QueueLongProperty("x-qpid-maximum-message-size") + new QueueLongProperty(X_QPID_MAXIMUM_MESSAGE_SIZE) { public void setPropertyValue(AMQQueue queue, long value) { queue.setMaximumMessageSize(value); } }, - new QueueLongProperty("x-qpid-maximum-message-count") + new QueueLongProperty(X_QPID_MAXIMUM_MESSAGE_COUNT) { public void setPropertyValue(AMQQueue queue, long value) { queue.setMaximumMessageCount(value); } }, - new QueueLongProperty("x-qpid-minimum-alert-repeat-gap") + new QueueLongProperty(X_QPID_MAXIMUM_QUEUE_DEPTH) + { + public void setPropertyValue(AMQQueue queue, long value) + { + queue.setMaximumQueueDepth(value); + } + }, + new QueueLongProperty(X_QPID_MINIMUM_ALERT_REPEAT_GAP) { public void setPropertyValue(AMQQueue queue, long value) { queue.setMinimumAlertRepeatGap(value); } }, - new QueueLongProperty("x-qpid-capacity") + new QueueLongProperty(X_QPID_CAPACITY) { public void setPropertyValue(AMQQueue queue, long value) { queue.setCapacity(value); } }, - new QueueLongProperty("x-qpid-flow-resume-capacity") + new QueueLongProperty(X_QPID_FLOW_RESUME_CAPACITY) { public void setPropertyValue(AMQQueue queue, long value) { @@ -411,9 +426,7 @@ public class AMQQueueFactory */ protected static String getDeadLetterQueueName(String name) { - ServerConfiguration serverConfig = ApplicationRegistry.getInstance().getConfiguration(); - String dlQueueName = name + serverConfig.getDeadLetterQueueSuffix(); - return dlQueueName; + return name + System.getProperty(BrokerProperties.PROPERTY_DEAD_LETTER_QUEUE_SUFFIX, DEFAULT_DLQ_NAME_SUFFIX); } /** @@ -425,9 +438,7 @@ public class AMQQueueFactory */ protected static String getDeadLetterExchangeName(String name) { - ServerConfiguration serverConfig = ApplicationRegistry.getInstance().getConfiguration(); - String dlExchangeName = name + serverConfig.getDeadLetterExchangeSuffix(); - return dlExchangeName; + return name + System.getProperty(BrokerProperties.PROPERTY_DEAD_LETTER_EXCHANGE_SUFFIX, DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX); } private static Map<String, Object> createQueueArgumentsFromConfig(QueueConfiguration config) diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java index bbc33ca846..d7dbd58537 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java @@ -47,7 +47,7 @@ public class InboundMessageAdapter implements InboundMessage public AMQShortString getRoutingKeyShortString() { - return AMQShortString.valueOf(_entry.getMessage()); + return AMQShortString.valueOf(_entry.getMessage().getRoutingKey()); } public String getRoutingKey() diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java b/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java index c5a610c7b6..18affc7161 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java @@ -34,7 +34,6 @@ import org.apache.qpid.server.message.EnqueableMessage; import org.apache.qpid.server.message.InboundMessage; import org.apache.qpid.server.message.MessageContentSource; import org.apache.qpid.server.message.MessageMetaData; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.store.StoredMessage; import java.nio.ByteBuffer; @@ -47,9 +46,6 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes /** Used for debugging purposes. */ private static final Logger _logger = Logger.getLogger(IncomingMessage.class); - private static final boolean SYNCHED_CLOCKS = - ApplicationRegistry.getInstance().getConfiguration().getSynchedClocks(); - private final MessagePublishInfo _messagePublishInfo; private ContentHeaderBody _contentHeaderBody; @@ -101,33 +97,7 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes public void setExpiration() { - long expiration = - ((BasicContentHeaderProperties) _contentHeaderBody.getProperties()).getExpiration(); - long timestamp = - ((BasicContentHeaderProperties) _contentHeaderBody.getProperties()).getTimestamp(); - - if (SYNCHED_CLOCKS) - { - _expiration = expiration; - } - else - { - // Update TTL to be in broker time. - if (expiration != 0L) - { - if (timestamp != 0L) - { - // todo perhaps use arrival time - long diff = (System.currentTimeMillis() - timestamp); - - if ((diff > 1000L) || (diff < 1000L)) - { - _expiration = expiration + diff; - } - } - } - } - + _expiration = ((BasicContentHeaderProperties) _contentHeaderBody.getProperties()).getExpiration(); } public MessageMetaData headersReceived(long currentTime) diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java index 25e771a9cf..9aa8d1da83 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java @@ -454,7 +454,7 @@ public abstract class QueueEntryImpl implements QueueEntry { } - }, 0L); + }); txn.dequeue(currentQueue, message, new ServerTransaction.Action() { diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java index d42bd6cf03..73c2870b9b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java @@ -41,11 +41,8 @@ import org.apache.qpid.AMQSecurityException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.pool.ReferenceCountingExecutorService; import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.QueueConfigType; import org.apache.qpid.server.configuration.QueueConfiguration; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; +import org.apache.qpid.server.configuration.plugins.AbstractConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.LogSubject; @@ -55,7 +52,6 @@ import org.apache.qpid.server.logging.messages.QueueMessages; import org.apache.qpid.server.logging.subjects.QueueLogSubject; import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.server.protocol.AMQSessionModel; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.security.AuthorizationHolder; import org.apache.qpid.server.subscription.AssignedSubscriptionMessageGroupManager; import org.apache.qpid.server.subscription.DefinedGroupMessageGroupManager; @@ -135,23 +131,23 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes private final AtomicInteger _bindingCountHigh = new AtomicInteger(); /** max allowed size(KB) of a single message */ - private long _maximumMessageSize = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageSize(); + private long _maximumMessageSize; /** max allowed number of messages on a queue. */ - private long _maximumMessageCount = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageCount(); + private long _maximumMessageCount; /** max queue depth for the queue */ - private long _maximumQueueDepth = ApplicationRegistry.getInstance().getConfiguration().getMaximumQueueDepth(); + private long _maximumQueueDepth; /** maximum message age before alerts occur */ - private long _maximumMessageAge = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageAge(); + private long _maximumMessageAge; /** the minimum interval between sending out consecutive alerts of the same type */ - private long _minimumAlertRepeatGap = ApplicationRegistry.getInstance().getConfiguration().getMinimumAlertRepeatGap(); + private long _minimumAlertRepeatGap; - private long _capacity = ApplicationRegistry.getInstance().getConfiguration().getCapacity(); + private long _capacity; - private long _flowResumeCapacity = ApplicationRegistry.getInstance().getConfiguration().getFlowResumeCapacity(); + private long _flowResumeCapacity; private final Set<NotificationCheck> _notificationChecks = EnumSet.noneOf(NotificationCheck.class); @@ -185,11 +181,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes //TODO : persist creation time private long _createTime = System.currentTimeMillis(); - private UUID _qmfId; - private ConfigurationPlugin _queueConfiguration; + private AbstractConfiguration _queueConfiguration; /** the maximum delivery count for each message on this queue or 0 if maximum delivery count is not to be enforced. */ - private int _maximumDeliveryCount = ApplicationRegistry.getInstance().getConfiguration().getMaxDeliveryCount(); + private int _maximumDeliveryCount; private final MessageGroupManager _messageGroupManager; private final Collection<SubscriptionRegistrationListener> _subscriptionListeners = @@ -243,7 +238,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes _arguments = arguments == null ? new HashMap<String, Object>() : new HashMap<String, Object>(arguments); _id = id; - _qmfId = getConfigStore().createId(); _asyncDelivery = ReferenceCountingExecutorService.getInstance().acquireExecutorService(); _logSubject = new QueueLogSubject(this); @@ -259,8 +253,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes durable, !durable, _entries.getPriorities() > 0)); - getConfigStore().addConfiguredObject(this); - if(arguments != null && arguments.containsKey(QPID_GROUP_HEADER_KEY)) { if(arguments.containsKey(QPID_SHARED_MSG_GROUP) && String.valueOf(arguments.get(QPID_SHARED_MSG_GROUP)).equals("1")) @@ -331,22 +323,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes return _id; } - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public QueueConfigType getConfigType() - { - return QueueConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getVirtualHost(); - } - public boolean isDurable() { return _durable; @@ -621,24 +597,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes break; } } - - reconfigure(); - } - - private void reconfigure() - { - //Reconfigure the queue for to reflect this new binding. - ConfigurationPlugin config = getVirtualHost().getConfiguration().getQueueConfiguration(this); - - if (config != null) - { - if (_logger.isDebugEnabled()) - { - _logger.debug("Reconfiguring queue(" + this + ") with config:" + config + " was "+ _queueConfiguration); - } - // Reconfigure with new config. - configure(config); - } } public int getBindingCountHigh() @@ -649,8 +607,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes public void removeBinding(final Binding binding) { _bindings.remove(binding); - - reconfigure(); } public List<Binding> getBindings() @@ -1383,7 +1339,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes } _virtualHost.getQueueRegistry().unregisterQueue(_name); - getConfigStore().removeConfiguredObject(this); List<QueueEntry> entries = getMessagesOnTheQueue(new QueueEntryFilter() { @@ -1442,7 +1397,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes { } - }, 0L); + }); txn.dequeue(this, entry.getMessage(), new ServerTransaction.Action() { @@ -2161,39 +2116,21 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes } - public void configure(ConfigurationPlugin config) + public void configure(QueueConfiguration config) { if (config != null) { - if (config instanceof QueueConfiguration) - { - - setMaximumMessageAge(((QueueConfiguration)config).getMaximumMessageAge()); - setMaximumQueueDepth(((QueueConfiguration)config).getMaximumQueueDepth()); - setMaximumMessageSize(((QueueConfiguration)config).getMaximumMessageSize()); - setMaximumMessageCount(((QueueConfiguration)config).getMaximumMessageCount()); - setMinimumAlertRepeatGap(((QueueConfiguration)config).getMinimumAlertRepeatGap()); - setMaximumDeliveryCount(((QueueConfiguration)config).getMaxDeliveryCount()); - _capacity = ((QueueConfiguration)config).getCapacity(); - _flowResumeCapacity = ((QueueConfiguration)config).getFlowResumeCapacity(); - } - - _queueConfiguration = config; - + setMaximumMessageAge(config.getMaximumMessageAge()); + setMaximumQueueDepth(config.getMaximumQueueDepth()); + setMaximumMessageSize(config.getMaximumMessageSize()); + setMaximumMessageCount(config.getMaximumMessageCount()); + setMinimumAlertRepeatGap(config.getMinimumAlertRepeatGap()); + setMaximumDeliveryCount(config.getMaxDeliveryCount()); + _capacity = config.getCapacity(); + _flowResumeCapacity = config.getFlowResumeCapacity(); } } - - public ConfigurationPlugin getConfiguration() - { - return _queueConfiguration; - } - - public ConfigStore getConfigStore() - { - return getVirtualHost().getConfigStore(); - } - public long getMessageDequeueCount() { return _dequeueCount.get(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java index e0e317f75d..1379b375cf 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java @@ -20,44 +20,39 @@ */ package org.apache.qpid.server.registry; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.log4j.Logger; -import org.apache.qpid.server.logging.*; -import org.osgi.framework.BundleContext; +import java.util.Collection; +import java.util.Timer; +import java.util.TimerTask; +import org.apache.log4j.Logger; import org.apache.qpid.common.Closeable; import org.apache.qpid.common.QpidProperties; -import org.apache.qpid.qmf.QMFService; -import org.apache.qpid.server.configuration.BrokerConfig; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfigurationManager; -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.configuration.SystemConfig; -import org.apache.qpid.server.configuration.SystemConfigImpl; -import org.apache.qpid.server.configuration.VirtualHostConfiguration; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.configuration.startup.DefaultRecovererProvider; +import org.apache.qpid.server.logging.CompositeStartupMessageLogger; +import org.apache.qpid.server.logging.Log4jMessageLogger; +import org.apache.qpid.server.logging.LogActor; +import org.apache.qpid.server.logging.LogRecorder; +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.logging.SystemOutMessageLogger; import org.apache.qpid.server.logging.actors.AbstractActor; import org.apache.qpid.server.logging.actors.BrokerActor; import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.logging.actors.GenericActor; import org.apache.qpid.server.logging.messages.BrokerMessages; import org.apache.qpid.server.logging.messages.VirtualHostMessages; import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.model.adapter.BrokerAdapter; -import org.apache.qpid.server.plugins.PluginManager; -import org.apache.qpid.server.security.SecurityManager; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; -import org.apache.qpid.server.security.auth.manager.AuthenticationManagerRegistry; -import org.apache.qpid.server.security.auth.manager.IAuthenticationManagerRegistry; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.stats.StatisticsCounter; -import org.apache.qpid.server.transport.QpidAcceptor; +import org.apache.qpid.server.stats.StatisticsGatherer; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.virtualhost.VirtualHostImpl; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.*; -import java.util.concurrent.atomic.AtomicReference; - /** * An abstract application registry that provides access to configuration information and handles the @@ -65,321 +60,90 @@ import java.util.concurrent.atomic.AtomicReference; * <p/> * Subclasses should handle the construction of the "registered objects" such as the exchange registry. */ -public abstract class ApplicationRegistry implements IApplicationRegistry +public class ApplicationRegistry implements IApplicationRegistry { - private static final Logger _logger = Logger.getLogger(ApplicationRegistry.class); - private static AtomicReference<IApplicationRegistry> _instance = new AtomicReference<IApplicationRegistry>(null); - - private final ServerConfiguration _configuration; - - private final Map<InetSocketAddress, QpidAcceptor> _acceptors = - Collections.synchronizedMap(new HashMap<InetSocketAddress, QpidAcceptor>()); - - private IAuthenticationManagerRegistry _authenticationManagerRegistry; - - private final VirtualHostRegistry _virtualHostRegistry = new VirtualHostRegistry(this); - - private SecurityManager _securityManager; + private final VirtualHostRegistry _virtualHostRegistry = new VirtualHostRegistry(); - private PluginManager _pluginManager; - - private ConfigurationManager _configurationManager; - - private RootMessageLogger _rootMessageLogger; - - private CompositeStartupMessageLogger _startupMessageLogger; - - private UUID _brokerId = UUID.randomUUID(); - - private QMFService _qmfService; - - private BrokerConfig _brokerConfig; + private volatile RootMessageLogger _rootMessageLogger; private Broker _broker; - private ConfigStore _configStore; - private Timer _reportingTimer; private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived; - private BundleContext _bundleContext; - - private final List<PortBindingListener> _portBindingListeners = new ArrayList<PortBindingListener>(); - - private int _httpManagementPort = -1, _httpsManagementPort = -1; - private LogRecorder _logRecorder; - private List<IAuthenticationManagerRegistry.RegistryChangeListener> _authManagerChangeListeners = - new ArrayList<IAuthenticationManagerRegistry.RegistryChangeListener>(); - - public Map<InetSocketAddress, QpidAcceptor> getAcceptors() - { - synchronized (_acceptors) - { - return new HashMap<InetSocketAddress, QpidAcceptor>(_acceptors); - } - } - - protected void setSecurityManager(SecurityManager securityManager) - { - _securityManager = securityManager; - } - - protected void setPluginManager(PluginManager pluginManager) - { - _pluginManager = pluginManager; - } - - protected void setConfigurationManager(ConfigurationManager configurationManager) - { - _configurationManager = configurationManager; - } + private ConfigurationEntryStore _store; + private TaskExecutor _taskExecutor; protected void setRootMessageLogger(RootMessageLogger rootMessageLogger) { _rootMessageLogger = rootMessageLogger; } - protected CompositeStartupMessageLogger getStartupMessageLogger() - { - return _startupMessageLogger; - } - - protected void setStartupMessageLogger(CompositeStartupMessageLogger startupMessageLogger) + public ApplicationRegistry(ConfigurationEntryStore store) { - _startupMessageLogger = startupMessageLogger; - } - - protected void setBrokerId(UUID brokerId) - { - _brokerId = brokerId; - } - - protected QMFService getQmfService() - { - return _qmfService; - } - - protected void setQmfService(QMFService qmfService) - { - _qmfService = qmfService; - } - - public static void initialise(IApplicationRegistry instance) throws Exception - { - if(instance == null) - { - throw new IllegalArgumentException("ApplicationRegistry instance must not be null"); - } - - if(!_instance.compareAndSet(null, instance)) - { - throw new IllegalStateException("An ApplicationRegistry is already initialised"); - } - - _logger.info("Initialising Application Registry(" + instance + ")"); - - - final ConfigStore store = ConfigStore.newInstance(); - store.setRoot(new SystemConfigImpl(store)); - instance.setConfigStore(store); - - final BrokerConfig brokerConfig = new BrokerConfigAdapter(instance); - - final SystemConfig system = store.getRoot(); - system.addBroker(brokerConfig); - instance.setBrokerConfig(brokerConfig); - - try - { - instance.initialise(); - } - catch (Exception e) - { - _instance.set(null); - - //remove the Broker instance, then re-throw - try - { - system.removeBroker(brokerConfig); - } - catch(Throwable t) - { - //ignore - } - - throw e; - } - } - - public ConfigStore getConfigStore() - { - return _configStore; - } - - public void setConfigStore(final ConfigStore configStore) - { - _configStore = configStore; - } - - public static boolean isConfigured() - { - return _instance.get() != null; - } - - public static void remove() - { - IApplicationRegistry instance = _instance.getAndSet(null); - try - { - if (instance != null) - { - if (_logger.isInfoEnabled()) - { - _logger.info("Shutting down ApplicationRegistry(" + instance + ")"); - } - instance.close(); - } - } - catch (Exception e) - { - _logger.error("Error shutting down Application Registry(" + instance + "): " + e, e); - } - } - - protected ApplicationRegistry(ServerConfiguration configuration) - { - this(configuration, null); - } - - protected ApplicationRegistry(ServerConfiguration configuration, BundleContext bundleContext) - { - _configuration = configuration; - _bundleContext = bundleContext; - } - - public void configure() throws ConfigurationException - { - _configurationManager = new ConfigurationManager(); - - try - { - _pluginManager = new PluginManager(_configuration.getPluginDirectory(), _configuration.getCacheDirectory(), _bundleContext); - } - catch (Exception e) - { - throw new ConfigurationException(e); - } - - _configuration.initialise(); + _store = store; + initialiseStatistics(); } public void initialise() throws Exception { + // Create the RootLogger to be used during broker operation + boolean statusUpdatesEnabled = Boolean.parseBoolean(System.getProperty(BrokerProperties.PROPERTY_STATUS_UPDATES, "true")); + _rootMessageLogger = new Log4jMessageLogger(statusUpdatesEnabled); + _logRecorder = new LogRecorder(); - //Create the RootLogger to be used during broker operation - _rootMessageLogger = new Log4jMessageLogger(_configuration); //Create the composite (log4j+SystemOut MessageLogger to be used during startup RootMessageLogger[] messageLoggers = {new SystemOutMessageLogger(), _rootMessageLogger}; - _startupMessageLogger = new CompositeStartupMessageLogger(messageLoggers); + CompositeStartupMessageLogger startupMessageLogger = new CompositeStartupMessageLogger(messageLoggers); - BrokerActor actor = new BrokerActor(_startupMessageLogger); - CurrentActor.setDefault(actor); + BrokerActor actor = new BrokerActor(startupMessageLogger); CurrentActor.set(actor); - + CurrentActor.setDefault(actor); + GenericActor.setDefaultMessageLogger(_rootMessageLogger); try { - initialiseStatistics(); - - if(_configuration.getHTTPManagementEnabled()) - { - _httpManagementPort = _configuration.getHTTPManagementPort(); - } - if (_configuration.getHTTPSManagementEnabled()) - { - _httpsManagementPort = _configuration.getHTTPSManagementPort(); - } - - _broker = new BrokerAdapter(this); - - configure(); - - _qmfService = new QMFService(getConfigStore(), this); - logStartupMessages(CurrentActor.get()); - _securityManager = new SecurityManager(_configuration, _pluginManager); + _taskExecutor = new TaskExecutor(); + _taskExecutor.start(); - _authenticationManagerRegistry = createAuthenticationManagerRegistry(_configuration, _pluginManager); + RecovererProvider provider = new DefaultRecovererProvider((StatisticsGatherer)this, _virtualHostRegistry, _logRecorder, _rootMessageLogger, _taskExecutor); + ConfiguredObjectRecoverer<? extends ConfiguredObject> brokerRecoverer = provider.getRecoverer(Broker.class.getSimpleName()); + _broker = (Broker) brokerRecoverer.create(provider, _store.getRootEntry()); - if(!_authManagerChangeListeners.isEmpty()) - { - for(IAuthenticationManagerRegistry.RegistryChangeListener listener : _authManagerChangeListeners) - { + _virtualHostRegistry.setDefaultVirtualHostName((String)_broker.getAttribute(Broker.DEFAULT_VIRTUAL_HOST)); - _authenticationManagerRegistry.addRegistryChangeListener(listener); - for(AuthenticationManager authMgr : _authenticationManagerRegistry.getAvailableAuthenticationManagers().values()) - { - listener.authenticationManagerRegistered(authMgr); - } - } - _authManagerChangeListeners.clear(); - } - } - finally - { - CurrentActor.remove(); - } - - CurrentActor.set(new BrokerActor(_rootMessageLogger)); - try - { - initialiseVirtualHosts(); initialiseStatisticsReporting(); + + // starting the broker + _broker.setDesiredState(State.INITIALISING, State.ACTIVE); + + CurrentActor.get().message(BrokerMessages.READY()); } finally { - // Startup complete, so pop the current actor CurrentActor.remove(); } - } - protected IAuthenticationManagerRegistry createAuthenticationManagerRegistry(ServerConfiguration _configuration, PluginManager _pluginManager) - throws ConfigurationException - { - return new AuthenticationManagerRegistry(_configuration, _pluginManager); + CurrentActor.setDefault(new BrokerActor(_rootMessageLogger)); } - protected void initialiseVirtualHosts() throws Exception + private void initialiseStatisticsReporting() { - for (String name : _configuration.getVirtualHosts()) - { - createVirtualHost(_configuration.getVirtualHostConfig(name)); - } - getVirtualHostRegistry().setDefaultVirtualHostName(_configuration.getDefaultVirtualHost()); - } - - public void initialiseStatisticsReporting() - { - long report = _configuration.getStatisticsReportingPeriod() * 1000; // convert to ms - final boolean broker = _configuration.isStatisticsGenerationBrokerEnabled(); - final boolean virtualhost = _configuration.isStatisticsGenerationVirtualhostsEnabled(); - final boolean reset = _configuration.isStatisticsReportResetEnabled(); + long report = ((Number)_broker.getAttribute(Broker.STATISTICS_REPORTING_PERIOD)).intValue() * 1000; // convert to ms + final boolean reset = (Boolean)_broker.getAttribute(Broker.STATISTICS_REPORTING_RESET_ENABLED); /* add a timer task to report statistics if generation is enabled for broker or virtualhosts */ - if (report > 0L && (broker || virtualhost)) + if (report > 0L) { _reportingTimer = new Timer("Statistics-Reporting", true); - - - - _reportingTimer.scheduleAtFixedRate(new StatisticsReportingTask(broker, virtualhost, reset), - report / 2, - report); + StatisticsReportingTask task = new StatisticsReportingTask(reset, _rootMessageLogger); + _reportingTimer.scheduleAtFixedRate(task, report / 2, report); } } @@ -388,76 +152,62 @@ public abstract class ApplicationRegistry implements IApplicationRegistry private final int DELIVERED = 0; private final int RECEIVED = 1; - private boolean _broker; - private boolean _virtualhost; - private boolean _reset; + private final boolean _reset; + private final RootMessageLogger _logger; - - public StatisticsReportingTask(boolean broker, boolean virtualhost, boolean reset) + public StatisticsReportingTask(boolean reset, RootMessageLogger logger) { - _broker = broker; - _virtualhost = virtualhost; _reset = reset; + _logger = logger; } public void run() { - CurrentActor.set(new AbstractActor(ApplicationRegistry.getInstance().getRootMessageLogger()) { + CurrentActor.set(new AbstractActor(_logger) + { public String getLogMessage() { return "[" + Thread.currentThread().getName() + "] "; } }); - - if (_broker) + try { CurrentActor.get().message(BrokerMessages.STATS_DATA(DELIVERED, _dataDelivered.getPeak() / 1024.0, _dataDelivered.getTotal())); CurrentActor.get().message(BrokerMessages.STATS_MSGS(DELIVERED, _messagesDelivered.getPeak(), _messagesDelivered.getTotal())); CurrentActor.get().message(BrokerMessages.STATS_DATA(RECEIVED, _dataReceived.getPeak() / 1024.0, _dataReceived.getTotal())); CurrentActor.get().message(BrokerMessages.STATS_MSGS(RECEIVED, _messagesReceived.getPeak(), _messagesReceived.getTotal())); - } + Collection<VirtualHost> hosts = _virtualHostRegistry.getVirtualHosts(); - if (_virtualhost) - { - for (VirtualHost vhost : getVirtualHostRegistry().getVirtualHosts()) + if (hosts.size() > 1) { - String name = vhost.getName(); - StatisticsCounter dataDelivered = vhost.getDataDeliveryStatistics(); - StatisticsCounter messagesDelivered = vhost.getMessageDeliveryStatistics(); - StatisticsCounter dataReceived = vhost.getDataReceiptStatistics(); - StatisticsCounter messagesReceived = vhost.getMessageReceiptStatistics(); - - CurrentActor.get().message(VirtualHostMessages.STATS_DATA(name, DELIVERED, dataDelivered.getPeak() / 1024.0, dataDelivered.getTotal())); - CurrentActor.get().message(VirtualHostMessages.STATS_MSGS(name, DELIVERED, messagesDelivered.getPeak(), messagesDelivered.getTotal())); - CurrentActor.get().message(VirtualHostMessages.STATS_DATA(name, RECEIVED, dataReceived.getPeak() / 1024.0, dataReceived.getTotal())); - CurrentActor.get().message(VirtualHostMessages.STATS_MSGS(name, RECEIVED, messagesReceived.getPeak(), messagesReceived.getTotal())); + for (VirtualHost vhost : hosts) + { + String name = vhost.getName(); + StatisticsCounter dataDelivered = vhost.getDataDeliveryStatistics(); + StatisticsCounter messagesDelivered = vhost.getMessageDeliveryStatistics(); + StatisticsCounter dataReceived = vhost.getDataReceiptStatistics(); + StatisticsCounter messagesReceived = vhost.getMessageReceiptStatistics(); + + CurrentActor.get().message(VirtualHostMessages.STATS_DATA(name, DELIVERED, dataDelivered.getPeak() / 1024.0, dataDelivered.getTotal())); + CurrentActor.get().message(VirtualHostMessages.STATS_MSGS(name, DELIVERED, messagesDelivered.getPeak(), messagesDelivered.getTotal())); + CurrentActor.get().message(VirtualHostMessages.STATS_DATA(name, RECEIVED, dataReceived.getPeak() / 1024.0, dataReceived.getTotal())); + CurrentActor.get().message(VirtualHostMessages.STATS_MSGS(name, RECEIVED, messagesReceived.getPeak(), messagesReceived.getTotal())); + } } - } - if (_reset) + if (_reset) + { + resetStatistics(); + } + } + catch(Exception e) { - resetStatistics(); + ApplicationRegistry._logger.warn("Unexpected exception occured while reporting the statistics", e); + } + finally + { + CurrentActor.remove(); } - - CurrentActor.remove(); - } - } - - /** - * Get the ApplicationRegistry - * @return the IApplicationRegistry instance - * @throws IllegalStateException if no registry instance has been initialised. - */ - public static IApplicationRegistry getInstance() throws IllegalStateException - { - IApplicationRegistry iApplicationRegistry = _instance.get(); - if (iApplicationRegistry == null) - { - throw new IllegalStateException("No ApplicationRegistry has been initialised"); - } - else - { - return iApplicationRegistry; } } @@ -488,7 +238,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry } //Set the Actor for Broker Shutdown - CurrentActor.set(new BrokerActor(getRootMessageLogger())); + CurrentActor.set(new BrokerActor(_rootMessageLogger)); try { //Stop Statistics Reporting @@ -497,154 +247,34 @@ public abstract class ApplicationRegistry implements IApplicationRegistry _reportingTimer.cancel(); } - //Stop incoming connections - unbind(); + if (_broker != null) + { + _broker.setDesiredState(_broker.getActualState(), State.STOPPED); + } //Shutdown virtualhosts close(_virtualHostRegistry); - close(_authenticationManagerRegistry); - - close(_qmfService); - - close(_pluginManager); - - BrokerConfig broker = getBrokerConfig(); - if(broker != null) + if (_taskExecutor != null) { - broker.getSystem().removeBroker(broker); + _taskExecutor.stop(); } CurrentActor.get().message(BrokerMessages.STOPPED()); - } - finally - { - CurrentActor.remove(); - } - } - - private void unbind() - { - List<QpidAcceptor> removedAcceptors = new ArrayList<QpidAcceptor>(); - synchronized (_acceptors) - { - for (InetSocketAddress bindAddress : _acceptors.keySet()) - { - QpidAcceptor acceptor = _acceptors.get(bindAddress); - removedAcceptors.add(acceptor); - try - { - acceptor.getNetworkTransport().close(); - } - catch (Throwable e) - { - _logger.error("Unable to close network driver due to:" + e.getMessage()); - } + _logRecorder.closeLogRecorder(); - CurrentActor.get().message(BrokerMessages.SHUTTING_DOWN(acceptor.toString(), bindAddress.getPort())); - } } - synchronized (_portBindingListeners) - { - for(QpidAcceptor acceptor : removedAcceptors) - { - for(PortBindingListener listener : _portBindingListeners) - { - listener.unbound(acceptor); - } - } - } - } - - public ServerConfiguration getConfiguration() - { - return _configuration; - } - - public void addAcceptor(InetSocketAddress bindAddress, QpidAcceptor acceptor) - { - synchronized (_acceptors) - { - _acceptors.put(bindAddress, acceptor); - } - synchronized (_portBindingListeners) + finally { - for(PortBindingListener listener : _portBindingListeners) + if (_taskExecutor != null) { - listener.bound(acceptor, bindAddress); + _taskExecutor.stopImmediately(); } + CurrentActor.remove(); } - } - - public VirtualHostRegistry getVirtualHostRegistry() - { - return _virtualHostRegistry; - } - - public SecurityManager getSecurityManager() - { - return _securityManager; - } - - @Override - public AuthenticationManager getAuthenticationManager(SocketAddress address) - { - return _authenticationManagerRegistry.getAuthenticationManager(address); - } - - @Override - public IAuthenticationManagerRegistry getAuthenticationManagerRegistry() - { - return _authenticationManagerRegistry; - } - - public PluginManager getPluginManager() - { - return _pluginManager; - } - - public ConfigurationManager getConfigurationManager() - { - return _configurationManager; - } - - public RootMessageLogger getRootMessageLogger() - { - return _rootMessageLogger; - } - - public RootMessageLogger getCompositeStartupMessageLogger() - { - return _startupMessageLogger; - } - - public UUID getBrokerId() - { - return _brokerId; - } - - public QMFService getQMFService() - { - return _qmfService; - } - - public BrokerConfig getBrokerConfig() - { - return _brokerConfig; - } - - public void setBrokerConfig(final BrokerConfig broker) - { - _brokerConfig = broker; - } - - public VirtualHost createVirtualHost(final VirtualHostConfiguration vhostConfig) throws Exception - { - VirtualHostImpl virtualHost = new VirtualHostImpl(this, vhostConfig); - _virtualHostRegistry.registerVirtualHost(virtualHost); - getBrokerConfig().addVirtualHost(virtualHost); - return virtualHost; + _store = null; + _broker = null; } public void registerMessageDelivered(long messageSize) @@ -713,60 +343,10 @@ public abstract class ApplicationRegistry implements IApplicationRegistry logActor.message(BrokerMessages.MAX_MEMORY(Runtime.getRuntime().maxMemory())); } + @Override public Broker getBroker() { return _broker; } - @Override - public void addPortBindingListener(PortBindingListener listener) - { - synchronized (_portBindingListeners) - { - _portBindingListeners.add(listener); - } - } - - - @Override - public boolean useHTTPManagement() - { - return _httpManagementPort != -1; - } - - @Override - public int getHTTPManagementPort() - { - return _httpManagementPort; - } - - @Override - public boolean useHTTPSManagement() - { - return _httpsManagementPort != -1; - } - - @Override - public int getHTTPSManagementPort() - { - return _httpsManagementPort; - } - - public LogRecorder getLogRecorder() - { - return _logRecorder; - } - - @Override - public void addRegistryChangeListener(IAuthenticationManagerRegistry.RegistryChangeListener registryChangeListener) - { - if(_authenticationManagerRegistry == null) - { - _authManagerChangeListeners.add(registryChangeListener); - } - else - { - _authenticationManagerRegistry.addRegistryChangeListener(registryChangeListener); - } - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java deleted file mode 100644 index 950a090b43..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * - * 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.registry; - -import org.apache.qpid.common.QpidProperties; -import org.apache.qpid.common.ServerPropertyNames; -import org.apache.qpid.server.configuration.BrokerConfig; -import org.apache.qpid.server.configuration.BrokerConfigType; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.SystemConfig; -import org.apache.qpid.server.configuration.VirtualHostConfig; -import org.apache.qpid.server.virtualhost.VirtualHost; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - -public class BrokerConfigAdapter implements BrokerConfig -{ - private final IApplicationRegistry _instance; - private SystemConfig _system; - - private final Map<UUID, VirtualHostConfig> _vhosts = new ConcurrentHashMap<UUID, VirtualHostConfig>(); - private final long _createTime = System.currentTimeMillis(); - private UUID _qmfId; - private String _federationTag; - - public BrokerConfigAdapter(final IApplicationRegistry instance) - { - _instance = instance; - _qmfId = instance.getConfigStore().createId(); - _federationTag = UUID.randomUUID().toString(); - } - - public void setSystem(final SystemConfig system) - { - _system = system; - } - - public SystemConfig getSystem() - { - return _system; - } - - public Integer getPort() - { - List ports = _instance.getConfiguration().getPorts(); - if(ports.size() > 0) - { - return Integer.valueOf(ports.get(0).toString()); - } - else - { - return 0; - } - } - - public Integer getWorkerThreads() - { - return _instance.getConfiguration().getConnectorProcessors(); - } - - public Integer getMaxConnections() - { - return 0; - } - - public Integer getConnectionBacklogLimit() - { - return 0; - } - - public Long getStagingThreshold() - { - return 0L; - } - - public Integer getManagementPublishInterval() - { - return 10000; - } - - public String getVersion() - { - return QpidProperties.getReleaseVersion() + " [Build: " + QpidProperties.getBuildVersion() + "]"; - } - - public String getDataDirectory() - { - return _instance.getConfiguration().getQpidWork(); - } - - public void addVirtualHost(final VirtualHostConfig virtualHost) - { - _vhosts.put(virtualHost.getQMFId(), virtualHost); - getConfigStore().addConfiguredObject(virtualHost); - - } - - private ConfigStore getConfigStore() - { - return _instance.getConfigStore(); - } - - public long getCreateTime() - { - return _createTime; - } - - public void createBrokerConnection(final String transport, - final String host, - final int port, - final boolean durable, - final String authMechanism, - final String username, - final String password) - { - VirtualHost vhost = _instance.getVirtualHostRegistry().getDefaultVirtualHost(); - vhost.createBrokerConnection(transport, host, port, "", durable, authMechanism, username, password); - } - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public BrokerConfigType getConfigType() - { - return BrokerConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return _system; - } - - public boolean isDurable() - { - return false; - } - - public String getFederationTag() - { - return _federationTag; - } - - /** - * @see org.apache.qpid.server.configuration.BrokerConfig#getFeatures() - */ - public List<String> getFeatures() - { - final List<String> features = new ArrayList<String>(); - if (!_instance.getConfiguration().getDisabledFeatures().contains(ServerPropertyNames.FEATURE_QPID_JMS_SELECTOR)) - { - features.add(ServerPropertyNames.FEATURE_QPID_JMS_SELECTOR); - } - - return Collections.unmodifiableList(features); - } - - @Override - public String toString() - { - return "BrokerConfigAdapter{" + - "_id=" + _qmfId + - ", _system=" + _system + - ", _vhosts=" + _vhosts + - ", _createTime=" + _createTime + - ", _federationTag='" + _federationTag + '\'' + - '}'; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java deleted file mode 100644 index 774d0338ef..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * 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.registry; - -import org.apache.commons.configuration.ConfigurationException; -import org.osgi.framework.BundleContext; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.configuration.ServerConfiguration; - -import java.io.File; - -public class ConfigurationFileApplicationRegistry extends ApplicationRegistry -{ - public ConfigurationFileApplicationRegistry(File configurationURL) throws ConfigurationException - { - this(configurationURL, null); - } - - public ConfigurationFileApplicationRegistry(File configurationURL, BundleContext bundleContext) throws ConfigurationException - { - super(new ServerConfiguration(configurationURL), bundleContext); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java index 88c3c93156..d12258d194 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java @@ -20,27 +20,8 @@ */ package org.apache.qpid.server.registry; -import org.apache.qpid.qmf.QMFService; -import org.apache.qpid.server.configuration.BrokerConfig; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfigurationManager; -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.configuration.VirtualHostConfiguration; -import org.apache.qpid.server.logging.RootMessageLogger; import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.plugins.PluginManager; -import org.apache.qpid.server.security.SecurityManager; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; -import org.apache.qpid.server.security.auth.manager.IAuthenticationManagerRegistry; import org.apache.qpid.server.stats.StatisticsGatherer; -import org.apache.qpid.server.transport.QpidAcceptor; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.virtualhost.VirtualHostRegistry; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.Map; -import java.util.UUID; public interface IApplicationRegistry extends StatisticsGatherer { @@ -56,80 +37,5 @@ public interface IApplicationRegistry extends StatisticsGatherer */ void close(); - /** - * Get the low level configuration. For use cases where the configured object approach is not required - * you can get the complete configuration information. - * @return a Commons Configuration instance - */ - ServerConfiguration getConfiguration(); - - /** - * Get the AuthenticationManager for the given socket address - * - * If no AuthenticationManager has been specifically set for the given address, then use the default - * AuthenticationManager - * - * @param address The (listening) socket address for which the AuthenticationManager is required - * @return the AuthenticationManager - */ - AuthenticationManager getAuthenticationManager(SocketAddress address); - - IAuthenticationManagerRegistry getAuthenticationManagerRegistry(); - - VirtualHostRegistry getVirtualHostRegistry(); - - SecurityManager getSecurityManager(); - - PluginManager getPluginManager(); - - ConfigurationManager getConfigurationManager(); - - RootMessageLogger getRootMessageLogger(); - - /** - * Register any acceptors for this registry - * @param bindAddress The address that the acceptor has been bound with - * @param acceptor The acceptor in use - */ - void addAcceptor(InetSocketAddress bindAddress, QpidAcceptor acceptor); - - public UUID getBrokerId(); - - QMFService getQMFService(); - - void setBrokerConfig(BrokerConfig broker); - - BrokerConfig getBrokerConfig(); - Broker getBroker(); - - VirtualHost createVirtualHost(VirtualHostConfiguration vhostConfig) throws Exception; - - ConfigStore getConfigStore(); - - void setConfigStore(ConfigStore store); - - void initialiseStatisticsReporting(); - - Map<InetSocketAddress, QpidAcceptor> getAcceptors(); - - void addPortBindingListener(PortBindingListener listener); - - boolean useHTTPManagement(); - - int getHTTPManagementPort(); - - boolean useHTTPSManagement(); - - int getHTTPSManagementPort(); - - void addRegistryChangeListener(IAuthenticationManagerRegistry.RegistryChangeListener registryChangeListener); - - public interface PortBindingListener - { - public void bound(QpidAcceptor acceptor, InetSocketAddress bindAddress); - public void unbound(QpidAcceptor acceptor); - - } - } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java deleted file mode 100644 index 704e50da5c..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * 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.security; - -import org.apache.log4j.Logger; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.security.access.ObjectProperties; -import org.apache.qpid.server.security.access.ObjectType; -import org.apache.qpid.server.security.access.Operation; - -/** - * This is intended as the parent for all simple plugins. - */ -public abstract class AbstractPlugin implements SecurityPlugin -{ - private final Logger _logger = Logger.getLogger(getClass()); - - private ConfigurationPlugin _config; - - public Result getDefault() - { - return Result.ABSTAIN; - } - - public abstract Result access(ObjectType object, Object instance); - - public abstract Result authorise(Operation operation, ObjectType object, ObjectProperties properties); - - public void configure(ConfigurationPlugin config) - { - _config = config; - } - - public ConfigurationPlugin getConfig() - { - return _config; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java deleted file mode 100644 index 236931e8cd..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * - * 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.security; - -import org.apache.qpid.server.security.access.ObjectProperties; -import org.apache.qpid.server.security.access.ObjectType; -import org.apache.qpid.server.security.access.Operation; - -/** - * This {@link SecurityPlugin} proxies the authorise calls to a serries of methods, one per {@link Operation}. - * - */ -public abstract class AbstractProxyPlugin extends AbstractPlugin -{ - public Result authoriseConsume(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authorisePublish(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authoriseCreate(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authoriseAccess(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authoriseBind(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authoriseUnbind(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authoriseDelete(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authorisePurge(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authoriseUpdate(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result accessVirtualhost(Object instance) - { - return getDefault(); - } - - @Override - public Result access(ObjectType objectType, Object instance) - { - switch (objectType) - { - case VIRTUALHOST: - return accessVirtualhost(instance); - } - - return getDefault(); - } - - @Override - public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties) - { - switch (operation) - { - case CONSUME: - return authoriseConsume(objectType, properties); - case PUBLISH: - return authorisePublish(objectType, properties); - case CREATE: - return authoriseCreate(objectType, properties); - case ACCESS: - return authoriseAccess(objectType, properties); - case BIND: - return authoriseBind(objectType, properties); - case UNBIND: - return authoriseUnbind(objectType, properties); - case DELETE: - return authoriseDelete(objectType, properties); - case PURGE: - return authorisePurge(objectType, properties); - case UPDATE: - return authoriseUpdate(objectType, properties); - } - - return getDefault(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/AccessControl.java index c3c06bf206..b4831f83e5 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPlugin.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/AccessControl.java @@ -18,28 +18,26 @@ */ package org.apache.qpid.server.security; -import org.apache.qpid.server.plugins.Plugin; import org.apache.qpid.server.security.access.ObjectProperties; import org.apache.qpid.server.security.access.ObjectType; import org.apache.qpid.server.security.access.Operation; /** - * The two methods, {@link #access(ObjectType, Object)} and {@link #authorise(Operation, ObjectType, ObjectProperties)}, - * return the {@link Result} of the security decision, which may be to {@link Result#ABSTAIN} if no decision is made - * by this plugin. + * The two methods, {@link #access(ObjectType, Object)} and {@link #authorise(Operation, ObjectType, ObjectProperties)}, + * return the {@link Result} of the security decision, which may be to {@link Result#ABSTAIN} if no decision is made. */ -public interface SecurityPlugin extends Plugin -{ +public interface AccessControl +{ /** * Default result for {@link #access(ObjectType, Object)} or {@link #authorise(Operation, ObjectType, ObjectProperties)}. */ Result getDefault(); - + /** * Authorise access granted to an object instance. */ Result access(ObjectType objectType, Object instance); - + /** * Authorise an operation on an object defined by a set of properties. */ diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java b/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java index 8f3bdf7738..8243fc3f75 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java @@ -24,14 +24,14 @@ import javax.security.auth.Subject; import java.security.Principal; /** - * Represents the authorization of the logged on user. - * + * Represents the authorization of the logged on user. + * */ public interface AuthorizationHolder { - /** + /** * Returns the {@link Subject} of the authorized user. This is guaranteed to - * contain at least one {@link org.apache.qpid.server.security.auth.sasl.UsernamePrincipal}, representing the the identity + * contain at least one {@link org.apache.qpid.server.security.auth.UsernamePrincipal}, representing the the identity * used when the user logged on to the application, and zero or more {@link org.apache.qpid.server.security.auth.sasl.GroupPrincipal} * representing the group(s) to which the user belongs. * @@ -39,10 +39,10 @@ public interface AuthorizationHolder */ Subject getAuthorizedSubject(); - /** + /** * Returns the {@link Principal} representing the the identity * used when the user logged on to the application. - * + * * @return a Principal */ Principal getAuthorizedPrincipal(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java index 436660cfaf..1a1cce171b 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java @@ -18,22 +18,23 @@ */ package org.apache.qpid.server.security; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.Logger; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.plugins.PluginManager; + +import org.apache.qpid.server.plugin.AccessControlFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.security.access.ObjectProperties; +import org.apache.qpid.server.security.access.ObjectType; import org.apache.qpid.server.security.access.Operation; import static org.apache.qpid.server.security.access.ObjectType.EXCHANGE; +import static org.apache.qpid.server.security.access.ObjectType.GROUP; import static org.apache.qpid.server.security.access.ObjectType.METHOD; import static org.apache.qpid.server.security.access.ObjectType.QUEUE; +import static org.apache.qpid.server.security.access.ObjectType.USER; import static org.apache.qpid.server.security.access.ObjectType.VIRTUALHOST; import static org.apache.qpid.server.security.access.Operation.BIND; import static org.apache.qpid.server.security.access.Operation.CONSUME; @@ -45,103 +46,105 @@ import static org.apache.qpid.server.security.access.Operation.UNBIND; import javax.security.auth.Subject; import java.net.SocketAddress; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; /** - * The security manager contains references to all loaded {@link SecurityPlugin}s and delegates security decisions to them based + * The security manager contains references to all loaded {@link AccessControl}s and delegates security decisions to them based * on virtual host name. The plugins can be external <em>OSGi</em> .jar files that export the required classes or just internal * objects for simpler plugins. - * - * @see SecurityPlugin + * + * @see AccessControl */ public class SecurityManager { private static final Logger _logger = Logger.getLogger(SecurityManager.class); - + /** Container for the {@link java.security.Principal} that is using to this thread. */ private static final ThreadLocal<Subject> _subject = new ThreadLocal<Subject>(); - private static final ThreadLocal<Boolean> _accessChecksDisabled = new ThreadLocal<Boolean>() + + public static final ThreadLocal<Boolean> _accessChecksDisabled = new ClearingThreadLocal(false); + + private Map<String, AccessControl> _globalPlugins = new HashMap<String, AccessControl>(); + private Map<String, AccessControl> _hostPlugins = new HashMap<String, AccessControl>(); + + /** + * A special ThreadLocal, which calls remove() on itself whenever the value is + * the default, to avoid leaving a default value set after its use has passed. + */ + private static final class ClearingThreadLocal extends ThreadLocal<Boolean> { - protected Boolean initialValue() + private Boolean _defaultValue; + + public ClearingThreadLocal(Boolean defaultValue) { - return false; + super(); + _defaultValue = defaultValue; } - }; - private PluginManager _pluginManager; - private Map<String, SecurityPluginFactory> _pluginFactories = new HashMap<String, SecurityPluginFactory>(); - private Map<String, SecurityPlugin> _globalPlugins = new HashMap<String, SecurityPlugin>(); - private Map<String, SecurityPlugin> _hostPlugins = new HashMap<String, SecurityPlugin>(); + @Override + protected Boolean initialValue() + { + return _defaultValue; + } - public static class SecurityConfiguration extends ConfigurationPlugin - { - public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory() + @Override + public void set(Boolean value) { - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException + if (value == _defaultValue) { - ConfigurationPlugin instance = new SecurityConfiguration(); - instance.setConfiguration(path, config); - return instance; + super.remove(); } - - public List<String> getParentPaths() + else { - return Arrays.asList("security", "virtualhosts.virtualhost.security"); + super.set(value); } - }; - - @Override - public String[] getElementsProcessed() - { - return new String[]{"security"}; } - public void validateConfiguration() throws ConfigurationException + @Override + public Boolean get() { - if (getConfig().isEmpty()) + Boolean value = super.get(); + if (value == _defaultValue) { - throw new ConfigurationException("security section is incomplete, no elements found."); + super.remove(); } + return value; } } - - public SecurityManager(SecurityManager parent) throws ConfigurationException + /* + * Used by the VirtualHost to allow deferring to the broker level security plugins if required. + */ + public SecurityManager(SecurityManager parent, String aclFile) { - _pluginManager = parent._pluginManager; - _pluginFactories = parent._pluginFactories; - + this(aclFile); + // our global plugins are the parent's host plugins _globalPlugins = parent._hostPlugins; } - public SecurityManager(ConfigurationPlugin configuration, PluginManager manager) throws ConfigurationException + public SecurityManager(String aclFile) { - this(configuration, manager, null); - } - - public SecurityManager(ConfigurationPlugin configuration, PluginManager manager, SecurityPluginFactory plugin) throws ConfigurationException - { - _pluginManager = manager; - if (manager == null) // No plugin manager, no plugins + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put("aclFile", aclFile); + for (AccessControlFactory provider : (new QpidServiceLoader<AccessControlFactory>()).instancesOf(AccessControlFactory.class)) { - return; + AccessControl accessControl = provider.createInstance(attributes); + if(accessControl != null) + { + addHostPlugin(accessControl); + } } - _pluginFactories = _pluginManager.getSecurityPlugins(); - if (plugin != null) + if(_logger.isDebugEnabled()) { - _pluginFactories.put(plugin.getPluginName(), plugin); + _logger.debug("Configured " + _hostPlugins.size() + " access control plugins"); } - - configureHostPlugins(configuration); } public static Subject getThreadSubject() @@ -154,41 +157,6 @@ public class SecurityManager _subject.set(subject); } - public void configureHostPlugins(ConfigurationPlugin hostConfig) throws ConfigurationException - { - _hostPlugins = configurePlugins(hostConfig); - } - - public void configureGlobalPlugins(ConfigurationPlugin configuration) throws ConfigurationException - { - _globalPlugins = configurePlugins(configuration); - } - - public Map<String, SecurityPlugin> configurePlugins(ConfigurationPlugin hostConfig) throws ConfigurationException - { - Map<String, SecurityPlugin> plugins = new HashMap<String, SecurityPlugin>(); - SecurityConfiguration securityConfig = hostConfig.getConfiguration(SecurityConfiguration.class.getName()); - - // If we have no security Configuration then there is nothing to configure. - if (securityConfig != null) - { - for (SecurityPluginFactory<?> factory : _pluginFactories.values()) - { - SecurityPlugin plugin = factory.newInstance(securityConfig); - if (plugin != null) - { - plugins.put(factory.getPluginName(), plugin); - } - } - } - return plugins; - } - - public void addHostPlugin(SecurityPlugin plugin) - { - _hostPlugins.put(plugin.getClass().getName(), plugin); - } - public static Logger getLogger() { return _logger; @@ -205,7 +173,7 @@ public class SecurityManager private abstract class AccessCheck { - abstract Result allowed(SecurityPlugin plugin); + abstract Result allowed(AccessControl plugin); } private boolean checkAllPlugins(AccessCheck checker) @@ -215,16 +183,16 @@ public class SecurityManager return true; } - Map<String, SecurityPlugin> remainingPlugins = _globalPlugins.isEmpty() - ? Collections.<String, SecurityPlugin>emptyMap() - : _hostPlugins.isEmpty() ? _globalPlugins : new HashMap<String, SecurityPlugin>(_globalPlugins); - - if(!_hostPlugins.isEmpty()) + Map<String, AccessControl> remainingPlugins = _globalPlugins.isEmpty() + ? Collections.<String, AccessControl>emptyMap() + : _hostPlugins.isEmpty() ? _globalPlugins : new HashMap<String, AccessControl>(_globalPlugins); + + if(!_hostPlugins.isEmpty()) { - for (Entry<String, SecurityPlugin> hostEntry : _hostPlugins.entrySet()) + for (Entry<String, AccessControl> hostEntry : _hostPlugins.entrySet()) { // Create set of global only plugins - SecurityPlugin globalPlugin = remainingPlugins.get(hostEntry.getKey()); + AccessControl globalPlugin = remainingPlugins.get(hostEntry.getKey()); if (globalPlugin != null) { remainingPlugins.remove(hostEntry.getKey()); @@ -272,7 +240,7 @@ public class SecurityManager } } - for (SecurityPlugin plugin : remainingPlugins.values()) + for (AccessControl plugin : remainingPlugins.values()) { Result remaining = checker.allowed(plugin); if (remaining == Result.DEFER) @@ -284,16 +252,16 @@ public class SecurityManager return false; } } - + // getting here means either allowed or abstained from all plugins return true; } - + public boolean authoriseBind(final Exchange exch, final AMQQueue queue, final AMQShortString routingKey) { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(BIND, EXCHANGE, new ObjectProperties(exch, queue, routingKey)); } @@ -304,7 +272,7 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { ObjectProperties properties = new ObjectProperties(); properties.setName(methodName); @@ -318,11 +286,22 @@ public class SecurityManager }); } + public boolean accessManagement() + { + return checkAllPlugins(new AccessCheck() + { + Result allowed(AccessControl plugin) + { + return plugin.access(ObjectType.MANAGEMENT, null); + } + }); + } + public boolean accessVirtualhost(final String vhostname, final SocketAddress remoteAddress) { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.access(VIRTUALHOST, remoteAddress); } @@ -333,7 +312,7 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(CONSUME, QUEUE, new ObjectProperties(queue)); } @@ -345,7 +324,7 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(CREATE, EXCHANGE, new ObjectProperties(autoDelete, durable, exchangeName, internal, nowait, passive, exchangeType)); @@ -358,7 +337,7 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(CREATE, QUEUE, new ObjectProperties(autoDelete, durable, exclusive, nowait, passive, queueName, owner)); } @@ -369,7 +348,7 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(DELETE, QUEUE, new ObjectProperties(queue)); } @@ -380,13 +359,34 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(DELETE, EXCHANGE, new ObjectProperties(exchange.getName())); } }); } + public boolean authoriseGroupOperation(final Operation operation, final String groupName) + { + return checkAllPlugins(new AccessCheck() + { + Result allowed(AccessControl plugin) + { + return plugin.authorise(operation, GROUP, new ObjectProperties(groupName)); + } + }); + } + + public boolean authoriseUserOperation(final Operation operation, final String userName) + { + return checkAllPlugins(new AccessCheck() + { + Result allowed(AccessControl plugin) + { + return plugin.authorise(operation, USER, new ObjectProperties(userName)); + } + }); + } private ConcurrentHashMap<String, ConcurrentHashMap<String, PublishAccessCheck>> _immediatePublishPropsCache = new ConcurrentHashMap<String, ConcurrentHashMap<String, PublishAccessCheck>>(); @@ -428,7 +428,7 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(PURGE, QUEUE, new ObjectProperties(queue)); } @@ -439,7 +439,7 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(UNBIND, EXCHANGE, new ObjectProperties(exch, queue, routingKey)); } @@ -465,9 +465,16 @@ public class SecurityManager _props = props; } - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(PUBLISH, EXCHANGE, _props); } } + + + public void addHostPlugin(AccessControl plugin) + { + _hostPlugins.put(plugin.getClass().getName(), plugin); + } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java deleted file mode 100644 index 21c2d1cda5..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * 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.security; - -import org.apache.log4j.Logger; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; - -/** - * An OSGi {@link BundleActivator} that loads a {@link SecurityPluginFactory}. - */ -public abstract class SecurityPluginActivator implements BundleActivator -{ - private static final Logger _logger = Logger.getLogger(SecurityPluginActivator.class); - - private SecurityPluginFactory _factory; - private ConfigurationPluginFactory _config; - private BundleContext _ctx; - private String _bundleName; - - /** Implement this to return the factory this plugin activates. */ - public abstract SecurityPluginFactory getFactory(); - - /** Implement this to return the factory this plugin activates. */ - public abstract ConfigurationPluginFactory getConfigurationFactory(); - - /** - * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) - */ - public void start(BundleContext ctx) throws Exception - { - _ctx = ctx; - _factory = getFactory(); - _config = getConfigurationFactory(); - _bundleName = ctx.getBundle().getSymbolicName(); - - // register the service - _logger.info("Registering security plugin: " + _bundleName); - _ctx.registerService(SecurityPluginFactory.class.getName(), _factory, null); - _ctx.registerService(ConfigurationPluginFactory.class.getName(), _config, null); - } - - /** - * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) - */ - public void stop(BundleContext context) throws Exception - { - _logger.info("Stopping security plugin: " + _bundleName); - - // null object references - _factory = null; - _config = null; - _ctx = null; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginFactory.java deleted file mode 100644 index fe81cba282..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginFactory.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * - * 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.security; - -import org.apache.qpid.server.plugins.PluginFactory; - -/** - * The factory that generates instances of security plugins. Usually implemented as a static member class in the plugin itself. - */ -public interface SecurityPluginFactory<S extends SecurityPlugin> extends PluginFactory<S> -{ -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java b/java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java new file mode 100644 index 0000000000..8138745486 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java @@ -0,0 +1,137 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security; + +import java.security.Principal; + +import javax.security.auth.Subject; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; + +import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; +import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; +import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.group.GroupPrincipalAccessor; + +/** + * Creates a {@link Subject} formed by the {@link Principal}'s returned from: + * <ol> + * <li>Authenticating using an {@link AuthenticationManager}</li> + * <li>A {@link GroupPrincipalAccessor}</li> + * </ol> + * + * <p> + * SubjectCreator is a facade to the {@link AuthenticationManager}, and is intended to be + * the single place that {@link Subject}'s are created in the broker. + * </p> + */ +public class SubjectCreator +{ + private AuthenticationManager _authenticationManager; + private GroupPrincipalAccessor _groupAccessor; + + public SubjectCreator(AuthenticationManager authenticationManager, GroupPrincipalAccessor groupAccessor) + { + _authenticationManager = authenticationManager; + _groupAccessor = groupAccessor; + } + + /** + * Gets the known SASL mechanisms + * + * @return SASL mechanism names, space separated. + */ + public String getMechanisms() + { + return _authenticationManager.getMechanisms(); + } + + /** + * @see AuthenticationManager#createSaslServer(String, String, Principal) + */ + public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException + { + return _authenticationManager.createSaslServer(mechanism, localFQDN, externalPrincipal); + } + + /** + * Authenticates a user using SASL negotiation. + * + * @param server SASL server + * @param response SASL response to process + */ + public SubjectAuthenticationResult authenticate(SaslServer server, byte[] response) + { + AuthenticationResult authenticationResult = _authenticationManager.authenticate(server, response); + if(server.isComplete()) + { + String username = server.getAuthorizationID(); + + return createResultWithGroups(username, authenticationResult); + } + else + { + return new SubjectAuthenticationResult(authenticationResult); + } + } + + /** + * Authenticates a user using their username and password. + */ + public SubjectAuthenticationResult authenticate(String username, String password) + { + final AuthenticationResult authenticationResult = _authenticationManager.authenticate(username, password); + + return createResultWithGroups(username, authenticationResult); + } + + private SubjectAuthenticationResult createResultWithGroups(String username, final AuthenticationResult authenticationResult) + { + if(authenticationResult.getStatus() == AuthenticationStatus.SUCCESS) + { + final Subject authenticationSubject = new Subject(); + + authenticationSubject.getPrincipals().addAll(authenticationResult.getPrincipals()); + authenticationSubject.getPrincipals().addAll(_groupAccessor.getGroupPrincipals(username)); + + authenticationSubject.setReadOnly(); + + return new SubjectAuthenticationResult(authenticationResult, authenticationSubject); + } + else + { + return new SubjectAuthenticationResult(authenticationResult); + } + } + + public Subject createSubjectWithGroups(String username) + { + Subject authenticationSubject = new Subject(); + + authenticationSubject.getPrincipals().add(new AuthenticatedPrincipal(username)); + authenticationSubject.getPrincipals().addAll(_groupAccessor.getGroupPrincipals(username)); + authenticationSubject.setReadOnly(); + + return authenticationSubject; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java index a9ec4d1647..8e38681e68 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java @@ -18,33 +18,31 @@ */ package org.apache.qpid.server.security.access; -import org.apache.commons.lang.StringUtils; - -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.queue.AMQQueue; - import java.util.ArrayList; import java.util.EnumMap; +import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.queue.AMQQueue; + /** * An set of properties for an access control v2 rule {@link ObjectType}. - * + * * The {@link #matches(ObjectProperties)} method is intended to be used when determining precedence of rules, and * {@link #equals(Object)} and {@link #hashCode()} are intended for use in maps. This is due to the wildcard matching * described above. */ public class ObjectProperties { - /** serialVersionUID */ - private static final long serialVersionUID = -1356019341374170495L; - public static final String STAR= "*"; public static final ObjectProperties EMPTY = new ObjectProperties(); - + public enum Property { ROUTING_KEY, @@ -65,81 +63,89 @@ public class ObjectProperties AUTO_DELETE, COMPONENT, PACKAGE, - CLASS; - - public static Property parse(String text) + CLASS, + FROM_NETWORK, + FROM_HOSTNAME; + + private static final Map<String, Property> _canonicalNameToPropertyMap = new HashMap<String, ObjectProperties.Property>(); + + static { for (Property property : values()) { - if (property.getName().equalsIgnoreCase(text)) - { - return property; - } + _canonicalNameToPropertyMap.put(getCanonicalName(property.name()), property); + } + } + + /** + * Properties are parsed using their canonical name (see {@link #getCanonicalName(String)}) + * so that, for the sake of user-friendliness, the ACL file parses is insensitive to + * case and underscores. + */ + public static Property parse(String text) + { + String propertyName = getCanonicalName(text); + Property property = _canonicalNameToPropertyMap.get(propertyName); + + if(property == null) + { + throw new IllegalArgumentException("Not a valid property: " + text + + " because " + propertyName + + " is not in " + _canonicalNameToPropertyMap.keySet()); + } + else + { + return property; } - throw new IllegalArgumentException("Not a valid property: " + text); } - - public String getName() + + private static String getCanonicalName(String name) { - return StringUtils.remove(name(), '_').toLowerCase(); + return StringUtils.remove(name, '_').toLowerCase(); } - - public static List<String> getPropertyNames() - { - List<String> properties = new ArrayList<String>(); - for (Property property : values()) - { - properties.add(property.getName()); - } - return properties; - } } private final EnumMap<Property, String> _properties = new EnumMap<Property, String>(Property.class); - public static List<String> getAllPropertyNames() + public static List<String> getAllPropertyNames() { - List<String> properties = new ArrayList<String>(); - for (Property property : Property.values()) - { - properties.add(StringUtils.remove(property.name(), '_').toLowerCase()); - } - return properties; - } - + List<String> properties = new ArrayList<String>(); + for (Property property : Property.values()) + { + properties.add(StringUtils.remove(property.name(), '_').toLowerCase()); + } + return properties; + } + public ObjectProperties() { - super(); } - + + public ObjectProperties(Property property, String value) + { + _properties.put(property, value); + } + public ObjectProperties(ObjectProperties copy) { - super(); - _properties.putAll(copy._properties); } - + public ObjectProperties(String name) { - super(); - setName(name); } - + public ObjectProperties(AMQShortString name) { - super(); - setName(name); } - + public ObjectProperties(AMQQueue queue) { - super(); - setName(queue.getName()); - + put(Property.AUTO_DELETE, queue.isAutoDelete()); put(Property.TEMPORARY, queue.isAutoDelete()); put(Property.DURABLE, queue.isDurable()); @@ -157,45 +163,45 @@ public class ObjectProperties put(Property.OWNER, queue.getAuthorizationHolder().getAuthorizedPrincipal().getName()); } } - + public ObjectProperties(Exchange exch, AMQQueue queue, AMQShortString routingKey) { this(queue); - - setName(exch.getName()); - + + setName(exch.getName()); + put(Property.QUEUE_NAME, queue.getName()); put(Property.ROUTING_KEY, routingKey); } - + public ObjectProperties(Exchange exch, AMQShortString routingKey) { this(exch.getName(), routingKey.asString()); } - + public ObjectProperties(String exchangeName, String routingKey, Boolean immediate) { this(exchangeName, routingKey); - + put(Property.IMMEDIATE, immediate); } - + public ObjectProperties(String exchangeName, String routingKey) { super(); - + setName(exchangeName); - + put(Property.ROUTING_KEY, routingKey); } - + public ObjectProperties(Boolean autoDelete, Boolean durable, AMQShortString exchangeName, Boolean internal, Boolean nowait, Boolean passive, AMQShortString exchangeType) { super(); - + setName(exchangeName); - + put(Property.AUTO_DELETE, autoDelete); put(Property.TEMPORARY, autoDelete); put(Property.DURABLE, durable); @@ -204,14 +210,14 @@ public class ObjectProperties put(Property.PASSIVE, passive); put(Property.TYPE, exchangeType); } - + public ObjectProperties(Boolean autoDelete, Boolean durable, Boolean exclusive, Boolean nowait, Boolean passive, AMQShortString queueName, String owner) { super(); - + setName(queueName); - + put(Property.AUTO_DELETE, autoDelete); put(Property.TEMPORARY, autoDelete); put(Property.DURABLE, durable); @@ -220,7 +226,7 @@ public class ObjectProperties put(Property.PASSIVE, passive); put(Property.OWNER, owner); } - + public ObjectProperties(Boolean exclusive, Boolean noAck, Boolean noLocal, Boolean nowait, AMQQueue queue) { this(queue); @@ -230,17 +236,7 @@ public class ObjectProperties put(Property.EXCLUSIVE, exclusive); put(Property.NO_WAIT, nowait); } - - public List<String> getPropertyNames() - { - List<String> properties = new ArrayList<String>(); - for (Property property : _properties.keySet()) - { - properties.add(property.getName()); - } - return properties; - } - + public Boolean isSet(Property key) { return _properties.containsKey(key) && Boolean.valueOf(_properties.get(key)); @@ -255,17 +251,17 @@ public class ObjectProperties { return _properties.get(Property.NAME); } - + public void setName(String name) { _properties.put(Property.NAME, name); } - + public void setName(AMQShortString name) { put(Property.NAME, name); } - + public String put(Property key, AMQShortString value) { return put(key, value == null ? "" : value.asString()); @@ -275,7 +271,7 @@ public class ObjectProperties { return _properties.put(key, value == null ? "" : value.trim()); } - + public void put(Property key, Boolean value) { if (value != null) @@ -283,66 +279,64 @@ public class ObjectProperties _properties.put(key, Boolean.toString(value)); } } - + public boolean matches(ObjectProperties properties) { if (properties._properties.keySet().isEmpty()) { return true; } - + if (!_properties.keySet().containsAll(properties._properties.keySet())) { return false; } - + for (Map.Entry<Property,String> entry : properties._properties.entrySet()) { Property key = entry.getKey(); String ruleValue = entry.getValue(); - + String thisValue = _properties.get(key); - if (!valueMatches(thisValue, ruleValue)) + if (!valueMatches(thisValue, ruleValue)) { return false; } } - + return true; } - + private boolean valueMatches(String thisValue, String ruleValue) { return (StringUtils.isEmpty(ruleValue) || StringUtils.equals(thisValue, ruleValue)) || ruleValue.equals(STAR) - || (ruleValue.endsWith(STAR) + || (ruleValue.endsWith(STAR) && thisValue != null && thisValue.length() >= ruleValue.length() - 1 && thisValue.startsWith(ruleValue.substring(0, ruleValue.length() - 1))); } @Override - public boolean equals(Object o) + public boolean equals(Object obj) { - if (this == o) + if (obj == null) { - return true; + return false; } - if (o == null || getClass() != o.getClass()) + if (obj == this) { - return false; + return true; } - - ObjectProperties that = (ObjectProperties) o; - - if (_properties != null ? !_properties.equals(that._properties) : that._properties != null) + if (obj.getClass() != getClass()) { return false; } - - return true; + ObjectProperties rhs = (ObjectProperties) obj; + return new EqualsBuilder() + .append(_properties, rhs._properties).isEquals(); } @Override diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java index 90ecd1dd17..8bc4b9d278 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java @@ -41,12 +41,15 @@ public enum ObjectType { ALL(Operation.ALL), VIRTUALHOST(Operation.ALL, ACCESS), + MANAGEMENT(Operation.ALL, ACCESS), QUEUE(Operation.ALL, CREATE, DELETE, PURGE, CONSUME), EXCHANGE(Operation.ALL, ACCESS, CREATE, DELETE, BIND, UNBIND, PUBLISH), LINK, // Not allowed in the Java broker ROUTE, // Not allowed in the Java broker - METHOD(Operation.ALL, ACCESS, UPDATE); - + METHOD(Operation.ALL, ACCESS, UPDATE), + USER(Operation.ALL, CREATE, DELETE, UPDATE), + GROUP(Operation.ALL, CREATE, DELETE, UPDATE); + private EnumSet<Operation> _actions; private ObjectType() diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java deleted file mode 100644 index 4df135a4ca..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * 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.security.access.plugins; - -import org.apache.qpid.server.security.AbstractPlugin; -import org.apache.qpid.server.security.Result; -import org.apache.qpid.server.security.access.ObjectProperties; -import org.apache.qpid.server.security.access.ObjectType; -import org.apache.qpid.server.security.access.Operation; - -/** - * This {@link org.apache.qpid.server.security.SecurityPlugin} simply abstains from all authorisation requests and ignores configuration. - */ -public abstract class BasicPlugin extends AbstractPlugin -{ - public Result access(ObjectType objectType, Object instance) - { - return getDefault(); - } - - public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties) - { - return getDefault(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java deleted file mode 100644 index 4b7a2fb457..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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.security.access.plugins; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; -import org.apache.qpid.server.security.SecurityPluginFactory; - -import java.util.Arrays; -import java.util.List; - -/** - * The <code>LegacyAccess</code> plugin is used internally and simply ignores legacy elements of the configuration file. - */ -public class LegacyAccess extends BasicPlugin -{ - public static class LegacyAccessConfiguration extends ConfigurationPlugin { - public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.msg-auth", "virtualhosts.virtualhost.security.msg-auth"); - } - - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException - { - ConfigurationPlugin instance = new LegacyAccessConfiguration(); - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[] { "" }; - } - } - - public static final SecurityPluginFactory<LegacyAccess> FACTORY = new SecurityPluginFactory<LegacyAccess>() - { - public LegacyAccess newInstance(ConfigurationPlugin config) throws ConfigurationException - { - LegacyAccessConfiguration configuration = config.getConfiguration(LegacyAccessConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - return null; - } - - LegacyAccess plugin = new LegacyAccess(); - plugin.configure(configuration); - return plugin; - } - - public String getPluginName() - { - return LegacyAccess.class.getName(); - } - - public Class<LegacyAccess> getPluginClass() - { - return LegacyAccess.class; - } - }; - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java new file mode 100644 index 0000000000..fb31132514 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.security.auth; + +import java.io.Serializable; +import java.security.Principal; +import java.util.Set; + +import javax.security.auth.Subject; + +import org.apache.qpid.server.security.auth.UsernamePrincipal; + +/** + * A simple Principal wrapper. Exists to allow us to identify the "primary" principal + * by calling {@link Subject#getPrincipals(Class)}, passing in {@link AuthenticatedPrincipal}.class, + * e.g. when logging. + */ +public final class AuthenticatedPrincipal implements Principal, Serializable +{ + private final Principal _wrappedPrincipal; + + /** convenience constructor for the common case where we're wrapping a {@link UsernamePrincipal} */ + public AuthenticatedPrincipal(String userPrincipalName) + { + this(new UsernamePrincipal(userPrincipalName)); + } + + public AuthenticatedPrincipal(Principal wrappedPrincipal) + { + if(wrappedPrincipal == null) + { + throw new IllegalArgumentException("Wrapped principal is null"); + } + + _wrappedPrincipal = wrappedPrincipal; + } + + @Override + public String getName() + { + return _wrappedPrincipal.getName(); + } + + @Override + public int hashCode() + { + return _wrappedPrincipal.hashCode(); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + + if (!(obj instanceof AuthenticatedPrincipal)) + { + return false; + } + + AuthenticatedPrincipal other = (AuthenticatedPrincipal) obj; + + return _wrappedPrincipal.equals(other._wrappedPrincipal); + } + + public static AuthenticatedPrincipal getOptionalAuthenticatedPrincipalFromSubject(final Subject authSubject) + { + return getAuthenticatedPrincipalFromSubject(authSubject, true); + } + + public static AuthenticatedPrincipal getAuthenticatedPrincipalFromSubject(final Subject authSubject) + { + return getAuthenticatedPrincipalFromSubject(authSubject, false); + } + + private static AuthenticatedPrincipal getAuthenticatedPrincipalFromSubject(final Subject authSubject, boolean isPrincipalOptional) + { + if (authSubject == null) + { + throw new IllegalArgumentException("No authenticated subject."); + } + + final Set<AuthenticatedPrincipal> principals = authSubject.getPrincipals(AuthenticatedPrincipal.class); + int numberOfAuthenticatedPrincipals = principals.size(); + + if(numberOfAuthenticatedPrincipals == 0 && isPrincipalOptional) + { + return null; + } + else + { + if (numberOfAuthenticatedPrincipals != 1) + { + throw new IllegalArgumentException( + "Can't find single AuthenticatedPrincipal in authenticated subject. There were " + + numberOfAuthenticatedPrincipals + + " authenticated principals out of a total number of principals of: " + authSubject.getPrincipals()); + } + return principals.iterator().next(); + } + } + + @Override + public String toString() + { + return getName(); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java index 949c0f2b89..09bf6cf3b1 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java @@ -7,9 +7,9 @@ * 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 @@ -20,15 +20,20 @@ */ package org.apache.qpid.server.security.auth; -import javax.security.auth.Subject; +import java.security.Principal; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; /** - * Encapsulates the result of an attempt to authenticate. + * Encapsulates the result of an attempt to authenticate using an {@link AuthenticationManager}. * <p> * The authentication status describes the overall outcome. * <p> * <ol> - * <li>If authentication status is SUCCESS, the subject will be populated. + * <li>If authentication status is SUCCESS, at least one {@link Principal} will be populated. * </li> * <li>If authentication status is CONTINUE, the authentication has failed because the user * supplied incorrect credentials (etc). If the authentication requires it, the next challenge @@ -40,6 +45,8 @@ import javax.security.auth.Subject; * </li> * </ol> * + * The main principal provided to the constructor is wrapped in an {@link AuthenticatedPrincipal} + * to make it easier for the rest of the application to identify it among the set of other principals. */ public class AuthenticationResult { @@ -56,37 +63,59 @@ public class AuthenticationResult private final AuthenticationStatus _status; private final byte[] _challenge; private final Exception _cause; - private final Subject _subject; + private final Set<Principal> _principals = new HashSet<Principal>(); + private final Principal _mainPrincipal; public AuthenticationResult(final AuthenticationStatus status) { this(null, status, null); } + public AuthenticationResult(Principal mainPrincipal) + { + this(mainPrincipal, Collections.<Principal>emptySet()); + } + + public AuthenticationResult(Principal mainPrincipal, Set<Principal> otherPrincipals) + { + AuthenticatedPrincipal specialQpidAuthenticatedPrincipal = new AuthenticatedPrincipal(mainPrincipal); + _principals.addAll(otherPrincipals); + _principals.remove(mainPrincipal); + _principals.add(specialQpidAuthenticatedPrincipal); + _mainPrincipal = mainPrincipal; + + _status = AuthenticationStatus.SUCCESS; + _challenge = null; + _cause = null; + } + public AuthenticationResult(final byte[] challenge, final AuthenticationStatus status) { - this(challenge, status, null); + _challenge = challenge; + _status = status; + _cause = null; + _mainPrincipal = null; } public AuthenticationResult(final AuthenticationStatus error, final Exception cause) { - this(null, error, cause); + _status = error; + _challenge = null; + _cause = cause; + _mainPrincipal = null; } public AuthenticationResult(final byte[] challenge, final AuthenticationStatus status, final Exception cause) { - this._status = status; - this._challenge = challenge; - this._cause = cause; - this._subject = null; - } + if(status == AuthenticationStatus.SUCCESS) + { + throw new IllegalArgumentException("Successful authentication requires at least one principal"); + } - public AuthenticationResult(final Subject subject) - { - this._status = AuthenticationStatus.SUCCESS; - this._challenge = null; - this._cause = null; - this._subject = subject; + _status = status; + _challenge = challenge; + _cause = cause; + _mainPrincipal = null; } public Exception getCause() @@ -104,9 +133,13 @@ public class AuthenticationResult return _challenge; } - public Subject getSubject() + public Set<Principal> getPrincipals() { - return _subject; + return _principals; } + public Principal getMainPrincipal() + { + return _mainPrincipal; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/SubjectAuthenticationResult.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/SubjectAuthenticationResult.java new file mode 100644 index 0000000000..3be96b87eb --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/SubjectAuthenticationResult.java @@ -0,0 +1,76 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth; + +import java.security.Principal; + +import javax.security.auth.Subject; + +import org.apache.qpid.server.security.SubjectCreator; + +/** + * Encapsulates the result of an attempt to authenticate using a {@link SubjectCreator}. + * + * <p> + * iff authentication was successful, {@link #getSubject()} will return a non-null value and + * {@link #getStatus()} will return {@link AuthenticationResult.AuthenticationStatus#SUCCESS}. + * + * In this case, the {@link Subject} will contain the user {@link Principal} and zero or more other principals + * representing groups. + * </p> + * @see SubjectCreator + */ +public class SubjectAuthenticationResult +{ + private final AuthenticationResult _authenticationResult; + private final Subject _subject; + + public SubjectAuthenticationResult(AuthenticationResult authenticationResult, Subject subject) + { + _authenticationResult = authenticationResult; + _subject = subject; + } + + public SubjectAuthenticationResult(AuthenticationResult unsuccessfulAuthenticationResult) + { + this(unsuccessfulAuthenticationResult, null); + } + + public Exception getCause() + { + return _authenticationResult.getCause(); + } + + public AuthenticationResult.AuthenticationStatus getStatus() + { + return _authenticationResult.getStatus(); + } + + public byte[] getChallenge() + { + return _authenticationResult.getChallenge(); + } + + public Subject getSubject() + { + return _subject; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java index 9e7db94216..5b3c1d59cf 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java @@ -7,9 +7,9 @@ * 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 @@ -18,14 +18,13 @@ * under the License. * */ -package org.apache.qpid.server.security.auth.sasl; +package org.apache.qpid.server.security.auth; -import javax.security.auth.Subject; +import java.io.Serializable; import java.security.Principal; -import java.util.Set; /** A principal that is just a wrapper for a simple username. */ -public class UsernamePrincipal implements Principal +public class UsernamePrincipal implements Principal, Serializable { private final String _name; @@ -48,9 +47,6 @@ public class UsernamePrincipal implements Principal return _name; } - /** - * @see java.lang.Object#hashCode() - */ @Override public int hashCode() { @@ -58,9 +54,6 @@ public class UsernamePrincipal implements Principal return prime * _name.hashCode(); } - /** - * @see java.lang.Object#equals(java.lang.Object) - */ @Override public boolean equals(Object obj) { @@ -81,19 +74,4 @@ public class UsernamePrincipal implements Principal } } } - - public static UsernamePrincipal getUsernamePrincipalFromSubject(final Subject authSubject) - { - if (authSubject == null) - { - throw new IllegalArgumentException("No authenticated subject."); - } - - final Set<UsernamePrincipal> principals = authSubject.getPrincipals(UsernamePrincipal.class); - if (principals.size() != 1) - { - throw new IllegalArgumentException("Can't find single UsernamePrincipal in authenticated subject"); - } - return principals.iterator().next(); - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java index cac60a5283..578bb96efa 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java @@ -21,9 +21,9 @@ package org.apache.qpid.server.security.auth.database; import org.apache.log4j.Logger; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser; import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.login.AccountNotFoundException; diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java index 67f4b7344a..605d2d019d 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java @@ -32,6 +32,8 @@ import java.util.Map; /** Represents a "user database" which is really a way of storing principals (i.e. usernames) and passwords. */ public interface PrincipalDatabase { + void setPasswordFile(String passwordFile) throws IOException; + /** * Set the password for a given principal in the specified callback. This is used for certain SASL providers. The * user database implementation should look up the password in any way it chooses and set it in the callback by diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java new file mode 100644 index 0000000000..ff21d63c87 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth.manager; + +import java.io.IOException; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; +import org.apache.qpid.server.security.auth.database.PrincipalDatabase; + +/** + * Factory for {@link PrincipalDatabaseAuthenticationManager} objects configured + * with either the Plain or Base64MD5 digest {@link PrincipalDatabase} + * implementation. + */ +public abstract class AbstractPrincipalDatabaseAuthManagerFactory implements AuthenticationManagerFactory +{ + public static final String ATTRIBUTE_PATH = "path"; + + private static final Logger LOGGER = Logger.getLogger(AbstractPrincipalDatabaseAuthManagerFactory.class); + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes == null || !getType().equals(attributes.get(ATTRIBUTE_TYPE))) + { + return null; + } + + String passwordFile = (String) attributes.get(ATTRIBUTE_PATH); + if (passwordFile == null) + { + LOGGER.warn("Password file path must not be null"); + return null; + } + + PrincipalDatabase principalDatabase = createPrincipalDatabase(); + try + { + principalDatabase.setPasswordFile(passwordFile); + } + catch (IOException e) + { + throw new RuntimeException(e.getMessage(), e); + } + + return new PrincipalDatabaseAuthenticationManager(principalDatabase); + } + + abstract String getType(); + + abstract PrincipalDatabase createPrincipalDatabase(); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java index 5676c43754..dd4c2e717a 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java @@ -21,31 +21,25 @@ package org.apache.qpid.server.security.auth.manager; import java.security.Principal; -import java.util.Arrays; -import java.util.List; + import javax.security.auth.Subject; -import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; + import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.sasl.anonymous.AnonymousInitialiser; import org.apache.qpid.server.security.auth.sasl.anonymous.AnonymousSaslServer; public class AnonymousAuthenticationManager implements AuthenticationManager { - private static final Logger _logger = Logger.getLogger(AnonymousAuthenticationManager.class); - private static final AnonymousInitialiser SASL_INITIALISER = new AnonymousInitialiser(); private static final String ANONYMOUS = SASL_INITIALISER.getMechanismName(); - private static final Principal ANONYMOUS_PRINCIPAL = new UsernamePrincipal("ANONYMOUS"); + public static final String ANONYMOUS_USERNAME = "ANONYMOUS"; + + public static final Principal ANONYMOUS_PRINCIPAL = new UsernamePrincipal(ANONYMOUS_USERNAME); public static final Subject ANONYMOUS_SUBJECT = new Subject(); static @@ -53,76 +47,11 @@ public class AnonymousAuthenticationManager implements AuthenticationManager ANONYMOUS_SUBJECT.getPrincipals().add(ANONYMOUS_PRINCIPAL); } - private static final AuthenticationResult ANONYMOUS_AUTHENTICATION = new AuthenticationResult(ANONYMOUS_SUBJECT); - - - private static CallbackHandler _callbackHandler = SASL_INITIALISER.getCallbackHandler(); + private static final AuthenticationResult ANONYMOUS_AUTHENTICATION = new AuthenticationResult(ANONYMOUS_PRINCIPAL); static final AnonymousAuthenticationManager INSTANCE = new AnonymousAuthenticationManager(); - public static class AnonymousAuthenticationManagerConfiguration extends ConfigurationPlugin - { - - public static final ConfigurationPluginFactory FACTORY = - new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.anonymous-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new AnonymousAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[0]; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - } - - - public static final AuthenticationManagerPluginFactory<AnonymousAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<AnonymousAuthenticationManager>() - { - public AnonymousAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - AnonymousAuthenticationManagerConfiguration configuration = - config == null - ? null - : (AnonymousAuthenticationManagerConfiguration) config.getConfiguration(AnonymousAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for AnonymousAuthenticationManager"); - return null; - } - return INSTANCE; - } - - public Class<AnonymousAuthenticationManager> getPluginClass() - { - return AnonymousAuthenticationManager.class; - } - - public String getPluginName() - { - return AnonymousAuthenticationManager.class.getName(); - } - }; - - - private AnonymousAuthenticationManager() + AnonymousAuthenticationManager() { } @@ -184,9 +113,4 @@ public class AnonymousAuthenticationManager implements AuthenticationManager public void close() { } - - @Override - public void configure(ConfigurationPlugin config) throws ConfigurationException - { - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java new file mode 100644 index 0000000000..1b1995500c --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth.manager; + +import java.util.Map; + +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; + +public class AnonymousAuthenticationManagerFactory implements AuthenticationManagerFactory +{ + public static final String PROVIDER_TYPE = AnonymousAuthenticationManager.class.getSimpleName(); + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE))) + { + return new AnonymousAuthenticationManager(); + } + return null; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java index ccddcb7669..c1a694f148 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java @@ -24,22 +24,22 @@ import java.security.Principal; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import org.apache.qpid.common.Closeable; -import org.apache.qpid.server.plugins.Plugin; import org.apache.qpid.server.security.auth.AuthenticationResult; /** * Implementations of the AuthenticationManager are responsible for determining * the authenticity of a user's credentials. - * - * If the authentication is successful, the manager is responsible for producing a populated - * {@link javax.security.auth.Subject} containing the user's identity and zero or more principals representing - * groups to which the user belongs. + * <p> + * If the authentication is successful, the manager is responsible for producing an + * {@link AuthenticationResult} containing the user's main {@link Principal} and zero or + * more other implementation-specific principals. + * </p> * <p> * The {@link #initialise()} method is responsible for registering SASL mechanisms required by * the manager. The {@link #close()} method must reverse this registration. - * + * </p> */ -public interface AuthenticationManager extends Closeable, Plugin +public interface AuthenticationManager extends Closeable { /** The name for the required SASL Server mechanisms */ public static final String PROVIDER_NAME= "AMQSASLProvider-Server"; @@ -88,5 +88,4 @@ public interface AuthenticationManager extends Closeable, Plugin * @return authentication result */ AuthenticationResult authenticate(String username, String password); - } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java deleted file mode 100644 index 89a4d8ae66..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * 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.security.auth.manager; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.commons.configuration.ConfigurationException; -import org.apache.qpid.common.Closeable; -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.plugins.Plugin; -import org.apache.qpid.server.plugins.PluginManager; -import org.apache.qpid.server.security.SecurityManager.SecurityConfiguration; - -/** - * A concrete implementation of {@link IAuthenticationManagerRegistry} that registers all {@link AuthenticationManager} - * instances defined in the configuration, building an optional mapping between port number and AuthenticationManager. - * - * <p>The default AuthenticationManager is either the one nominated as default within the configuration with - * {@link ServerConfiguration#getDefaultAuthenticationManager()}, or if there is only one, it is implicitly - * the default.</p> - * - * <p>It is important to {@link #close()} the registry after use and this allows the AuthenticationManagers - * to reverse any security registrations they have performed.</p> - */ -public class AuthenticationManagerRegistry implements Closeable, IAuthenticationManagerRegistry -{ - private final Map<String,AuthenticationManager> _classToAuthManagerMap = new HashMap<String,AuthenticationManager>(); - private final AuthenticationManager _defaultAuthenticationManager; - private final Map<Integer,AuthenticationManager> _portToAuthenticationManagerMap; - private final List<RegistryChangeListener> _listeners = - Collections.synchronizedList(new ArrayList<RegistryChangeListener>()); - - public AuthenticationManagerRegistry(ServerConfiguration serverConfiguration, PluginManager _pluginManager) - throws ConfigurationException - { - final Collection<AuthenticationManagerPluginFactory<? extends Plugin>> factories = _pluginManager.getAuthenticationManagerPlugins().values(); - - if (factories.size() == 0) - { - throw new ConfigurationException("No authentication manager factory plugins found. Check the desired authentication" + - " manager plugin has been placed in the plugins directory."); - } - - final SecurityConfiguration securityConfiguration = serverConfiguration.getConfiguration(SecurityConfiguration.class.getName()); - - boolean willClose = true; - try - { - createAuthenticationManagersRejectingDuplicates(factories, securityConfiguration); - - if(_classToAuthManagerMap.isEmpty()) - { - throw new ConfigurationException("No authentication managers configured within the configuration file."); - } - - _defaultAuthenticationManager = getDefaultAuthenticationManager(serverConfiguration); - - _portToAuthenticationManagerMap = getPortToAuthenticationManagerMap(serverConfiguration); - willClose = false; - } - finally - { - // if anything went wrong whilst configuring the registry, try to close all the AuthentcationManagers instantiated so far. - // This is done to allow the AuthenticationManager to undo any security registrations that they have performed. - if (willClose) - { - close(); - } - } - } - - @Override - public AuthenticationManager getAuthenticationManager(SocketAddress address) - { - AuthenticationManager authManager = - address instanceof InetSocketAddress - ? _portToAuthenticationManagerMap.get(((InetSocketAddress)address).getPort()) - : null; - - return authManager == null ? _defaultAuthenticationManager : authManager; - } - - @Override - public void close() - { - for (AuthenticationManager authManager : _classToAuthManagerMap.values()) - { - authManager.close(); - } - } - - private void createAuthenticationManagersRejectingDuplicates( - final Collection<AuthenticationManagerPluginFactory<? extends Plugin>> factories, - final SecurityConfiguration securityConfiguration) - throws ConfigurationException - { - for(AuthenticationManagerPluginFactory<? extends Plugin> factory : factories) - { - final AuthenticationManager tmp = factory.newInstance(securityConfiguration); - if (tmp != null) - { - if(_classToAuthManagerMap.containsKey(tmp.getClass().getSimpleName())) - { - throw new ConfigurationException("Cannot configure more than one authentication manager of type " - + tmp.getClass().getSimpleName() + "." - + " Remove configuration for one of the authentication managers."); - } - _classToAuthManagerMap.put(tmp.getClass().getSimpleName(),tmp); - - for(RegistryChangeListener listener : _listeners) - { - listener.authenticationManagerRegistered(tmp); - } - } - } - } - - private AuthenticationManager getDefaultAuthenticationManager( - ServerConfiguration serverConfiguration) - throws ConfigurationException - { - final AuthenticationManager defaultAuthenticationManager; - if(_classToAuthManagerMap.size() == 1) - { - defaultAuthenticationManager = _classToAuthManagerMap.values().iterator().next(); - } - else if(serverConfiguration.getDefaultAuthenticationManager() != null) - { - defaultAuthenticationManager = _classToAuthManagerMap.get(serverConfiguration.getDefaultAuthenticationManager()); - if(defaultAuthenticationManager == null) - { - throw new ConfigurationException("No authentication managers configured of type " - + serverConfiguration.getDefaultAuthenticationManager() - + " which is specified as the default. Available managers are: " - + _classToAuthManagerMap.keySet()); - } - } - else - { - throw new ConfigurationException("If more than one authentication manager is configured a default MUST be specified."); - } - return defaultAuthenticationManager; - } - - private Map<Integer,AuthenticationManager> getPortToAuthenticationManagerMap( - ServerConfiguration serverConfiguration) - throws ConfigurationException - { - Map<Integer,AuthenticationManager> portToAuthenticationManagerMap = new HashMap<Integer, AuthenticationManager>(); - - for(Map.Entry<Integer,String> portMapping : serverConfiguration.getPortAuthenticationMappings().entrySet()) - { - - AuthenticationManager authenticationManager = _classToAuthManagerMap.get(portMapping.getValue()); - if(authenticationManager == null) - { - throw new ConfigurationException("Unknown authentication manager class " + portMapping.getValue() + - " configured for port " + portMapping.getKey()); - } - portToAuthenticationManagerMap.put(portMapping.getKey(), authenticationManager); - } - - return portToAuthenticationManagerMap; - } - - @Override - public Map<String, AuthenticationManager> getAvailableAuthenticationManagers() - { - return Collections.unmodifiableMap(new HashMap<String, AuthenticationManager>(_classToAuthManagerMap)); - } - - @Override - public void addRegistryChangeListener(RegistryChangeListener listener) - { - _listeners.add(listener); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFObjectClass.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactory.java index fefdecb8d7..c61567ef77 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFObjectClass.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactory.java @@ -18,27 +18,25 @@ * under the License. * */ -package org.apache.qpid.qmf; +package org.apache.qpid.server.security.auth.manager; -import java.util.List; +import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase; +import org.apache.qpid.server.security.auth.database.PrincipalDatabase; -public abstract class QMFObjectClass<T extends QMFObject, S extends QMFObject.Delegate> extends QMFClass +public class Base64MD5PasswordFileAuthenticationManagerFactory extends AbstractPrincipalDatabaseAuthManagerFactory { - public QMFObjectClass(String name, - byte[] schemaHash, - List<QMFProperty> properties, - List<QMFStatistic> statistics, List<QMFMethod> methods) + public static final String PROVIDER_TYPE = "Base64MD5PasswordFileAuthenticationProvider"; + + @Override + String getType() { - super(QMFClass.Type.OBJECT, name, schemaHash, properties, statistics, methods); + return PROVIDER_TYPE; } - public QMFObjectClass(String name, byte[] schemaHash) + @Override + PrincipalDatabase createPrincipalDatabase() { - super(QMFClass.Type.OBJECT, name, schemaHash); + return new Base64MD5PasswordFilePrincipalDatabase(); } - - public abstract T newInstance(S delegate); - - } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java index 2d6866b657..9ed8cf7fed 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java @@ -19,90 +19,19 @@ package org.apache.qpid.server.security.auth.manager; import java.security.Principal; -import java.util.Arrays; -import java.util.List; -import javax.security.auth.Subject; + import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; + import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.sasl.external.ExternalSaslServer; public class ExternalAuthenticationManager implements AuthenticationManager { - private static final Logger _logger = Logger.getLogger(ExternalAuthenticationManager.class); - private static final String EXTERNAL = "EXTERNAL"; - static final ExternalAuthenticationManager INSTANCE = new ExternalAuthenticationManager(); - - public static class ExternalAuthenticationManagerConfiguration extends ConfigurationPlugin - { - - public static final ConfigurationPluginFactory FACTORY = - new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.external-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new ExternalAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[0]; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - } - - - public static final AuthenticationManagerPluginFactory<ExternalAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<ExternalAuthenticationManager>() - { - public ExternalAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - ExternalAuthenticationManagerConfiguration configuration = - config == null - ? null - : (ExternalAuthenticationManagerConfiguration) config.getConfiguration(ExternalAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for ExternalAuthenticationManager"); - return null; - } - return INSTANCE; - } - - public Class<ExternalAuthenticationManager> getPluginClass() - { - return ExternalAuthenticationManager.class; - } - - public String getPluginName() - { - return ExternalAuthenticationManager.class.getName(); - } - }; - - - private ExternalAuthenticationManager() + ExternalAuthenticationManager() { } @@ -137,15 +66,13 @@ public class ExternalAuthenticationManager implements AuthenticationManager // Process response from the client try { - byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]); + server.evaluateResponse(response != null ? response : new byte[0]); Principal principal = ((ExternalSaslServer)server).getAuthenticatedPrincipal(); if(principal != null) { - final Subject subject = new Subject(); - subject.getPrincipals().add(principal); - return new AuthenticationResult(subject); + return new AuthenticationResult(principal); } else { @@ -162,16 +89,11 @@ public class ExternalAuthenticationManager implements AuthenticationManager @Override public AuthenticationResult authenticate(String username, String password) { - return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR); + return new AuthenticationResult(new UsernamePrincipal(username)); } @Override public void close() { } - - @Override - public void configure(ConfigurationPlugin config) throws ConfigurationException - { - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java new file mode 100644 index 0000000000..3c3628e9db --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth.manager; + +import java.util.Map; + +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; + +public class ExternalAuthenticationManagerFactory implements AuthenticationManagerFactory +{ + public static final String PROVIDER_TYPE = ExternalAuthenticationManager.class.getSimpleName(); + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE))) + { + return new ExternalAuthenticationManager(); + } + return null; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java deleted file mode 100644 index 485ca2e1e9..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.security.auth.manager; - -import java.net.SocketAddress; - -import java.util.Map; -import org.apache.qpid.common.Closeable; -import org.apache.qpid.server.virtualhost.VirtualHost; - -/** - * Registry for {@link AuthenticationManager} instances. - * - * <p>A lookup method {@link #getAuthenticationManager(SocketAddress)} allows a caller to determine - * the AuthenticationManager associated with a particular port number.</p> - * - * <p>It is important to {@link #close()} the registry after use and this allows the AuthenticationManagers - * to reverse any security registrations they have performed.</p> - */ -public interface IAuthenticationManagerRegistry extends Closeable -{ - /** - * Returns the {@link AuthenticationManager} associated with a particular {@link SocketAddress}. - * If no authentication manager is associated with this address, a default authentication manager will be - * returned. Null is never returned. - * - * @param address - * @return authentication manager. - */ - public AuthenticationManager getAuthenticationManager(SocketAddress address); - - Map<String, AuthenticationManager> getAvailableAuthenticationManagers(); - - public static interface RegistryChangeListener - { - void authenticationManagerRegistered(AuthenticationManager authenticationManager); - void authenticationManagerUnregistered(AuthenticationManager authenticationManager); - } - - public void addRegistryChangeListener(RegistryChangeListener listener); - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java index d735ecb1d4..3c1b709648 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java @@ -20,10 +20,7 @@ package org.apache.qpid.server.security.auth.manager; import java.io.IOException; import java.security.Principal; -import java.util.Arrays; import java.util.HashMap; -import java.util.List; -import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; @@ -31,86 +28,15 @@ import javax.security.sasl.AuthorizeCallback; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.UsernamePrincipal; public class KerberosAuthenticationManager implements AuthenticationManager { - private static final Logger _logger = Logger.getLogger(KerberosAuthenticationManager.class); - private static final String GSSAPI_MECHANISM = "GSSAPI"; private final CallbackHandler _callbackHandler = new GssApiCallbackHandler(); - public static class KerberosAuthenticationManagerConfiguration extends ConfigurationPlugin - { - - public static final ConfigurationPluginFactory FACTORY = - new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.kerberos-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new KerberosAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[0]; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - } - - - public static final AuthenticationManagerPluginFactory<KerberosAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<KerberosAuthenticationManager>() - { - public KerberosAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - KerberosAuthenticationManagerConfiguration configuration = - config == null - ? null - : (KerberosAuthenticationManagerConfiguration) config.getConfiguration(KerberosAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for KerberosAuthenticationManager"); - return null; - } - KerberosAuthenticationManager kerberosAuthenticationManager = new KerberosAuthenticationManager(); - kerberosAuthenticationManager.configure(configuration); - return kerberosAuthenticationManager; - } - - public Class<KerberosAuthenticationManager> getPluginClass() - { - return KerberosAuthenticationManager.class; - } - - public String getPluginName() - { - return KerberosAuthenticationManager.class.getName(); - } - }; - - - private KerberosAuthenticationManager() + KerberosAuthenticationManager() { } @@ -158,10 +84,7 @@ public class KerberosAuthenticationManager implements AuthenticationManager if (server.isComplete()) { - final Subject subject = new Subject(); - _logger.debug("Authenticated as " + server.getAuthorizationID()); - subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID())); - return new AuthenticationResult(subject); + return new AuthenticationResult(new UsernamePrincipal(server.getAuthorizationID())); } else { @@ -186,11 +109,6 @@ public class KerberosAuthenticationManager implements AuthenticationManager { } - @Override - public void configure(ConfigurationPlugin config) throws ConfigurationException - { - } - private static class GssApiCallbackHandler implements CallbackHandler { diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java new file mode 100644 index 0000000000..7af6727280 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth.manager; + +import java.util.Map; + +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; + +public class KerberosAuthenticationManagerFactory implements AuthenticationManagerFactory +{ + public static final String PROVIDER_TYPE = KerberosAuthenticationManager.class.getSimpleName(); + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE))) + { + return new KerberosAuthenticationManager(); + } + return null; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java index a51f195761..43b92735f1 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java @@ -20,13 +20,23 @@ */ package org.apache.qpid.server.security.auth.manager; -import org.apache.qpid.server.plugins.PluginFactory; +import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase; +import org.apache.qpid.server.security.auth.database.PrincipalDatabase; -/** - * Factory producing authentication producing configured, initialised authentication - * managers. - */ -public interface AuthenticationManagerPluginFactory<S extends AuthenticationManager> extends PluginFactory<S> +public class PlainPasswordFileAuthenticationManagerFactory extends AbstractPrincipalDatabaseAuthManagerFactory { + public static final String PROVIDER_TYPE = "PlainPasswordFileAuthenticationProvider"; + + @Override + String getType() + { + return PROVIDER_TYPE; + } + + @Override + PrincipalDatabase createPrincipalDatabase() + { + return new PlainPasswordFilePrincipalDatabase(); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java index e6498919a1..f4c834810d 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java @@ -21,38 +21,25 @@ package org.apache.qpid.server.security.auth.manager; import java.security.Principal; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.Logger; -import org.apache.qpid.configuration.PropertyException; -import org.apache.qpid.configuration.PropertyUtils; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; import org.apache.qpid.server.security.auth.AuthenticationResult; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; import org.apache.qpid.server.security.auth.database.PrincipalDatabase; import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser; import org.apache.qpid.server.security.auth.sasl.JCAProvider; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.UsernamePrincipal; -import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.AccountNotFoundException; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import javax.security.sasl.SaslServerFactory; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; + import java.security.Security; -import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; -import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.TreeMap; @@ -60,27 +47,10 @@ import java.util.TreeMap; * Concrete implementation of the AuthenticationManager that determines if supplied * user credentials match those appearing in a PrincipalDatabase. The implementation * of the PrincipalDatabase is determined from the configuration. - * - * This implementation also registers the JMX UserManagemement MBean. - * - * This plugin expects configuration such as: - * - * <pre> - * <pd-auth-manager> - * <principal-database> - * <class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class> - * <attributes> - * <attribute> - * <name>passwordFile</name> - * <value>${conf}/passwd</value> - * </attribute> - * </attributes> - * </principal-database> - * </pd-auth-manager> - * </pre> */ public class PrincipalDatabaseAuthenticationManager implements AuthenticationManager { + private static final Logger _logger = Logger.getLogger(PrincipalDatabaseAuthenticationManager.class); /** The list of mechanisms, in the order in which they are configured (i.e. preferred order) */ @@ -95,95 +65,11 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan */ private final Map<String, Map<String, ?>> _serverCreationProperties = new HashMap<String, Map<String, ?>>(); - private PrincipalDatabase _principalDatabase = null; + private final PrincipalDatabase _principalDatabase; - public static final AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager>() - { - public PrincipalDatabaseAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - final PrincipalDatabaseAuthenticationManagerConfiguration configuration = - config == null - ? null - : (PrincipalDatabaseAuthenticationManagerConfiguration) config.getConfiguration(PrincipalDatabaseAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for PrincipalDatabaseAuthenticationManager"); - return null; - } - - final PrincipalDatabaseAuthenticationManager pdam = new PrincipalDatabaseAuthenticationManager(); - pdam.configure(configuration); - pdam.initialise(); - return pdam; - } - - public Class<PrincipalDatabaseAuthenticationManager> getPluginClass() - { - return PrincipalDatabaseAuthenticationManager.class; - } - - public String getPluginName() - { - return PrincipalDatabaseAuthenticationManager.class.getName(); - } - }; - - public static class PrincipalDatabaseAuthenticationManagerConfiguration extends ConfigurationPlugin { - - public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.pd-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new PrincipalDatabaseAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[] {"principal-database.class", - "principal-database.attributes.attribute.name", - "principal-database.attributes.attribute.value"}; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - public String getPrincipalDatabaseClass() - { - return getConfig().getString("principal-database.class"); - } - - public Map<String,String> getPdClassAttributeMap() throws ConfigurationException - { - final List<String> argumentNames = (List) getConfig().getList("principal-database.attributes.attribute.name"); - final List<String> argumentValues = (List) getConfig().getList("principal-database.attributes.attribute.value"); - final Map<String,String> attributes = new HashMap<String,String>(argumentNames.size()); - - for (int i = 0; i < argumentNames.size(); i++) - { - final String argName = argumentNames.get(i); - final String argValue = argumentValues.get(i); - - attributes.put(argName, argValue); - } - - return Collections.unmodifiableMap(attributes); - } - } - - protected PrincipalDatabaseAuthenticationManager() + public PrincipalDatabaseAuthenticationManager(PrincipalDatabase pd) { + _principalDatabase = pd; } public void initialise() @@ -246,21 +132,6 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan _logger.info("Initialised " + mechanism + " SASL provider successfully"); } - /** - * @see org.apache.qpid.server.plugins.Plugin#configure(org.apache.qpid.server.configuration.plugins.ConfigurationPlugin) - */ - public void configure(final ConfigurationPlugin config) throws ConfigurationException - { - final PrincipalDatabaseAuthenticationManagerConfiguration pdamConfig = (PrincipalDatabaseAuthenticationManagerConfiguration) config; - final String pdClazz = pdamConfig.getPrincipalDatabaseClass(); - - _logger.info("PrincipalDatabase concrete implementation : " + pdClazz); - - _principalDatabase = createPrincipalDatabaseImpl(pdClazz); - - configPrincipalDatabase(_principalDatabase, pdamConfig); - } - public String getMechanisms() { return _mechanisms; @@ -268,8 +139,11 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException { - return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, _serverCreationProperties.get(mechanism), - _callbackHandlerMap.get(mechanism)); + Map<String, ?> properties = _serverCreationProperties.get(mechanism); + CallbackHandler callbackHandler = _callbackHandlerMap.get(mechanism); + + return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, properties, + callbackHandler); } /** @@ -284,9 +158,8 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan if (server.isComplete()) { - final Subject subject = new Subject(); - subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID())); - return new AuthenticationResult(subject); + final String userId = server.getAuthorizationID(); + return new AuthenticationResult(new UsernamePrincipal(userId)); } else { @@ -308,9 +181,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan { if (_principalDatabase.verifyPassword(username, password.toCharArray())) { - final Subject subject = new Subject(); - subject.getPrincipals().add(new UsernamePrincipal(username)); - return new AuthenticationResult(subject); + return new AuthenticationResult(new UsernamePrincipal(username)); } else { @@ -329,100 +200,8 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan Security.removeProvider(PROVIDER_NAME); } - private PrincipalDatabase createPrincipalDatabaseImpl(final String pdClazz) throws ConfigurationException - { - try - { - return (PrincipalDatabase) Class.forName(pdClazz).newInstance(); - } - catch (InstantiationException ie) - { - throw new ConfigurationException("Cannot instantiate " + pdClazz, ie); - } - catch (IllegalAccessException iae) - { - throw new ConfigurationException("Cannot access " + pdClazz, iae); - } - catch (ClassNotFoundException cnfe) - { - throw new ConfigurationException("Cannot load " + pdClazz + " implementation", cnfe); - } - catch (ClassCastException cce) - { - throw new ConfigurationException("Expecting a " + PrincipalDatabase.class + " implementation", cce); - } - } - - private void configPrincipalDatabase(final PrincipalDatabase principalDatabase, final PrincipalDatabaseAuthenticationManagerConfiguration config) - throws ConfigurationException - { - - final Map<String,String> attributes = config.getPdClassAttributeMap(); - - for (Iterator<Entry<String, String>> iterator = attributes.entrySet().iterator(); iterator.hasNext();) - { - final Entry<String, String> nameValuePair = iterator.next(); - final String methodName = generateSetterName(nameValuePair.getKey()); - final Method method; - try - { - method = principalDatabase.getClass().getMethod(methodName, String.class); - } - catch (Exception e) - { - throw new ConfigurationException("No method " + methodName + " found in class " - + principalDatabase.getClass() - + " hence unable to configure principal database. The method must be public and " - + "have a single String argument with a void return type", e); - } - try - { - method.invoke(principalDatabase, PropertyUtils.replaceProperties(nameValuePair.getValue())); - } - catch (IllegalArgumentException e) - { - throw new ConfigurationException(e.getMessage(), e); - } - catch (PropertyException e) - { - throw new ConfigurationException(e.getMessage(), e); - } - catch (IllegalAccessException e) - { - throw new ConfigurationException(e.getMessage(), e); - } - catch (InvocationTargetException e) - { - // QPID-1347.. InvocationTargetException wraps the checked exception thrown from the reflective - // method call. Pull out the underlying message and cause to make these more apparent to the user. - throw new ConfigurationException(e.getCause().getMessage(), e.getCause()); - } - } - } - public PrincipalDatabase getPrincipalDatabase() { return _principalDatabase; } - - private String generateSetterName(String argName) throws ConfigurationException - { - if ((argName == null) || (argName.length() == 0)) - { - throw new ConfigurationException("Argument names must have length >= 1 character"); - } - - if (Character.isLowerCase(argName.charAt(0))) - { - argName = Character.toUpperCase(argName.charAt(0)) + argName.substring(1); - } - - final String methodName = "set" + argName; - return methodName; - } - - protected void setPrincipalDatabase(final PrincipalDatabase principalDatabase) - { - _principalDatabase = principalDatabase; - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java index 64b24e28bc..7891ef8cf5 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java @@ -21,10 +21,10 @@ package org.apache.qpid.server.security.auth.manager; import java.io.IOException; import java.security.Principal; -import java.util.Arrays; import java.util.HashMap; import java.util.Hashtable; -import java.util.List; + +import javax.naming.AuthenticationException; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; @@ -32,7 +32,6 @@ import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; -import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; @@ -41,13 +40,10 @@ import javax.security.sasl.AuthorizeCallback; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.sasl.plain.PlainPasswordCallback; public class SimpleLDAPAuthenticationManager implements AuthenticationManager @@ -55,123 +51,25 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager private static final Logger _logger = Logger.getLogger(SimpleLDAPAuthenticationManager.class); private static final String PLAIN_MECHANISM = "PLAIN"; - private static final String DEFAULT_LDAP_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory"; - private String _providerSearchURL; - private String _searchContext; - private String _searchFilter; - private String _providerAuthURL; - private String _ldapContextFactory; - - public static class SimpleLDAPAuthenticationManagerConfiguration extends ConfigurationPlugin - { - - public static final ConfigurationPluginFactory FACTORY = - new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.simple-ldap-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new SimpleLDAPAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - private static final String PROVIDER_URL = "provider-url"; - private static final String PROVIDER_SEARCH_URL = "provider-search-url"; - private static final String PROVIDER_AUTH_URL = "provider-auth-url"; - private static final String SEARCH_CONTEXT = "search-context"; - private static final String SEARCH_FILTER = "search-filter"; - private static final String LDAP_CONTEXT_FACTORY = "ldap-context-factory"; - - public String[] getElementsProcessed() - { - return new String[] {PROVIDER_URL, PROVIDER_SEARCH_URL, PROVIDER_AUTH_URL, SEARCH_CONTEXT, SEARCH_FILTER, - LDAP_CONTEXT_FACTORY}; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - public String getLDAPContextFactory() - { - return getConfig().getString(LDAP_CONTEXT_FACTORY, DEFAULT_LDAP_CONTEXT_FACTORY); - } - - - public String getProviderURL() - { - return getConfig().getString(PROVIDER_URL); - } - - public String getProviderSearchURL() - { - return getConfig().getString(PROVIDER_SEARCH_URL, getProviderURL()); - } - - public String getSearchContext() - { - return getConfig().getString(SEARCH_CONTEXT); - } - - public String getSearchFilter() - { - return getConfig().getString(SEARCH_FILTER); - } - - public String getProviderAuthURL() - { - return getConfig().getString(PROVIDER_AUTH_URL, getProviderURL()); - } - } - - - public static final AuthenticationManagerPluginFactory<SimpleLDAPAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<SimpleLDAPAuthenticationManager>() - { - public SimpleLDAPAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - SimpleLDAPAuthenticationManagerConfiguration configuration = - config == null - ? null - : (SimpleLDAPAuthenticationManagerConfiguration) config.getConfiguration(SimpleLDAPAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for SimpleLDAPAuthenticationManager"); - return null; - } - SimpleLDAPAuthenticationManager simpleLDAPAuthenticationManager = new SimpleLDAPAuthenticationManager(); - simpleLDAPAuthenticationManager.configure(configuration); - return simpleLDAPAuthenticationManager; - } - - public Class<SimpleLDAPAuthenticationManager> getPluginClass() - { - return SimpleLDAPAuthenticationManager.class; - } - - public String getPluginName() - { - return SimpleLDAPAuthenticationManager.class.getName(); - } - }; - + private final String _providerSearchURL; + private final String _providerAuthURL; + private final String _searchContext; + private final String _searchFilter; + private final String _ldapContextFactory; - private SimpleLDAPAuthenticationManager() + SimpleLDAPAuthenticationManager(String providerSearchUrl, String providerAuthUrl, String searchContext, String searchFilter, String ldapContextFactory) { + _providerSearchURL = providerSearchUrl; + _providerAuthURL = providerAuthUrl; + _searchContext = searchContext; + _searchFilter = searchFilter; + _ldapContextFactory = ldapContextFactory; } @Override public void initialise() { - + validateInitialDirContext(); } @Override @@ -205,10 +103,10 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager if (server.isComplete()) { - final Subject subject = new Subject(); - _logger.debug("Authenticated as " + server.getAuthorizationID()); - subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID())); - return new AuthenticationResult(subject); + String authorizationID = server.getAuthorizationID(); + _logger.debug("Authenticated as " + authorizationID); + + return new AuthenticationResult(new UsernamePrincipal(authorizationID)); } else { @@ -224,34 +122,74 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager @Override public AuthenticationResult authenticate(String username, String password) { - try { - return doLDAPNameAuthentication(getNameFromId(username), password); + AuthenticationResult result = doLDAPNameAuthentication(getNameFromId(username), password); + if(result.getStatus() == AuthenticationStatus.SUCCESS) + { + //Return a result based on the supplied username rather than the search name + return new AuthenticationResult(new UsernamePrincipal(username)); + } + else + { + return result; + } } catch (NamingException e) { - return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e); - } } - private AuthenticationResult doLDAPNameAuthentication(String username, String password) throws NamingException + private AuthenticationResult doLDAPNameAuthentication(String name, String password) { + if(name == null) + { + //The search didn't return anything, class as not-authenticated before it NPEs below + return new AuthenticationResult(AuthenticationStatus.CONTINUE); + } + Hashtable<Object,Object> env = new Hashtable<Object,Object>(); env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory); env.put(Context.PROVIDER_URL, _providerAuthURL); env.put(Context.SECURITY_AUTHENTICATION, "simple"); - env.put(Context.SECURITY_PRINCIPAL, username); + env.put(Context.SECURITY_PRINCIPAL, name); env.put(Context.SECURITY_CREDENTIALS, password); - DirContext ctx = new InitialDirContext(env); - ctx.close(); - final Subject subject = new Subject(); - subject.getPrincipals().add(new UsernamePrincipal(username)); - return new AuthenticationResult(subject); + + DirContext ctx = null; + try + { + ctx = new InitialDirContext(env); + + //Authentication succeeded + return new AuthenticationResult(new UsernamePrincipal(name)); + } + catch(AuthenticationException ae) + { + //Authentication failed + return new AuthenticationResult(AuthenticationStatus.CONTINUE); + } + catch (NamingException e) + { + //Some other failure + return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e); + } + finally + { + if(ctx != null) + { + try + { + ctx.close(); + } + catch (Exception e) + { + _logger.warn("Exception closing InitialDirContext", e); + } + } + } } @Override @@ -259,17 +197,8 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager { } - @Override - public void configure(ConfigurationPlugin config) throws ConfigurationException + private void validateInitialDirContext() { - SimpleLDAPAuthenticationManagerConfiguration ldapConfig = (SimpleLDAPAuthenticationManagerConfiguration) config; - - _ldapContextFactory = ldapConfig.getLDAPContextFactory(); - _providerSearchURL = ldapConfig.getProviderSearchURL(); - _providerAuthURL = ldapConfig.getProviderAuthURL(); - _searchContext = ldapConfig.getSearchContext(); - _searchFilter = ldapConfig.getSearchFilter(); - Hashtable<String,Object> env = new Hashtable<String, Object>(); env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory); env.put(Context.PROVIDER_URL, _providerSearchURL); @@ -277,11 +206,11 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager try { - new InitialDirContext(env); + new InitialDirContext(env).close(); } catch (NamingException e) { - throw new ConfigurationException("Unable to establish anonymous connection to the ldap server at " + _providerSearchURL, e); + throw new RuntimeException("Unable to establish anonymous connection to the ldap server at " + _providerSearchURL, e); } } @@ -305,19 +234,11 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager } catch (NamingException e) { - _logger.info("SASL Authentication Error", e); + _logger.warn("SASL Authentication Exception", e); } if(password != null) { - try - { - authenticated = doLDAPNameAuthentication(name, password); - - } - catch (NamingException e) - { - authenticated = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e); - } + authenticated = doLDAPNameAuthentication(name, password); } } else if (callback instanceof PlainPasswordCallback) @@ -325,17 +246,10 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager password = ((PlainPasswordCallback)callback).getPlainPassword(); if(name != null) { - try - { - authenticated = doLDAPNameAuthentication(name, password); - if(authenticated.getStatus()== AuthenticationResult.AuthenticationStatus.SUCCESS) - { - ((PlainPasswordCallback)callback).setAuthenticated(true); - } - } - catch (NamingException e) + authenticated = doLDAPNameAuthentication(name, password); + if(authenticated.getStatus()== AuthenticationResult.AuthenticationStatus.SUCCESS) { - authenticated = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e); + ((PlainPasswordCallback)callback).setAuthenticated(true); } } } @@ -357,7 +271,6 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory); env.put(Context.PROVIDER_URL, _providerSearchURL); - env.put(Context.SECURITY_AUTHENTICATION, "none"); DirContext ctx = null; @@ -382,7 +295,14 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager } finally { - ctx.close(); + try + { + ctx.close(); + } + catch (Exception e) + { + _logger.warn("Exception closing InitialDirContext", e); + } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java new file mode 100644 index 0000000000..05a692fb0e --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java @@ -0,0 +1,69 @@ +/* + * 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.security.auth.manager; + +import java.util.Map; + +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; + +public class SimpleLDAPAuthenticationManagerFactory implements AuthenticationManagerFactory +{ + private static final String DEFAULT_LDAP_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory"; + + public static final String PROVIDER_TYPE = SimpleLDAPAuthenticationManager.class.getSimpleName(); + + public static final String ATTRIBUTE_LDAP_CONTEXT_FACTORY = "ldapContextFactory"; + public static final String ATTRIBUTE_SEARCH_FILTER = "searchFilter"; + public static final String ATTRIBUTE_SEARCH_CONTEXT = "searchContext"; + public static final String ATTRIBUTE_PROVIDER_AUTH_URL = "providerAuthUrl"; + public static final String ATTRIBUTE_PROVIDER_SEARCH_URL = "providerSearchUrl"; + public static final String ATTRIBUTE_PROVIDER_URL = "providerUrl"; + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes == null || !PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE))) + { + return null; + } + String providerUrl = (String) attributes.get(ATTRIBUTE_PROVIDER_URL); + String providerSearchUrl = (String) attributes.get(ATTRIBUTE_PROVIDER_SEARCH_URL); + if (providerSearchUrl == null) + { + providerSearchUrl = providerUrl; + } + String providerAuthUrl = (String) attributes.get(ATTRIBUTE_PROVIDER_AUTH_URL); + if (providerAuthUrl == null) + { + providerAuthUrl = providerUrl; + } + String searchContext = (String) attributes.get(ATTRIBUTE_SEARCH_CONTEXT); + String searchFilter = (String) attributes.get(ATTRIBUTE_SEARCH_FILTER); + String ldapContextFactory = (String) attributes.get(ATTRIBUTE_LDAP_CONTEXT_FACTORY); + if (ldapContextFactory == null) + { + ldapContextFactory = DEFAULT_LDAP_CONTEXT_FACTORY; + } + + return new SimpleLDAPAuthenticationManager(providerSearchUrl, providerAuthUrl, searchContext, searchFilter, + ldapContextFactory); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java index 2e21cfbb07..abb8677e90 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java @@ -22,13 +22,13 @@ package org.apache.qpid.server.security.auth.rmi; import java.net.SocketAddress; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; import javax.management.remote.JMXAuthenticator; -import javax.management.remote.JMXPrincipal; import javax.security.auth.Subject; public class RMIPasswordAuthenticator implements JMXAuthenticator @@ -38,23 +38,33 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator static final String SHOULD_HAVE_2_ELEMENTS = "User details should have 2 elements, username, password"; static final String SHOULD_BE_NON_NULL = "Supplied username and password should be non-null"; static final String INVALID_CREDENTIALS = "Invalid user details supplied"; + static final String USER_NOT_AUTHORISED_FOR_MANAGEMENT = "User not authorised for management"; static final String CREDENTIALS_REQUIRED = "User details are required. " + - "Please ensure you are using an up to date management console to connect."; + "Please ensure you are using an up to date management console to connect."; - private AuthenticationManager _authenticationManager = null; - private SocketAddress _socketAddress; + private final Broker _broker; + private final SocketAddress _address; - public RMIPasswordAuthenticator(SocketAddress socketAddress) + public RMIPasswordAuthenticator(Broker broker, SocketAddress address) { - _socketAddress = socketAddress; + _broker = broker; + _address = address; } - public void setAuthenticationManager(final AuthenticationManager authenticationManager) + public Subject authenticate(Object credentials) throws SecurityException { - _authenticationManager = authenticationManager; + validateCredentials(credentials); + + final String[] userCredentials = (String[]) credentials; + final String username = (String) userCredentials[0]; + final String password = (String) userCredentials[1]; + + final Subject authenticatedSubject = doAuthentication(username, password); + doManagementAuthorisation(authenticatedSubject); + return authenticatedSubject; } - public Subject authenticate(Object credentials) throws SecurityException + private void validateCredentials(Object credentials) { // Verify that credential's are of type String[]. if (!(credentials instanceof String[])) @@ -70,41 +80,27 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator } // Verify that required number of credentials. - final String[] userCredentials = (String[]) credentials; - if (userCredentials.length != 2) + if (((String[])credentials).length != 2) { throw new SecurityException(SHOULD_HAVE_2_ELEMENTS); } + } - final String username = (String) userCredentials[0]; - final String password = (String) userCredentials[1]; - + private Subject doAuthentication(final String username, final String password) + { // Verify that all required credentials are actually present. if (username == null || password == null) { throw new SecurityException(SHOULD_BE_NON_NULL); } - // Verify that an AuthenticationManager has been set. - if (_authenticationManager == null) + SubjectCreator subjectCreator = _broker.getSubjectCreator(_address); + if (subjectCreator == null) { - try - { - if(ApplicationRegistry.getInstance().getAuthenticationManager(_socketAddress) != null) - { - _authenticationManager = ApplicationRegistry.getInstance().getAuthenticationManager(_socketAddress); - } - else - { - throw new SecurityException(UNABLE_TO_LOOKUP); - } - } - catch(IllegalStateException e) - { - throw new SecurityException(UNABLE_TO_LOOKUP); - } + throw new SecurityException("Can't get subject creator for " + _address); } - final AuthenticationResult result = _authenticationManager.authenticate(username, password); + + final SubjectAuthenticationResult result = subjectCreator.authenticate(username, password); if (AuthenticationStatus.ERROR.equals(result.getStatus())) { @@ -112,10 +108,7 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator } else if (AuthenticationStatus.SUCCESS.equals(result.getStatus())) { - final Subject subject = result.getSubject(); - subject.getPrincipals().add(new JMXPrincipal(username)); - subject.setReadOnly(); - return subject; + return result.getSubject(); } else { @@ -123,4 +116,21 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator } } + private void doManagementAuthorisation(Subject authenticatedSubject) + { + SecurityManager.setThreadSubject(authenticatedSubject); + try + { + if (!_broker.getSecurityManager().accessManagement()) + { + throw new SecurityException(USER_NOT_AUTHORISED_FOR_MANAGEMENT); + } + } + finally + { + SecurityManager.setThreadSubject(null); + } + } + + }
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java index f4e8f800c6..b70a987107 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java @@ -23,6 +23,7 @@ package org.apache.qpid.server.security.auth.sasl; import org.apache.commons.configuration.Configuration; import org.apache.log4j.Logger; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.database.PrincipalDatabase; import javax.security.auth.callback.Callback; diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java index 52d36023c2..d10193e743 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java @@ -23,6 +23,8 @@ package org.apache.qpid.server.security.auth.sasl.anonymous; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; +import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager; + public class AnonymousSaslServer implements SaslServer { @@ -52,7 +54,7 @@ public class AnonymousSaslServer implements SaslServer public String getAuthorizationID() { - return null; + return AnonymousAuthenticationManager.ANONYMOUS_PRINCIPAL.getName(); } public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java index 478f195530..4e12ac0750 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java @@ -139,6 +139,12 @@ public class CRAMMD5HexInitialiser extends UsernamePasswordInitialiser { _realPricipalDatabase.reload(); } + + @Override + public void setPasswordFile(String passwordFile) throws IOException + { + throw new UnsupportedOperationException(); + } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupDatabase.java new file mode 100644 index 0000000000..c66e7fd4e4 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupDatabase.java @@ -0,0 +1,287 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.group; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Collections; +import java.util.Date; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListSet; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +/** + * A group database that reads/writes the following file format: + * + * group1.users=user1,user2 + * group2.users=user2,user3 + */ +public class FileGroupDatabase implements GroupDatabase +{ + private static final Logger LOGGER = Logger.getLogger(FileGroupDatabase.class); + + private Map<String, Set<String>> _groupToUserMap = new ConcurrentHashMap<String, Set<String>>(); + private Map<String, Set<String>> _userToGroupMap = new ConcurrentHashMap<String, Set<String>>(); + private String _groupFile; + + @Override + public Set<String> getAllGroups() + { + return Collections.unmodifiableSet(_groupToUserMap.keySet()); + } + + public synchronized void setGroupFile(String groupFile) throws IOException + { + File file = new File(groupFile); + + if (!file.canRead()) + { + throw new FileNotFoundException(groupFile + + " cannot be found or is not readable"); + } + + readGroupFile(groupFile); + } + + @Override + public Set<String> getUsersInGroup(String group) + { + if (group == null) + { + LOGGER.warn("Requested user set for null group. Returning empty set."); + return Collections.emptySet(); + } + + Set<String> set = _groupToUserMap.get(group); + if (set == null) + { + return Collections.emptySet(); + } + else + { + return Collections.unmodifiableSet(set); + } + } + + @Override + public synchronized void addUserToGroup(String user, String group) + { + Set<String> users = _groupToUserMap.get(group); + if (users == null) + { + throw new IllegalArgumentException("Group " + group + " does not exist so could not add " + user + " to it"); + } + + users.add(user); + + Set<String> groups = _userToGroupMap.get(user); + if (groups == null) + { + groups = new ConcurrentSkipListSet<String>(); + _userToGroupMap.put(user, groups); + } + groups.add(group); + + update(); + } + + @Override + public synchronized void removeUserFromGroup(String user, String group) + { + Set<String> users = _groupToUserMap.get(group); + if (users == null) + { + throw new IllegalArgumentException("Group " + group + " does not exist so could not remove " + user + " from it"); + } + + users.remove(user); + + Set<String> groups = _userToGroupMap.get(user); + if (groups != null) + { + groups.remove(group); + } + + update(); + } + + @Override + public Set<String> getGroupsForUser(String user) + { + if(user == null) + { + LOGGER.warn("Requested group set for null user. Returning empty set."); + return Collections.emptySet(); + } + + Set<String> groups = _userToGroupMap.get(user); + if (groups == null) + { + return Collections.emptySet(); + } + else + { + return Collections.unmodifiableSet(groups); + } + } + + @Override + public synchronized void createGroup(String group) + { + Set<String> users = new ConcurrentSkipListSet<String>(); + _groupToUserMap.put(group, users); + + update(); + } + + @Override + public synchronized void removeGroup(String group) + { + _groupToUserMap.remove(group); + for (Set<String> groupsForUser : _userToGroupMap.values()) + { + groupsForUser.remove(group); + } + + update(); + } + + private synchronized void update() + { + if (_groupFile != null) + { + try + { + writeGroupFile(_groupFile); + } + catch (IOException e) + { + throw new RuntimeException("Unable to persist change to file " + _groupFile); + } + } + } + + private synchronized void readGroupFile(String groupFile) throws IOException + { + _groupFile = groupFile; + _groupToUserMap.clear(); + _userToGroupMap.clear(); + Properties propertiesFile = new Properties(); + FileInputStream fileInputStream = new FileInputStream(groupFile); + try + { + propertiesFile.load(fileInputStream); + } + finally + { + if(fileInputStream != null) + { + fileInputStream.close(); + } + } + + for (String propertyName : propertiesFile.stringPropertyNames()) + { + validatePropertyNameIsGroupName(propertyName); + + String groupName = propertyName.replaceAll("\\.users$", ""); + String userString = propertiesFile.getProperty(propertyName); + + final Set<String> userSet = buildUserSetFromCommaSeparateValue(userString); + + _groupToUserMap.put(groupName, userSet); + + for (String userName : userSet) + { + Set<String> groupsForThisUser = _userToGroupMap.get(userName); + + if (groupsForThisUser == null) + { + groupsForThisUser = new ConcurrentSkipListSet<String>(); + _userToGroupMap.put(userName, groupsForThisUser); + } + + groupsForThisUser.add(groupName); + } + } + } + + private synchronized void writeGroupFile(String groupFile) throws IOException + { + Properties propertiesFile = new Properties(); + + for (String group : _groupToUserMap.keySet()) + { + Set<String> users = _groupToUserMap.get(group); + String userList = StringUtils.join(users, ","); + + propertiesFile.setProperty(group + ".users", userList); + } + + String comment = "Written " + new Date(); + FileOutputStream fileOutputStream = new FileOutputStream(groupFile); + try + { + propertiesFile.store(fileOutputStream, comment); + } + finally + { + if(fileOutputStream != null) + { + fileOutputStream.close(); + } + } + } + + private void validatePropertyNameIsGroupName(String propertyName) + { + if (!propertyName.endsWith(".users")) + { + throw new IllegalArgumentException( + "Invalid definition with name '" + + propertyName + + "'. Group definitions must end with suffix '.users'"); + } + } + + private ConcurrentSkipListSet<String> buildUserSetFromCommaSeparateValue(String userString) + { + String[] users = userString.split(","); + final ConcurrentSkipListSet<String> userSet = new ConcurrentSkipListSet<String>(); + for (String user : users) + { + final String trimmed = user.trim(); + if (!trimmed.isEmpty()) + { + userSet.add(trimmed); + } + } + return userSet; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManager.java new file mode 100644 index 0000000000..8295f28f9e --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManager.java @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.group; + +import java.io.IOException; +import java.security.Principal; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.security.auth.UsernamePrincipal; + +/** + * Implementation of a group manager whose implementation is backed by a flat group file. + * <p> + * This plugin is configured in the following manner: + * </p> + * <pre> + * <file-group-manager> + * <attributes> + * <attribute> + * <name>groupFile</name> + * <value>${conf}/groups</value> + * </attribute> + * </attributes> + * </file-group-manager> + * </pre> + */ +public class FileGroupManager implements GroupManager +{ + private final FileGroupDatabase _groupDatabase; + + + public FileGroupManager(String groupFile) + { + _groupDatabase = new FileGroupDatabase(); + try + { + _groupDatabase.setGroupFile(groupFile); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Unable to set group file " + groupFile, e); + } + } + + @Override + public Set<Principal> getGroupPrincipalsForUser(String userId) + { + Set<String> groups = _groupDatabase.getGroupsForUser(userId); + if (groups.isEmpty()) + { + return Collections.emptySet(); + } + else + { + Set<Principal> principals = new HashSet<Principal>(); + for (String groupName : groups) + { + principals.add(new GroupPrincipal(groupName)); + } + return principals; + } + } + + @Override + public Set<Principal> getUserPrincipalsForGroup(String group) + { + Set<String> users = _groupDatabase.getUsersInGroup(group); + if (users.isEmpty()) + { + return Collections.emptySet(); + } + else + { + Set<Principal> principals = new HashSet<Principal>(); + for (String user : users) + { + principals.add(new UsernamePrincipal(user)); + } + return principals; + } + } + + @Override + public Set<Principal> getGroupPrincipals() + { + Set<String> groups = _groupDatabase.getAllGroups(); + if (groups.isEmpty()) + { + return Collections.emptySet(); + } + else + { + Set<Principal> principals = new HashSet<Principal>(); + for (String groupName : groups) + { + principals.add(new GroupPrincipal(groupName)); + } + return principals; + } + } + + @Override + public void createGroup(String group) + { + _groupDatabase.createGroup(group); + } + + @Override + public void removeGroup(String group) + { + _groupDatabase.removeGroup(group); + } + + @Override + public void addUserToGroup(String user, String group) + { + _groupDatabase.addUserToGroup(user, group); + } + + @Override + public void removeUserFromGroup(String user, String group) + { + _groupDatabase.removeUserFromGroup(user, group); + + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManagerFactory.java new file mode 100644 index 0000000000..5c4730a9c8 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManagerFactory.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.security.group; + +import static org.apache.qpid.server.util.MapValueConverter.getStringAttribute; + +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.plugin.GroupManagerFactory; + +public class FileGroupManagerFactory implements GroupManagerFactory +{ + static final String FILE_GROUP_MANAGER_TYPE = "file-group-manager"; + static final String FILE = "file"; + + @Override + public GroupManager createInstance(Map<String, Object> attributes) + { + if(!FILE_GROUP_MANAGER_TYPE.equals(getStringAttribute(GroupProvider.TYPE, attributes, null))) + { + return null; + } + + String groupFile = getStringAttribute(FILE, attributes, null); + if (StringUtils.isBlank(groupFile)) + { + throw new IllegalConfigurationException("Path to file containing groups is not specified!"); + } + return new FileGroupManager(groupFile); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupDatabase.java index ff4e38d9f7..98c12782d8 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupDatabase.java @@ -1,5 +1,4 @@ /* - * * 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 @@ -18,20 +17,18 @@ * under the License. * */ +package org.apache.qpid.server.security.group; -package org.apache.qpid.server.configuration; - -import java.util.UUID; +import java.util.Set; -public interface ConfiguredObject<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T, C>> +public interface GroupDatabase { - public UUID getQMFId(); - - public T getConfigType(); - - public ConfiguredObject<T,C> getParent(); - - public boolean isDurable(); + Set<String> getAllGroups(); + Set<String> getUsersInGroup(String group); - long getCreateTime(); + void addUserToGroup(String user, String group); + void removeUserFromGroup(String user, String group); + Set<String> getGroupsForUser(String user); + void createGroup(String group); + void removeGroup(String group); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfig.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManager.java index b101d70553..6d2df86919 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfig.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManager.java @@ -1,5 +1,4 @@ /* - * * 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 @@ -18,30 +17,24 @@ * under the License. * */ +package org.apache.qpid.server.security.group; -package org.apache.qpid.server.configuration; - -import java.util.Map; - +import java.security.Principal; +import java.util.Set; -public interface SubscriptionConfig extends ConfiguredObject<SubscriptionConfigType, SubscriptionConfig> +public interface GroupManager { + Set<Principal> getGroupPrincipalsForUser(String user); - SessionConfig getSessionConfig(); - - QueueConfig getQueue(); - - String getName(); - - Map<String, Object> getArguments(); + Set<Principal> getGroupPrincipals(); - String getCreditMode(); + Set<Principal> getUserPrincipalsForGroup(String group); - boolean isBrowsing(); + void createGroup(String group); - boolean isExclusive(); + void removeGroup(String group); - boolean isExplicitAcknowledge(); + void addUserToGroup(String user, String group); - Long getDelivered(); -}
\ No newline at end of file + void removeUserFromGroup(String user, String group); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java index 30a503c769..a9590bb964 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java @@ -7,9 +7,9 @@ * 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 @@ -18,8 +18,9 @@ * under the License. * */ -package org.apache.qpid.server.security.auth.sasl; +package org.apache.qpid.server.security.group; +import java.io.Serializable; import java.security.Principal; import java.security.acl.Group; import java.util.Enumeration; @@ -30,11 +31,11 @@ import java.util.Enumeration; * methods etc throw {@link UnsupportedOperationException}. * */ -public class GroupPrincipal implements Group +public class GroupPrincipal implements Group, Serializable { /** Name of the group */ private final String _groupName; - + public GroupPrincipal(final String groupName) { _groupName = groupName; @@ -83,7 +84,7 @@ public class GroupPrincipal implements Group { return true; } - else + else { if (obj instanceof GroupPrincipal) { diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java new file mode 100644 index 0000000000..d549b76aab --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.security.group; + +import java.security.Principal; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.model.adapter.GroupProviderAdapter; + + +public class GroupPrincipalAccessor +{ + private final Collection<GroupProvider> _groupProviders; + + public GroupPrincipalAccessor(Collection<GroupProvider> groupProviders) + { + _groupProviders = groupProviders; + } + + public Set<Principal> getGroupPrincipals(String username) + { + Set<Principal> principals = new HashSet<Principal>(); + for (GroupProvider groupProvider : _groupProviders) + { + Set<Principal> groups = groupProvider.getGroupPrincipalsForUser(username); + if (groups != null) + { + principals.addAll(groups); + } + } + + return Collections.unmodifiableSet(principals); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/signal/SignalHandlerTask.java b/java/broker/src/main/java/org/apache/qpid/server/signal/SignalHandlerTask.java deleted file mode 100644 index bdcfd86f82..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/signal/SignalHandlerTask.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * 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.signal; - -import org.apache.log4j.Logger; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -public abstract class SignalHandlerTask -{ - private static final Logger LOGGER = Logger.getLogger(SignalHandlerTask.class); - - private static final String HANDLE_METHOD = "handle"; - private static final String SUN_MISC_SIGNAL_CLASS = "sun.misc.Signal"; - private static final String SUN_MISC_SIGNAL_HANDLER_CLASS = "sun.misc.SignalHandler"; - - public boolean register(final String signalName) - { - try - { - //try to load the signal handling classes - Class<?> signalClazz = Class.forName(SUN_MISC_SIGNAL_CLASS); - Class<?> handlerClazz = Class.forName(SUN_MISC_SIGNAL_HANDLER_CLASS); - - //create an InvocationHandler that just executes the SignalHandlerTask - InvocationHandler invoker = new InvocationHandler() - { - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable - { - handle(); - - return null; - } - }; - - //create a dynamic proxy implementing SignalHandler - Object handler = Proxy.newProxyInstance(handlerClazz.getClassLoader(), new Class[]{handlerClazz}, invoker); - - //create the Signal to handle - Constructor<?> signalConstructor = signalClazz.getConstructor(String.class); - Object signal = signalConstructor.newInstance(signalName); - - //invoke the Signal.handle(signal, handler) method - Method handleMethod = signalClazz.getMethod(HANDLE_METHOD, signalClazz, handlerClazz); - handleMethod.invoke(null, signal, handler); - } - catch (Exception e) - { - LOGGER.debug("Unable to register handler for Signal " + signalName + " due to exception: " + e, e); - return false; - } - - return true; - } - - public abstract void handle(); - - public static String getPlatformDescription() - { - String name = System.getProperty("os.name"); - String osVer = System.getProperty("os.version"); - String jvmVendor = System.getProperty("java.vm.vendor"); - String jvmName = System.getProperty("java.vm.name"); - String javaRuntimeVer = System.getProperty("java.runtime.version"); - - return "OS: " + name + " " + osVer + ", JVM:" + jvmVendor + " " + jvmName + " " + javaRuntimeVer; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java b/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java index f352bbdd2c..ff41536a23 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java @@ -31,10 +31,10 @@ import org.apache.qpid.framing.MethodDispatcher; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.security.SecurityManager; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; import java.util.concurrent.CopyOnWriteArraySet; @@ -47,32 +47,29 @@ public class AMQStateManager implements AMQMethodListener { private static final Logger _logger = Logger.getLogger(AMQStateManager.class); - private final VirtualHostRegistry _virtualHostRegistry; + private final Broker _broker; private final AMQProtocolSession _protocolSession; /** The current state */ private AMQState _currentState; private CopyOnWriteArraySet<StateListener> _stateListeners = new CopyOnWriteArraySet<StateListener>(); - public AMQStateManager(VirtualHostRegistry virtualHostRegistry, AMQProtocolSession protocolSession) + public AMQStateManager(Broker broker, AMQProtocolSession protocolSession) { - - _virtualHostRegistry = virtualHostRegistry; + _broker = broker; _protocolSession = protocolSession; _currentState = AMQState.CONNECTION_NOT_STARTED; } /** - * Get the ApplicationRegistry associated with this AMQStateManager - * - * returns the application registry associated with the VirtualHostRegistry of the AMQStateManager + * Get the Broker instance * - * @return the ApplicationRegistry + * @return the Broker */ - public IApplicationRegistry getApplicationRegistry() + public Broker getBroker() { - return _virtualHostRegistry.getApplicationRegistry(); + return _broker; } public AMQState getCurrentState() @@ -148,7 +145,7 @@ public class AMQStateManager implements AMQMethodListener public VirtualHostRegistry getVirtualHostRegistry() { - return _virtualHostRegistry; + return _broker.getVirtualHostRegistry(); } public AMQProtocolSession getProtocolSession() @@ -157,13 +154,9 @@ public class AMQStateManager implements AMQMethodListener return _protocolSession; } - /** - * Get the AuthenticationManager associated with the ProtocolSession of the AMQStateManager - * - * @return the AuthenticationManager - */ - public AuthenticationManager getAuthenticationManager() + + public SubjectCreator getSubjectCreator() { - return getApplicationRegistry().getAuthenticationManager(getProtocolSession().getLocalAddress()); + return _broker.getSubjectCreator(getProtocolSession().getLocalAddress()); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java b/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java index ede01d247e..ab7ef3f55b 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java @@ -46,19 +46,7 @@ public interface ConfigurationRecoveryHandler public static interface BindingRecoveryHandler { void binding(UUID bindingId, UUID exchangeId, UUID queueId, String bindingName, ByteBuffer buf); - BrokerLinkRecoveryHandler completeBindingRecovery(); - } - - public static interface BrokerLinkRecoveryHandler - { - BridgeRecoveryHandler brokerLink(UUID id, long createTime, Map<String,String> arguments); - void completeBrokerLinkRecovery(); - } - - public static interface BridgeRecoveryHandler - { - void bridge(UUID id, long createTime, Map<String,String> arguments); - void completeBridgeRecoveryForLink(); + void completeBindingRecovery(); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java index 655887e5c2..4e7bbf04a6 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java @@ -26,8 +26,6 @@ import org.apache.qpid.AMQStoreException; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.federation.Bridge; -import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.queue.AMQQueue; public interface DurableConfigurationStore @@ -122,12 +120,5 @@ public interface DurableConfigurationStore * @throws AMQStoreException If the operation fails for any reason. */ void updateQueue(AMQQueue queue) throws AMQStoreException; - - void createBrokerLink(BrokerLink link) throws AMQStoreException; - - void deleteBrokerLink(BrokerLink link) throws AMQStoreException; - - void createBridge(Bridge bridge) throws AMQStoreException; - - void deleteBridge(Bridge bridge) throws AMQStoreException; + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java index 262d7d0213..3f1d1b9530 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java @@ -30,6 +30,7 @@ import java.util.concurrent.atomic.AtomicLong; /** A simple message store that stores the messages in a thread-safe structure in memory. */ public class MemoryMessageStore extends NullMessageStore { + public static final String TYPE = "Memory"; private final AtomicLong _messageId = new AtomicLong(1); private final AtomicBoolean _closed = new AtomicBoolean(false); @@ -138,6 +139,6 @@ public class MemoryMessageStore extends NullMessageStore @Override public String getStoreType() { - return "Memory"; + return TYPE; } } diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/CompletionCode.java b/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java index 706ab3974a..20b6b7a8a6 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/CompletionCode.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java @@ -18,19 +18,22 @@ * under the License. * */ +package org.apache.qpid.server.store; -package org.apache.qpid.qmf; -public enum CompletionCode +public class MemoryMessageStoreFactory implements MessageStoreFactory { - OK, - UNKNOWN_OBJECT, - UNKNOWN_METHOD, - NOT_IMPLEMENTED, - INVALID_PARAMETER, - FEATURE_NOT_IMPLEMENTED, - FORBIDDEN, - EXCEPTION, - UNKNOWN_PACKAGE, - UNKNOWN_CLASS; + + @Override + public String getType() + { + return MemoryMessageStore.TYPE; + } + + @Override + public MessageStore createMessageStore() + { + return new MemoryMessageStore(); + } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java new file mode 100644 index 0000000000..0d5a4850f6 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java @@ -0,0 +1,66 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.store; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.plugin.QpidServiceLoader; + +public class MessageStoreCreator +{ + private Map<String, MessageStoreFactory> _factories = new HashMap<String, MessageStoreFactory>(); + + public MessageStoreCreator() + { + QpidServiceLoader<MessageStoreFactory> qpidServiceLoader = new QpidServiceLoader<MessageStoreFactory>(); + Iterable<MessageStoreFactory> factories = qpidServiceLoader.atLeastOneInstanceOf(MessageStoreFactory.class); + for (MessageStoreFactory messageStoreFactory : factories) + { + String type = messageStoreFactory.getType(); + MessageStoreFactory factory = _factories.put(type.toLowerCase(), messageStoreFactory); + if (factory != null) + { + throw new IllegalStateException("MessageStoreFactory with type name '" + type + + "' is already registered using class '" + factory.getClass().getName() + "', can not register class '" + + messageStoreFactory.getClass().getName() + "'"); + } + } + } + + public MessageStore createMessageStore(String storeType) + { + MessageStoreFactory factory = _factories.get(storeType.toLowerCase()); + if (factory == null) + { + throw new IllegalConfigurationException("Unknown store type: " + storeType); + } + return factory.createMessageStore(); + } + + public Collection<MessageStoreFactory> getFactories() + { + return Collections.unmodifiableCollection(_factories.values()); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventSeverity.java b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreFactory.java index 9f9c832732..a1afd02f12 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventSeverity.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreFactory.java @@ -18,16 +18,11 @@ * under the License. * */ -package org.apache.qpid.qmf; +package org.apache.qpid.server.store; -public enum QMFEventSeverity +public interface MessageStoreFactory { - EMERGENCY, - ALERT, - CRITICAL, - ERROR, - WARN, - NOTICE, - INFORM, - DEBUG + String getType(); + + MessageStore createMessageStore(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java index be08e309e6..c6bffbc1de 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java @@ -24,8 +24,6 @@ import org.apache.qpid.AMQStoreException; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.federation.Bridge; -import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.queue.AMQQueue; public abstract class NullMessageStore implements MessageStore @@ -78,26 +76,6 @@ public abstract class NullMessageStore implements MessageStore } @Override - public void createBrokerLink(final BrokerLink link) throws AMQStoreException - { - } - - @Override - public void deleteBrokerLink(final BrokerLink link) throws AMQStoreException - { - } - - @Override - public void createBridge(final Bridge bridge) throws AMQStoreException - { - } - - @Override - public void deleteBridge(final Bridge bridge) throws AMQStoreException - { - } - - @Override public void configureMessageStore(String name, MessageStoreRecoveryHandler recoveryHandler, TransactionLogRecoveryHandler tlogRecoveryHandler, Configuration config) throws Exception diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/State.java b/java/broker/src/main/java/org/apache/qpid/server/store/State.java index 2783637b2a..1d0936cec4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/store/State.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/State.java @@ -20,8 +20,6 @@ */ package org.apache.qpid.server.store; -import org.apache.qpid.server.configuration.ConfiguredObject; - public enum State { /** The initial state of the store. In practice, the store immediately transitions to the subsequent states. */ @@ -30,7 +28,7 @@ public enum State INITIALISING, /** * The initial set-up of the store has completed. - * If the store is persistent, it has not yet loaded configuration for {@link ConfiguredObject}'s from disk. + * If the store is persistent, it has not yet loaded configuration from disk. * * From the point of view of the user, the store is essentially stopped. */ diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java index 154d7e6535..e9946d1860 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java @@ -23,7 +23,6 @@ package org.apache.qpid.server.store.derby; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.IOException; @@ -41,7 +40,6 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; @@ -55,12 +53,9 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.federation.Bridge; -import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.message.EnqueableMessage; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.store.ConfigurationRecoveryHandler; -import org.apache.qpid.server.store.ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler; import org.apache.qpid.server.store.ConfiguredObjectHelper; import org.apache.qpid.server.store.ConfiguredObjectRecord; import org.apache.qpid.server.store.Event; @@ -236,7 +231,7 @@ public class DerbyMessageStore implements MessageStore private static final String DERBY_SINGLE_DB_SHUTDOWN_CODE = "08006"; - private static final String DERBY_STORE_TYPE = "DERBY"; + public static final String TYPE = "DERBY"; private final StateManager _stateManager; @@ -572,8 +567,7 @@ public class DerbyMessageStore implements MessageStore BindingRecoveryHandler brh = qrh.completeQueueRecovery(); _configuredObjectHelper.recoverBindings(brh, configuredObjects); - BrokerLinkRecoveryHandler lrh = brh.completeBindingRecovery(); - recoverBrokerLinks(lrh); + brh.completeBindingRecovery(); } catch (SQLException e) { @@ -581,144 +575,6 @@ public class DerbyMessageStore implements MessageStore } } - private void recoverBrokerLinks(final ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler lrh) - throws SQLException - { - _logger.info("Recovering broker links..."); - - Connection conn = null; - try - { - conn = newAutoCommitConnection(); - - PreparedStatement stmt = conn.prepareStatement(SELECT_ALL_FROM_LINKS); - - try - { - ResultSet rs = stmt.executeQuery(); - - try - { - - while(rs.next()) - { - UUID id = new UUID(rs.getLong(2), rs.getLong(1)); - long createTime = rs.getLong(3); - Blob argumentsAsBlob = rs.getBlob(4); - - byte[] dataAsBytes = argumentsAsBlob.getBytes(1,(int) argumentsAsBlob.length()); - - DataInputStream dis = new DataInputStream(new ByteArrayInputStream(dataAsBytes)); - int size = dis.readInt(); - - Map<String,String> arguments = new HashMap<String, String>(); - - for(int i = 0; i < size; i++) - { - arguments.put(dis.readUTF(), dis.readUTF()); - } - - ConfigurationRecoveryHandler.BridgeRecoveryHandler brh = lrh.brokerLink(id, createTime, arguments); - - recoverBridges(brh, id); - - } - } - catch (IOException e) - { - throw new SQLException(e.getMessage(), e); - } - finally - { - rs.close(); - } - } - finally - { - stmt.close(); - } - - } - finally - { - if(conn != null) - { - conn.close(); - } - } - - } - - private void recoverBridges(final ConfigurationRecoveryHandler.BridgeRecoveryHandler brh, final UUID linkId) - throws SQLException - { - _logger.info("Recovering bridges for link " + linkId + "..."); - - Connection conn = null; - try - { - conn = newAutoCommitConnection(); - - PreparedStatement stmt = conn.prepareStatement(SELECT_ALL_FROM_BRIDGES); - - try - { - stmt.setLong(1, linkId.getLeastSignificantBits()); - stmt.setLong(2, linkId.getMostSignificantBits()); - - ResultSet rs = stmt.executeQuery(); - - try - { - - while(rs.next()) - { - UUID id = new UUID(rs.getLong(2), rs.getLong(1)); - long createTime = rs.getLong(3); - Blob argumentsAsBlob = rs.getBlob(6); - - byte[] dataAsBytes = argumentsAsBlob.getBytes(1,(int) argumentsAsBlob.length()); - - DataInputStream dis = new DataInputStream(new ByteArrayInputStream(dataAsBytes)); - int size = dis.readInt(); - - Map<String,String> arguments = new HashMap<String, String>(); - - for(int i = 0; i < size; i++) - { - arguments.put(dis.readUTF(), dis.readUTF()); - } - - brh.bridge(id, createTime, arguments); - - } - brh.completeBridgeRecoveryForLink(); - } - catch (IOException e) - { - throw new SQLException(e.getMessage(), e); - } - finally - { - rs.close(); - } - } - finally - { - stmt.close(); - } - - } - finally - { - if(conn != null) - { - conn.close(); - } - } - - } - @Override public void close() throws Exception { @@ -975,71 +831,6 @@ public class DerbyMessageStore implements MessageStore } } - @Override - public void createBrokerLink(final BrokerLink link) throws AMQStoreException - { - _logger.debug("public void createBrokerLink(BrokerLink = " + link + "): called"); - - if (_stateManager.isInState(State.ACTIVE)) - { - try - { - Connection conn = newAutoCommitConnection(); - - PreparedStatement stmt = conn.prepareStatement(FIND_LINK); - try - { - - stmt.setLong(1, link.getQMFId().getLeastSignificantBits()); - stmt.setLong(2, link.getQMFId().getMostSignificantBits()); - ResultSet rs = stmt.executeQuery(); - try - { - - // If we don't have any data in the result set then we can add this queue - if (!rs.next()) - { - PreparedStatement insertStmt = conn.prepareStatement(INSERT_INTO_LINKS); - - try - { - - insertStmt.setLong(1, link.getQMFId().getLeastSignificantBits()); - insertStmt.setLong(2, link.getQMFId().getMostSignificantBits()); - insertStmt.setLong(3, link.getCreateTime()); - - byte[] argumentBytes = convertStringMapToBytes(link.getArguments()); - ByteArrayInputStream bis = new ByteArrayInputStream(argumentBytes); - - insertStmt.setBinaryStream(4,bis,argumentBytes.length); - - insertStmt.execute(); - } - finally - { - insertStmt.close(); - } - } - } - finally - { - rs.close(); - } - } - finally - { - stmt.close(); - } - conn.close(); - - } - catch (SQLException e) - { - throw new AMQStoreException("Error writing " + link + " to database: " + e.getMessage(), e); - } - } - } - private byte[] convertStringMapToBytes(final Map<String, String> arguments) throws AMQStoreException { byte[] argumentBytes; @@ -1072,139 +863,7 @@ public class DerbyMessageStore implements MessageStore return argumentBytes; } - @Override - public void deleteBrokerLink(final BrokerLink link) throws AMQStoreException - { - _logger.debug("public void deleteBrokerLink( " + link + "): called"); - Connection conn = null; - PreparedStatement stmt = null; - try - { - conn = newAutoCommitConnection(); - stmt = conn.prepareStatement(DELETE_FROM_LINKS); - stmt.setLong(1, link.getQMFId().getLeastSignificantBits()); - stmt.setLong(2, link.getQMFId().getMostSignificantBits()); - int results = stmt.executeUpdate(); - - if (results == 0) - { - throw new AMQStoreException("Link " + link + " not found"); - } - } - catch (SQLException e) - { - throw new AMQStoreException("Error deleting Link " + link + " from database: " + e.getMessage(), e); - } - finally - { - closePreparedStatement(stmt); - closeConnection(conn); - } - - - } - - @Override - public void createBridge(final Bridge bridge) throws AMQStoreException - { - _logger.debug("public void createBridge(BrokerLink = " + bridge + "): called"); - if (_stateManager.isInState(State.ACTIVE)) - { - try - { - Connection conn = newAutoCommitConnection(); - - PreparedStatement stmt = conn.prepareStatement(FIND_BRIDGE); - try - { - - UUID id = bridge.getQMFId(); - stmt.setLong(1, id.getLeastSignificantBits()); - stmt.setLong(2, id.getMostSignificantBits()); - ResultSet rs = stmt.executeQuery(); - try - { - - // If we don't have any data in the result set then we can add this queue - if (!rs.next()) - { - PreparedStatement insertStmt = conn.prepareStatement(INSERT_INTO_BRIDGES); - - try - { - - insertStmt.setLong(1, id.getLeastSignificantBits()); - insertStmt.setLong(2, id.getMostSignificantBits()); - - insertStmt.setLong(3, bridge.getCreateTime()); - - UUID linkId = bridge.getLink().getQMFId(); - insertStmt.setLong(4, linkId.getLeastSignificantBits()); - insertStmt.setLong(5, linkId.getMostSignificantBits()); - - byte[] argumentBytes = convertStringMapToBytes(bridge.getArguments()); - ByteArrayInputStream bis = new ByteArrayInputStream(argumentBytes); - - insertStmt.setBinaryStream(6,bis,argumentBytes.length); - - insertStmt.execute(); - } - finally - { - insertStmt.close(); - } - } - } - finally - { - rs.close(); - } - } - finally - { - stmt.close(); - } - conn.close(); - - } - catch (SQLException e) - { - throw new AMQStoreException("Error writing " + bridge + " to database: " + e.getMessage(), e); - } - } - } - - @Override - public void deleteBridge(final Bridge bridge) throws AMQStoreException - { - _logger.debug("public void deleteBridge( " + bridge + "): called"); - Connection conn = null; - PreparedStatement stmt = null; - try - { - conn = newAutoCommitConnection(); - stmt = conn.prepareStatement(DELETE_FROM_BRIDGES); - stmt.setLong(1, bridge.getQMFId().getLeastSignificantBits()); - stmt.setLong(2, bridge.getQMFId().getMostSignificantBits()); - int results = stmt.executeUpdate(); - - if (results == 0) - { - throw new AMQStoreException("Bridge " + bridge + " not found"); - } - } - catch (SQLException e) - { - throw new AMQStoreException("Error deleting bridge " + bridge + " from database: " + e.getMessage(), e); - } - finally - { - closePreparedStatement(stmt); - closeConnection(conn); - } - - } @Override public Transaction newTransaction() @@ -2134,8 +1793,9 @@ public class DerbyMessageStore implements MessageStore public ByteBuffer getContent(int offsetInMessage, int size) { ByteBuffer buf = ByteBuffer.allocate(size); - getContent(offsetInMessage, buf); + int length = getContent(offsetInMessage, buf); buf.position(0); + buf.limit(length); return buf; } @@ -2673,7 +2333,7 @@ public class DerbyMessageStore implements MessageStore @Override public String getStoreType() { - return DERBY_STORE_TYPE; + return TYPE; } }
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFType.java b/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStoreFactory.java index 0e01c27db5..046b503d8a 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFType.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStoreFactory.java @@ -18,36 +18,24 @@ * under the License. * */ -package org.apache.qpid.qmf; +package org.apache.qpid.server.store.derby; -public enum QMFType +import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.store.MessageStoreFactory; + +public class DerbyMessageStoreFactory implements MessageStoreFactory { - UINT8, - UINT16, - UINT32, - UINT64, - UNKNOWN, - STR8, - STR16, - ABSTIME, - DELTATIME, - OBJECTREFERENCE, - BOOLEAN, - FLOAT, - DOUBLE, - UUID, - MAP, - INT8, - INT16, - INT32, - INT64, - OBJECT, - LIST, - ARRAY; + @Override + public String getType() + { + return DerbyMessageStore.TYPE; + } - public int codeValue() + @Override + public MessageStore createMessageStore() { - return ordinal()+1; + return new DerbyMessageStore(); } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java b/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java index c92853e400..6c5cb2e721 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java +++ b/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java @@ -27,11 +27,6 @@ import org.apache.qpid.common.AMQPFilterTypes; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.SessionConfig; -import org.apache.qpid.server.configuration.SubscriptionConfig; -import org.apache.qpid.server.configuration.SubscriptionConfigType; import org.apache.qpid.server.filter.FilterManager; import org.apache.qpid.server.filter.FilterManagerFactory; import org.apache.qpid.server.flow.FlowCreditManager; @@ -61,8 +56,7 @@ import java.util.concurrent.locks.ReentrantLock; * Encapsulation of a supscription to a queue. <p/> Ties together the protocol session of a subscriber, the consumer tag * that was given out by the broker and the channel id. <p/> */ -public abstract class SubscriptionImpl implements Subscription, FlowCreditManager.FlowCreditManagerListener, - SubscriptionConfig +public abstract class SubscriptionImpl implements Subscription, FlowCreditManager.FlowCreditManagerListener { private StateListener _stateListener = new StateListener() @@ -91,7 +85,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage private final long _subscriptionID; private LogSubject _logSubject; private LogActor _logActor; - private UUID _qmfId; private final AtomicLong _deliveredCount = new AtomicLong(0); private final AtomicLong _deliveredBytes = new AtomicLong(0); @@ -373,11 +366,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage return _channel; } - public ConfigStore getConfigStore() - { - return getQueue().getConfigStore(); - } - public Long getDelivered() { return _deliveredCount.get(); @@ -391,9 +379,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage } _queue = queue; - _qmfId = getConfigStore().createId(); - getConfigStore().addConfiguredObject(this); - _logSubject = new SubscriptionLogSubject(this); _logActor = new SubscriptionActor(CurrentActor.get().getRootMessageLogger(), this); @@ -547,8 +532,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage { _stateChangeLock.unlock(); } - getConfigStore().removeConfiguredObject(this); - //Log Subscription closed CurrentActor.get().message(_logSubject, SubscriptionMessages.CLOSE()); } @@ -752,11 +735,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage return "WINDOW"; } - public SessionConfig getSessionConfig() - { - return getChannel(); - } - public boolean isBrowsing() { return isBrowser(); @@ -767,32 +745,16 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage return true; } - @Override - public UUID getQMFId() - { - return _qmfId; - } - public boolean isDurable() { return false; } - public SubscriptionConfigType getConfigType() - { - return SubscriptionConfigType.getInstance(); - } - public boolean isExclusive() { return getQueue().hasExclusiveSubscriber(); } - public ConfiguredObject getParent() - { - return getSessionConfig(); - } - public String getName() { return String.valueOf(_consumerTag); diff --git a/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java b/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java index dfd9315226..b9bba49fab 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java +++ b/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java @@ -24,11 +24,6 @@ import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.BasicContentHeaderProperties; import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.SessionConfig; -import org.apache.qpid.server.configuration.SubscriptionConfig; -import org.apache.qpid.server.configuration.SubscriptionConfigType; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.filter.FilterManager; import org.apache.qpid.server.flow.CreditCreditManager; @@ -86,7 +81,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCreditManagerListener, SubscriptionConfig, LogSubject +public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCreditManagerListener, LogSubject { private final long _subscriptionID; @@ -125,7 +120,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr private LogActor _logActor; private final Map<String, Object> _properties = new ConcurrentHashMap<String, Object>(); - private UUID _qmfId; private String _traceExclude; private String _trace; private final long _createTime = System.currentTimeMillis(); @@ -192,8 +186,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr Map<String, Object> arguments = queue.getArguments(); _traceExclude = (String) arguments.get("qpid.trace.exclude"); _trace = (String) arguments.get("qpid.trace.id"); - _qmfId = getConfigStore().createId(); - getConfigStore().addConfiguredObject(this); String filterLogString = null; _logActor = GenericActor.getInstance(this); @@ -283,7 +275,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr } } _creditManager.removeListener(this); - getConfigStore().removeConfiguredObject(this); CurrentActor.get().message(getLogSubject(), SubscriptionMessages.CLOSE()); } finally @@ -295,11 +286,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr } - public ConfigStore getConfigStore() - { - return getQueue().getConfigStore(); - } - public Long getDelivered() { return _deliveredCount.get(); @@ -970,12 +956,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr return _session; } - - public SessionConfig getSessionConfig() - { - return getSessionModel(); - } - public boolean isBrowsing() { return _acquireMode == MessageAcquireMode.NOT_ACQUIRED; @@ -986,20 +966,11 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr return getQueue().hasExclusiveSubscriber(); } - public ConfiguredObject getParent() - { - return getSessionConfig(); - } - public boolean isDurable() { return false; } - public SubscriptionConfigType getConfigType() - { - return SubscriptionConfigType.getInstance(); - } public boolean isExplicitAcknowledge() { @@ -1011,12 +982,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr return _flowMode.toString(); } - @Override - public UUID getQMFId() - { - return _qmfId; - } - public String getName() { return _destination; diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java b/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java deleted file mode 100644 index 7c4188bfcd..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * 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.transport; - -import org.apache.qpid.server.protocol.AmqpProtocolVersion; -import org.apache.qpid.transport.network.NetworkTransport; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -public class QpidAcceptor -{ - public enum Transport - { - TCP("TCP"), - SSL("TCP/SSL"); - - private final String _asString; - - Transport(String asString) - { - _asString = asString; - } - - public String toString() - { - return _asString; - } - } - - private NetworkTransport _networkTransport; - private Transport _transport; - private Set<AmqpProtocolVersion> _supported; - - - public QpidAcceptor(NetworkTransport transport, Transport protocol, Set<AmqpProtocolVersion> supported) - { - _networkTransport = transport; - _transport = protocol; - _supported = Collections.unmodifiableSet(new HashSet<AmqpProtocolVersion>(supported)); - } - - public NetworkTransport getNetworkTransport() - { - return _networkTransport; - } - - public Transport getTransport() - { - return _transport; - } - - public Set<AmqpProtocolVersion> getSupported() - { - return _supported; - } - - public String toString() - { - return _transport.toString(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java index f21026794f..58de6a0cdf 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java +++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java @@ -20,17 +20,16 @@ */ package org.apache.qpid.server.transport; +import java.net.SocketAddress; import java.security.Principal; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; -import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import javax.security.auth.Subject; import org.apache.qpid.AMQException; import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.server.configuration.ConnectionConfig; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.actors.CurrentActor; @@ -39,6 +38,7 @@ import org.apache.qpid.server.logging.messages.ConnectionMessages; import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.security.AuthorizationHolder; +import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; import org.apache.qpid.server.stats.StatisticsCounter; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.Connection; @@ -48,6 +48,7 @@ import org.apache.qpid.transport.ExecutionException; import org.apache.qpid.transport.Method; import org.apache.qpid.transport.ProtocolEvent; import org.apache.qpid.transport.Session; +import org.apache.qpid.transport.network.NetworkConnection; import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CONNECTION_FORMAT; import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.SOCKET_FORMAT; @@ -55,7 +56,6 @@ import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.USER_FORM public class ServerConnection extends Connection implements AMQConnectionModel, LogSubject, AuthorizationHolder { - private ConnectionConfig _config; private Runnable _onOpenTask; private AtomicBoolean _logClosed = new AtomicBoolean(false); private LogActor _actor = GenericActor.getInstance(this); @@ -69,6 +69,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel, private AtomicLong _lastIoTime = new AtomicLong(); private boolean _blocking; private Principal _peerPrincipal; + private NetworkConnection _networkConnection; public ServerConnection(final long connectionId) { @@ -147,16 +148,6 @@ public class ServerConnection extends Connection implements AMQConnectionModel, initialiseStatistics(); } - public void setConnectionConfig(final ConnectionConfig config) - { - _config = config; - } - - public ConnectionConfig getConfig() - { - return _config; - } - public void onOpen(final Runnable task) { _onOpenTask = task; @@ -228,7 +219,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel, MessageFormat.format(CONNECTION_FORMAT, getConnectionId(), getClientId(), - getConfig().getAddress(), + getRemoteAddressString(), getVirtualHost().getName()) + "] "; } @@ -238,7 +229,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel, MessageFormat.format(USER_FORMAT, getConnectionId(), getClientId(), - getConfig().getAddress()) + getRemoteAddressString()) + "] "; } @@ -247,7 +238,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel, return "[" + MessageFormat.format(SOCKET_FORMAT, getConnectionId(), - getConfig().getAddress()) + getRemoteAddressString()) + "] "; } } @@ -396,7 +387,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel, else { _authorizedSubject = authorizedSubject; - _authorizedPrincipal = authorizedSubject.getPrincipals().iterator().next(); + _authorizedPrincipal = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(authorizedSubject); } } @@ -417,7 +408,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel, public String getRemoteAddressString() { - return getConfig().getAddress(); + return String.valueOf(getRemoteAddress()); } public String getUserName() @@ -489,4 +480,32 @@ public class ServerConnection extends Connection implements AMQConnectionModel, { _peerPrincipal = peerPrincipal; } + + @Override + public void setRemoteAddress(SocketAddress remoteAddress) + { + super.setRemoteAddress(remoteAddress); + } + + @Override + public void setLocalAddress(SocketAddress localAddress) + { + super.setLocalAddress(localAddress); + } + + public void setNetworkConnection(NetworkConnection network) + { + _networkConnection = network; + } + + public NetworkConnection getNetworkConnection() + { + return _networkConnection; + } + + public void doHeartbeat() + { + super.doHeartBeat(); + + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java index c13f63b44d..f3153fde62 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java +++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java @@ -32,18 +32,19 @@ import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import org.apache.qpid.common.ServerPropertyNames; import org.apache.qpid.properties.ConnectionStartProperties; -import org.apache.qpid.protocol.ProtocolEngine; -import org.apache.qpid.server.configuration.BrokerConfig; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.protocol.AMQConnectionModel; -import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.security.SecurityManager; -import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; import org.apache.qpid.server.subscription.Subscription_0_10; import org.apache.qpid.server.virtualhost.State; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.*; +import org.apache.qpid.transport.network.NetworkConnection; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,36 +54,49 @@ public class ServerConnectionDelegate extends ServerDelegate { private static final Logger LOGGER = LoggerFactory.getLogger(ServerConnectionDelegate.class); + private final Broker _broker; private final String _localFQDN; - private final IApplicationRegistry _appRegistry; private int _maxNoOfChannels; private Map<String,Object> _clientProperties; - private final AuthenticationManager _authManager; + private final SubjectCreator _subjectCreator; - public ServerConnectionDelegate(IApplicationRegistry appRegistry, String localFQDN, AuthenticationManager authManager) + public ServerConnectionDelegate(Broker broker, String localFQDN, SubjectCreator subjectCreator) { - this(createConnectionProperties(appRegistry.getBrokerConfig()), Collections.singletonList((Object)"en_US"), appRegistry, localFQDN, authManager); + this(createConnectionProperties(broker), Collections.singletonList((Object)"en_US"), broker, localFQDN, subjectCreator); } private ServerConnectionDelegate(Map<String, Object> properties, List<Object> locales, - IApplicationRegistry appRegistry, + Broker broker, String localFQDN, - AuthenticationManager authManager) + SubjectCreator subjectCreator) { - super(properties, parseToList(authManager.getMechanisms()), locales); + super(properties, parseToList(subjectCreator.getMechanisms()), locales); - _appRegistry = appRegistry; + _broker = broker; _localFQDN = localFQDN; - _maxNoOfChannels = appRegistry.getConfiguration().getMaxChannelCount(); - _authManager = authManager; + _maxNoOfChannels = (Integer)broker.getAttribute(Broker.SESSION_COUNT_LIMIT); + _subjectCreator = subjectCreator; + } + + private static List<String> getFeatures(Broker broker) + { + String brokerDisabledFeatures = System.getProperty(BrokerProperties.PROPERTY_DISABLED_FEATURES); + final List<String> features = new ArrayList<String>(); + if (brokerDisabledFeatures == null || !brokerDisabledFeatures.contains(ServerPropertyNames.FEATURE_QPID_JMS_SELECTOR)) + { + features.add(ServerPropertyNames.FEATURE_QPID_JMS_SELECTOR); + } + + return Collections.unmodifiableList(features); } - private static Map<String, Object> createConnectionProperties(final BrokerConfig brokerConfig) + private static Map<String, Object> createConnectionProperties(final Broker broker) { final Map<String,Object> map = new HashMap<String,Object>(2); - map.put(ServerPropertyNames.FEDERATION_TAG, brokerConfig.getFederationTag()); - final List<String> features = brokerConfig.getFeatures(); + // Federation tag is used by the client to identify the broker instance + map.put(ServerPropertyNames.FEDERATION_TAG, broker.getId().toString()); + final List<String> features = getFeatures(broker); if (features != null && features.size() > 0) { map.put(ServerPropertyNames.QPID_FEATURES, features); @@ -112,14 +126,14 @@ public class ServerConnectionDelegate extends ServerDelegate protected SaslServer createSaslServer(Connection conn, String mechanism) throws SaslException { - return _authManager.createSaslServer(mechanism, _localFQDN, ((ServerConnection) conn).getPeerPrincipal()); + return _subjectCreator.createSaslServer(mechanism, _localFQDN, ((ServerConnection) conn).getPeerPrincipal()); } protected void secure(final SaslServer ss, final Connection conn, final byte[] response) { final ServerConnection sconn = (ServerConnection) conn; - final AuthenticationResult authResult = _authManager.authenticate(ss, response); + final SubjectAuthenticationResult authResult = _subjectCreator.authenticate(ss, response); if (AuthenticationStatus.SUCCESS.equals(authResult.getStatus())) { @@ -166,7 +180,7 @@ public class ServerConnectionDelegate extends ServerDelegate { vhostName = ""; } - vhost = _appRegistry.getVirtualHostRegistry().getVirtualHost(vhostName); + vhost = _broker.getVirtualHostRegistry().getVirtualHost(vhostName); SecurityManager.setThreadSubject(sconn.getAuthorizedSubject()); @@ -174,7 +188,7 @@ public class ServerConnectionDelegate extends ServerDelegate { sconn.setVirtualHost(vhost); - if (!vhost.getSecurityManager().accessVirtualhost(vhostName, ((ProtocolEngine) sconn.getConfig()).getRemoteAddress())) + if (!vhost.getSecurityManager().accessVirtualhost(vhostName, sconn.getRemoteAddress())) { sconn.setState(Connection.State.CLOSING); sconn.invoke(new ConnectionClose(ConnectionCloseCode.CONNECTION_FORCED, "Permission denied '"+vhostName+"'")); @@ -215,14 +229,18 @@ public class ServerConnectionDelegate extends ServerDelegate return; } - setConnectionTuneOkChannelMax(sconn, okChannelMax); - } + if(ok.hasHeartbeat()) + { + final int heartbeat = ok.getHeartbeat(); + if(heartbeat > 0) + { + final NetworkConnection networkConnection = sconn.getNetworkConnection(); + networkConnection.setMaxReadIdle(2 * heartbeat); + networkConnection.setMaxWriteIdle(heartbeat); + } + } - @Override - protected int getHeartbeatMax() - { - //TODO: implement broker support for actually sending heartbeats - return 0; + setConnectionTuneOkChannelMax(sconn, okChannelMax); } @Override diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java index f82b25b3d6..6152ddd228 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java +++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java @@ -42,13 +42,8 @@ import javax.security.auth.Subject; import org.apache.qpid.AMQException; import org.apache.qpid.AMQStoreException; import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.protocol.ProtocolEngine; import org.apache.qpid.server.TransactionTimeoutHelper; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.ConnectionConfig; -import org.apache.qpid.server.configuration.SessionConfig; -import org.apache.qpid.server.configuration.SessionConfigType; +import org.apache.qpid.server.TransactionTimeoutHelper.CloseAction; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.actors.CurrentActor; @@ -91,7 +86,7 @@ import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_F import static org.apache.qpid.util.Serial.gt; public class ServerSession extends Session - implements AuthorizationHolder, SessionConfig, + implements AuthorizationHolder, AMQSessionModel, LogSubject, AsyncAutoCommitTransaction.FutureRecorder { private static final Logger _logger = LoggerFactory.getLogger(ServerSession.class); @@ -100,8 +95,7 @@ public class ServerSession extends Session private static final int PRODUCER_CREDIT_TOPUP_THRESHOLD = 1 << 30; private static final int UNFINISHED_COMMAND_QUEUE_THRESHOLD = 500; - private final UUID _id; - private ConnectionConfig _connectionConfig; + private final UUID _id = UUID.randomUUID(); private long _createTime = System.currentTimeMillis(); private LogActor _actor = GenericActor.getInstance(this); @@ -139,7 +133,6 @@ public class ServerSession extends Session private final AtomicLong _txnCommits = new AtomicLong(0); private final AtomicLong _txnRejects = new AtomicLong(0); private final AtomicLong _txnCount = new AtomicLong(0); - private final AtomicLong _txnUpdateTime = new AtomicLong(0); private Map<String, Subscription_0_10> _subscriptions = new ConcurrentHashMap<String, Subscription_0_10>(); @@ -147,21 +140,21 @@ public class ServerSession extends Session private final TransactionTimeoutHelper _transactionTimeoutHelper; - ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry) - { - this(connection, delegate, name, expiry, ((ServerConnection)connection).getConfig()); - } - public ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry, ConnectionConfig connConfig) + public ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry) { super(connection, delegate, name, expiry); - _connectionConfig = connConfig; _transaction = new AsyncAutoCommitTransaction(this.getMessageStore(),this); _logSubject = new ChannelLogSubject(this); - _id = getConfigStore().createId(); - getConfigStore().addConfiguredObject(this); - _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject); + _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject, new CloseAction() + { + @Override + public void doTimeoutAction(String reason) throws AMQException + { + getConnectionModel().closeSession(ServerSession.this, AMQConstant.RESOURCE_ERROR, reason); + } + }); } protected void setState(State state) @@ -184,12 +177,6 @@ public class ServerSession extends Session invoke(new MessageStop("")); } - private ConfigStore getConfigStore() - { - return getConnectionConfig().getConfigStore(); - } - - @Override protected boolean isFull(int id) { @@ -206,9 +193,8 @@ public class ServerSession extends Session } getConnectionModel().registerMessageReceived(message.getSize(), message.getArrivalTime()); PostEnqueueAction postTransactionAction = new PostEnqueueAction(queues, message, isTransactional()) ; - _transaction.enqueue(queues,message, postTransactionAction, 0L); + _transaction.enqueue(queues,message, postTransactionAction); incrementOutstandingTxnsIfNecessary(); - updateTransactionalActivity(); } @@ -389,8 +375,6 @@ public class ServerSession extends Session } _messageDispositionListenerMap.clear(); - getConfigStore().removeConfiguredObject(this); - for (Task task : _taskList) { task.doTask(this); @@ -424,7 +408,6 @@ public class ServerSession extends Session entry.release(); } }); - updateTransactionalActivity(); } public Collection<Subscription_0_10> getSubscriptions() @@ -470,11 +453,6 @@ public class ServerSession extends Session return _transaction.isTransactional(); } - public boolean inTransaction() - { - return isTransactional() && _txnUpdateTime.get() > 0 && _transaction.getTransactionStartTime() > 0; - } - public void selectTx() { _transaction = new LocalTransaction(this.getMessageStore()); @@ -609,22 +587,6 @@ public class ServerSession extends Session } } - /** - * Update last transaction activity timestamp - */ - public void updateTransactionalActivity() - { - if (isTransactional()) - { - _txnUpdateTime.set(System.currentTimeMillis()); - } - } - - public Long getTxnStarts() - { - return _txnStarts.get(); - } - public Long getTxnCommits() { return _txnCommits.get(); @@ -682,23 +644,7 @@ public class ServerSession extends Session public VirtualHost getVirtualHost() { - return (VirtualHost) _connectionConfig.getVirtualHost(); - } - - @Override - public UUID getQMFId() - { - return _id; - } - - public SessionConfigType getConfigType() - { - return SessionConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getVirtualHost(); + return getConnection().getVirtualHost(); } public boolean isDurable() @@ -706,44 +652,16 @@ public class ServerSession extends Session return false; } - public boolean isAttached() - { - return true; - } - - public long getDetachedLifespan() - { - return 0; - } - - public Long getExpiryTime() - { - return null; - } - - public Long getMaxClientRate() - { - return null; - } - - public ConnectionConfig getConnectionConfig() - { - return _connectionConfig; - } - - public String getSessionName() - { - return getName().toString(); - } public long getCreateTime() { return _createTime; } - public void mgmtClose() + @Override + public UUID getId() { - close(); + return _id; } public AMQConnectionModel getConnectionModel() @@ -774,28 +692,7 @@ public class ServerSession extends Session public void checkTransactionStatus(long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException { - if (inTransaction()) - { - long currentTime = System.currentTimeMillis(); - long openTime = currentTime - _transaction.getTransactionStartTime(); - long idleTime = currentTime - _txnUpdateTime.get(); - - _transactionTimeoutHelper.logIfNecessary(idleTime, idleWarn, ChannelMessages.IDLE_TXN(idleTime), - TransactionTimeoutHelper.IDLE_TRANSACTION_ALERT); - if (_transactionTimeoutHelper.isTimedOut(idleTime, idleClose)) - { - getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Idle transaction timed out"); - return; - } - - _transactionTimeoutHelper.logIfNecessary(openTime, openWarn, ChannelMessages.OPEN_TXN(openTime), - TransactionTimeoutHelper.OPEN_TRANSACTION_ALERT); - if (_transactionTimeoutHelper.isTimedOut(openTime, openClose)) - { - getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Open transaction timed out"); - return; - } - } + _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, openWarn, openClose, idleWarn, idleClose); } public void block(AMQQueue queue) @@ -878,9 +775,7 @@ public class ServerSession extends Session ? getConnection().getConnectionId() : -1; - String remoteAddress = _connectionConfig instanceof ProtocolEngine - ? ((ProtocolEngine) _connectionConfig).getRemoteAddress().toString() - : ""; + String remoteAddress = String.valueOf(getConnection().getRemoteAddress()); return "[" + MessageFormat.format(CHANNEL_FORMAT, connectionId, @@ -1065,14 +960,16 @@ public class ServerSession extends Session super.setClose(close); } - public int compareTo(AMQSessionModel session) + @Override + public int getConsumerCount() { - return getQMFId().compareTo(session.getQMFId()); + return _subscriptions.values().size(); } @Override - public int getConsumerCount() + public int compareTo(AMQSessionModel o) { - return _subscriptions.values().size(); + return getId().compareTo(o.getId()); } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java index 05963ee874..d83bd1c4dc 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java +++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java @@ -31,7 +31,6 @@ import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.exchange.ExchangeInUseException; import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.exchange.ExchangeType; import org.apache.qpid.server.exchange.HeadersExchange; import org.apache.qpid.server.filter.FilterManager; import org.apache.qpid.server.filter.FilterManagerFactory; @@ -41,11 +40,11 @@ import org.apache.qpid.server.logging.messages.ExchangeMessages; import org.apache.qpid.server.message.MessageMetaData_0_10; import org.apache.qpid.server.message.MessageTransferMessage; import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.security.SecurityManager; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.MessageStore; @@ -1266,18 +1265,12 @@ public class ServerSessionDelegate extends SessionDelegate } } queueRegistry.registerQueue(queue); - boolean autoRegister = ApplicationRegistry.getInstance().getConfiguration().getQueueAutoRegister(); - if (autoRegister) - { - - ExchangeRegistry exchangeRegistry = getExchangeRegistry(session); + ExchangeRegistry exchangeRegistry = getExchangeRegistry(session); - Exchange defaultExchange = exchangeRegistry.getDefaultExchange(); + Exchange defaultExchange = exchangeRegistry.getDefaultExchange(); - virtualHost.getBindingFactory().addBinding(queueName, queue, defaultExchange, null); - - } + virtualHost.getBindingFactory().addBinding(queueName, queue, defaultExchange, null); if (method.hasAutoDelete() && method.getAutoDelete() diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java index efd7850a49..43e60c8e13 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java @@ -66,11 +66,18 @@ public class AsyncAutoCommitTransaction implements ServerTransaction _futureRecorder = recorder; } + @Override public long getTransactionStartTime() { return 0L; } + @Override + public long getTransactionUpdateTime() + { + return 0L; + } + /** * Since AutoCommitTransaction have no concept of a long lived transaction, any Actions registered * by the caller are executed immediately. @@ -241,7 +248,7 @@ public class AsyncAutoCommitTransaction implements ServerTransaction } - public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime) + public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction) { Transaction txn = null; try diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java index e5a7df6880..8a9479a2d4 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java @@ -52,11 +52,18 @@ public class AutoCommitTransaction implements ServerTransaction _messageStore = transactionLog; } + @Override public long getTransactionStartTime() { return 0L; } + @Override + public long getTransactionUpdateTime() + { + return 0L; + } + /** * Since AutoCommitTransaction have no concept of a long lived transaction, any Actions registered * by the caller are executed immediately. @@ -178,7 +185,7 @@ public class AutoCommitTransaction implements ServerTransaction } - public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime) + public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction) { Transaction txn = null; try @@ -270,4 +277,6 @@ public class AutoCommitTransaction implements ServerTransaction } } + + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java index 05d0110e9b..ab987f0fb9 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java @@ -26,7 +26,6 @@ import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.store.MessageStore; -import org.apache.qpid.server.store.Transaction; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.Xid; @@ -39,10 +38,6 @@ public class DistributedTransaction implements ServerTransaction private final AutoCommitTransaction _autoCommitTransaction; - private volatile Transaction _transaction; - - private long _txnStartTime = 0L; - private DtxBranch _branch; private AMQSessionModel _session; private VirtualHost _vhost; @@ -55,9 +50,16 @@ public class DistributedTransaction implements ServerTransaction _autoCommitTransaction = new AutoCommitTransaction(vhost.getMessageStore()); } + @Override public long getTransactionStartTime() { - return _txnStartTime; + return 0; + } + + @Override + public long getTransactionUpdateTime() + { + return 0; } public void addPostTransactionAction(Action postTransactionAction) @@ -107,7 +109,7 @@ public class DistributedTransaction implements ServerTransaction { _branch.enqueue(queue, message); _branch.addPostTransactionAcion(postTransactionAction); - enqueue(Collections.singletonList(queue), message, postTransactionAction, System.currentTimeMillis()); + enqueue(Collections.singletonList(queue), message, postTransactionAction); } else { @@ -116,7 +118,7 @@ public class DistributedTransaction implements ServerTransaction } public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, - Action postTransactionAction, long currentTime) + Action postTransactionAction) { if(_branch != null) { @@ -128,7 +130,7 @@ public class DistributedTransaction implements ServerTransaction } else { - _autoCommitTransaction.enqueue(queues, message, postTransactionAction, currentTime); + _autoCommitTransaction.enqueue(queues, message, postTransactionAction); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java index 3fbcff7e2c..afa7cb0fb4 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java @@ -49,25 +49,42 @@ public class LocalTransaction implements ServerTransaction private final List<Action> _postTransactionActions = new ArrayList<Action>(); private volatile Transaction _transaction; - private MessageStore _transactionLog; - private long _txnStartTime = 0L; + private final ActivityTimeAccessor _activityTime; + private final MessageStore _transactionLog; + private volatile long _txnStartTime = 0L; + private volatile long _txnUpdateTime = 0l; private StoreFuture _asyncTran; public LocalTransaction(MessageStore transactionLog) { - _transactionLog = transactionLog; + this(transactionLog, new ActivityTimeAccessor() + { + @Override + public long getActivityTime() + { + return System.currentTimeMillis(); + } + }); } - - public boolean inTransaction() + + public LocalTransaction(MessageStore transactionLog, ActivityTimeAccessor activityTime) { - return _transaction != null; + _transactionLog = transactionLog; + _activityTime = activityTime; } + @Override public long getTransactionStartTime() { return _txnStartTime; } + @Override + public long getTransactionUpdateTime() + { + return _txnUpdateTime; + } + public void addPostTransactionAction(Action postTransactionAction) { sync(); @@ -78,6 +95,7 @@ public class LocalTransaction implements ServerTransaction { sync(); _postTransactionActions.add(postTransactionAction); + initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime(); if(message.isPersistent() && queue.isDurable()) { @@ -104,6 +122,7 @@ public class LocalTransaction implements ServerTransaction { sync(); _postTransactionActions.add(postTransactionAction); + initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime(); try { @@ -180,6 +199,7 @@ public class LocalTransaction implements ServerTransaction { sync(); _postTransactionActions.add(postTransactionAction); + initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime(); if(message.isPersistent() && queue.isDurable()) { @@ -189,7 +209,7 @@ public class LocalTransaction implements ServerTransaction { _logger.debug("Enqueue of message number " + message.getMessageNumber() + " to transaction log. Queue : " + queue.getNameShortString()); } - + beginTranIfNecessary(); _transaction.enqueueMessage(queue, message); } @@ -202,15 +222,11 @@ public class LocalTransaction implements ServerTransaction } } - public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime) + public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction) { sync(); _postTransactionActions.add(postTransactionAction); - - if (_txnStartTime == 0L) - { - _txnStartTime = currentTime == 0L ? System.currentTimeMillis() : currentTime; - } + initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime(); if(message.isPersistent()) { @@ -224,8 +240,7 @@ public class LocalTransaction implements ServerTransaction { _logger.debug("Enqueue of message number " + message.getMessageNumber() + " to transaction log. Queue : " + queue.getNameShortString() ); } - - + beginTranIfNecessary(); _transaction.enqueueMessage(queue, message); } @@ -378,16 +393,24 @@ public class LocalTransaction implements ServerTransaction } throw new RuntimeException("Failed to commit transaction", e); } - - } private void doPostTransactionActions() { + if(_logger.isDebugEnabled()) + { + _logger.debug("Beginning " + _postTransactionActions.size() + " post transaction actions"); + } + for(int i = 0; i < _postTransactionActions.size(); i++) { _postTransactionActions.get(i).postCommit(); } + + if(_logger.isDebugEnabled()) + { + _logger.debug("Completed post transaction actions"); + } } public void rollback() @@ -427,16 +450,34 @@ public class LocalTransaction implements ServerTransaction } } + private void initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime() + { + long currentTime = _activityTime.getActivityTime(); + + if (_txnStartTime == 0) + { + _txnStartTime = currentTime; + } + _txnUpdateTime = currentTime; + } + private void resetDetails() { _asyncTran = null; _transaction = null; - _postTransactionActions.clear(); + _postTransactionActions.clear(); _txnStartTime = 0L; + _txnUpdateTime = 0; } public boolean isTransactional() { return true; } + + public interface ActivityTimeAccessor + { + long getActivityTime(); + } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java index c568ae67aa..8acac00479 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java @@ -55,11 +55,18 @@ public interface ServerTransaction /** * Return the time the current transaction started. - * + * * @return the time this transaction started or 0 if not in a transaction */ long getTransactionStartTime(); + /** + * Return the time of the last activity on the current transaction. + * + * @return the time of the last activity or 0 if not in a transaction + */ + long getTransactionUpdateTime(); + /** * Register an Action for execution after transaction commit or rollback. Actions * will be executed in the order in which they are registered. @@ -92,7 +99,7 @@ public interface ServerTransaction * * Store operations will result only for a persistent messages on durable queues. */ - void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime); + void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction); /** * Commit the transaction represented by this object. diff --git a/java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java b/java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java new file mode 100644 index 0000000000..aa7b4afcae --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java @@ -0,0 +1,361 @@ +/* + * + * 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.util; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class MapValueConverter +{ + + public static String getStringAttribute(String name, Map<String,Object> attributes, String defaultVal) + { + final Object value = attributes.get(name); + return toString(value, defaultVal); + } + + public static String toString(final Object value) + { + return toString(value, null); + } + + public static String toString(final Object value, String defaultVal) + { + if (value == null) + { + return defaultVal; + } + else if (value instanceof String) + { + return (String)value; + } + return String.valueOf(value); + } + + public static String getStringAttribute(String name, Map<String, Object> attributes) + { + assertMandatoryAttribute(name, attributes); + return getStringAttribute(name, attributes, null); + } + + private static void assertMandatoryAttribute(String name, Map<String, Object> attributes) + { + if (!attributes.containsKey(name)) + { + throw new IllegalArgumentException("Value for attribute " + name + " is not found"); + } + } + + public static Map<String,Object> getMapAttribute(String name, Map<String,Object> attributes, Map<String,Object> defaultVal) + { + final Object value = attributes.get(name); + if(value == null) + { + return defaultVal; + } + else if(value instanceof Map) + { + @SuppressWarnings("unchecked") + Map<String,Object> retVal = (Map<String,Object>) value; + return retVal; + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Map"); + } + } + + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static <E extends Enum> E getEnumAttribute(Class<E> clazz, String name, Map<String,Object> attributes, E defaultVal) + { + Object obj = attributes.get(name); + if(obj == null) + { + return defaultVal; + } + else if(clazz.isInstance(obj)) + { + return (E) obj; + } + else if(obj instanceof String) + { + return (E) Enum.valueOf(clazz, (String)obj); + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + " is not of required type " + clazz.getSimpleName()); + } + } + + public static <E extends Enum<?>> E getEnumAttribute(Class<E> clazz, String name, Map<String,Object> attributes) + { + assertMandatoryAttribute(name, attributes); + return getEnumAttribute(clazz, name, attributes, null); + } + + @SuppressWarnings({ "unchecked" }) + public static <T extends Enum<T>> T toEnum(String name, Object rawValue, Class<T> enumType) + { + if (enumType.isInstance(rawValue)) + { + return (T) rawValue; + } + else if (rawValue instanceof String) + { + return (T) Enum.valueOf(enumType, (String) rawValue); + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + " is not of required type " + + enumType.getSimpleName()); + } + } + + public static Boolean getBooleanAttribute(String name, Map<String,Object> attributes, Boolean defaultValue) + { + Object obj = attributes.get(name); + return toBoolean(name, obj, defaultValue); + } + + public static Boolean toBoolean(String name, Object obj) + { + return toBoolean(name, obj, null); + } + + public static Boolean toBoolean(String name, Object obj, Boolean defaultValue) + { + if(obj == null) + { + return defaultValue; + } + else if(obj instanceof Boolean) + { + return (Boolean) obj; + } + else if(obj instanceof String) + { + return Boolean.parseBoolean((String) obj); + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Boolean"); + } + } + + + public static boolean getBooleanAttribute(String name, Map<String, Object> attributes) + { + assertMandatoryAttribute(name, attributes); + return getBooleanAttribute(name, attributes, null); + } + + public static Integer getIntegerAttribute(String name, Map<String,Object> attributes, Integer defaultValue) + { + Object obj = attributes.get(name); + return toInteger(name, obj, defaultValue); + } + + public static Integer toInteger(String name, Object obj) + { + return toInteger(name, obj, null); + } + + public static Integer toInteger(String name, Object obj, Integer defaultValue) + { + if(obj == null) + { + return defaultValue; + } + else if(obj instanceof Number) + { + return ((Number) obj).intValue(); + } + else if(obj instanceof String) + { + return Integer.valueOf((String) obj); + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Integer"); + } + } + + public static Integer getIntegerAttribute(String name, Map<String,Object> attributes) + { + assertMandatoryAttribute(name, attributes); + return getIntegerAttribute(name, attributes, null); + } + + public static Long getLongAttribute(String name, Map<String,Object> attributes, Long defaultValue) + { + Object obj = attributes.get(name); + return toLong(name, obj, defaultValue); + } + + public static Long toLong(String name, Object obj) + { + return toLong(name, obj, null); + } + + public static Long toLong(String name, Object obj, Long defaultValue) + { + if(obj == null) + { + return defaultValue; + } + else if(obj instanceof Number) + { + return ((Number) obj).longValue(); + } + else if(obj instanceof String) + { + return Long.valueOf((String) obj); + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Long"); + } + } + + public static <T> Set<T> getSetAttribute(String name, Map<String,Object> attributes) + { + assertMandatoryAttribute(name, attributes); + return getSetAttribute(name, attributes, Collections.<T>emptySet()); + } + + @SuppressWarnings("unchecked") + public static <T> Set<T> getSetAttribute(String name, Map<String,Object> attributes, Set<T> defaultValue) + { + Object obj = attributes.get(name); + if(obj == null) + { + return defaultValue; + } + else if(obj instanceof Set) + { + return (Set<T>) obj; + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Set"); + } + } + + @SuppressWarnings("unchecked") + public static <T extends Enum<T>> Set<T> getEnumSetAttribute(String name, Map<String, Object> attributes, Class<T> clazz) + { + Object obj = attributes.get(name); + Object[] items = null; + if (obj == null) + { + return null; + } + else if (obj instanceof Collection) + { + Collection<?> data = (Collection<?>) obj; + items = data.toArray(new Object[data.size()]); + } + else if (obj instanceof String[]) + { + items = (String[]) obj; + } + else if (obj instanceof Object[]) + { + items = (Object[]) obj; + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + "[" + obj + + "] cannot be converted into set of enum of " + clazz); + } + Set<T> set = new HashSet<T>(); + for (int i = 0; i < items.length; i++) + { + T item = null; + Object value = items[i]; + if (value instanceof String) + { + item = (T) Enum.valueOf(clazz, (String) value); + } + else if (clazz.isInstance(value)) + { + item = (T) value; + } + else + { + throw new IllegalArgumentException("Cannot convert " + value + " from [" + obj + "] into enum of " + clazz + + " for attribute " + name); + } + set.add(item); + } + return set; + } + + @SuppressWarnings("unchecked") + public static Map<String, Object> convert(Map<String, Object> configurationAttributes, Map<String, Class<?>> attributeTypes) + { + Map<String, Object> attributes = new HashMap<String, Object>(); + for (Map.Entry<String, Class<?>> attributeEntry : attributeTypes.entrySet()) + { + String attributeName = attributeEntry.getKey(); + if (configurationAttributes.containsKey(attributeName)) + { + Class<?> classObject = attributeEntry.getValue(); + Object rawValue = configurationAttributes.get(attributeName); + Object value = null; + if (classObject == Long.class || classObject == long.class) + { + value = toLong(attributeName, rawValue); + } + else if (classObject == Integer.class || classObject == int.class) + { + value = toInteger(attributeName, rawValue); + } + else if (classObject == Boolean.class || classObject == boolean.class) + { + value = toBoolean(attributeName, rawValue); + } + else if (classObject == String.class) + { + value = toString(rawValue); + } + else if (Enum.class.isAssignableFrom(classObject)) + { + @SuppressWarnings("rawtypes") + Class<Enum> enumType = (Class<Enum>)classObject; + value = toEnum(attributeName, rawValue, enumType); + } + else + { + throw new IllegalArgumentException("Cannot convert '" + rawValue + "' into " + classObject); + } + attributes.put(attributeName, value); + } + } + return attributes; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java index f810360662..d24f79c56c 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java +++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java @@ -25,13 +25,10 @@ import java.util.UUID; import java.util.concurrent.ScheduledFuture; import org.apache.qpid.common.Closeable; import org.apache.qpid.server.binding.BindingFactory; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.VirtualHostConfig; import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.connection.IConnectionRegistry; import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.protocol.v1_0.LinkRegistry; import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.registry.IApplicationRegistry; @@ -41,7 +38,7 @@ import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.txn.DtxRegistry; -public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHostConfig, Closeable, StatisticsGatherer +public interface VirtualHost extends DurableConfigurationStore.Source, Closeable, StatisticsGatherer { IConnectionRegistry getConnectionRegistry(); @@ -61,8 +58,6 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo void close(); - UUID getBrokerId(); - UUID getId(); void scheduleHouseKeepingTask(long period, HouseKeepingTask task); @@ -77,25 +72,12 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo int getHouseKeepingActiveCount(); - IApplicationRegistry getApplicationRegistry(); + VirtualHostRegistry getVirtualHostRegistry(); BindingFactory getBindingFactory(); - void createBrokerConnection(String transport, - String host, - int port, - String vhost, - boolean durable, - String authMechanism, String username, String password); - - public BrokerLink createBrokerConnection(UUID id, long createTime, Map<String,String> arguments); - - ConfigStore getConfigStore(); - DtxRegistry getDtxRegistry(); - void removeBrokerConnection(BrokerLink brokerLink); - LinkRegistry getLinkRegistry(String remoteContainerId); ScheduledFuture<?> scheduleTask(long delay, Runnable timeoutTask); diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java index ea2f0f15e4..ae88e3e9f7 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java @@ -35,15 +35,16 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.BindingFactory; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.messages.TransactionLogMessages; import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject; import org.apache.qpid.server.message.AMQMessage; import org.apache.qpid.server.message.AbstractServerMessageImpl; import org.apache.qpid.server.message.EnqueableMessage; +import org.apache.qpid.server.message.MessageReference; import org.apache.qpid.server.message.MessageTransferMessage; import org.apache.qpid.server.message.ServerMessage; +import org.apache.qpid.server.protocol.v1_0.Message_1_0; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.server.queue.QueueEntry; @@ -65,7 +66,6 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa ConfigurationRecoveryHandler.QueueRecoveryHandler, ConfigurationRecoveryHandler.ExchangeRecoveryHandler, ConfigurationRecoveryHandler.BindingRecoveryHandler, - ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler, MessageStoreRecoveryHandler, MessageStoreRecoveryHandler.StoredMessageRecoveryHandler, TransactionLogRecoveryHandler, @@ -77,7 +77,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa private final VirtualHost _virtualHost; private final Map<String, Integer> _queueRecoveries = new TreeMap<String, Integer>(); - private final Map<Long, AbstractServerMessageImpl> _recoveredMessages = new HashMap<Long, AbstractServerMessageImpl>(); + private final Map<Long, ServerMessage> _recoveredMessages = new HashMap<Long, ServerMessage>(); private final Map<Long, StoredMessage> _unusedMessages = new HashMap<Long, StoredMessage>(); private MessageStoreLogSubject _logSubject; @@ -169,7 +169,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa public void message(StoredMessage message) { - AbstractServerMessageImpl serverMessage; + ServerMessage serverMessage; switch(message.getMetaData().getType()) { case META_DATA_0_8: @@ -178,6 +178,9 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa case META_DATA_0_10: serverMessage = new MessageTransferMessage(message, null); break; + case META_DATA_1_0: + serverMessage = new Message_1_0(message); + break; default: throw new RuntimeException("Unknown message type retrieved from store " + message.getMetaData().getClass()); } @@ -190,19 +193,6 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa { } - public BridgeRecoveryHandler brokerLink(final UUID id, - final long createTime, - final Map<String, String> arguments) - { - BrokerLink blink = _virtualHost.createBrokerConnection(id, createTime, arguments); - return new BridgeRecoveryHandlerImpl(blink); - - } - - public void completeBrokerLinkRecovery() - { - } - public void dtxRecord(long format, byte[] globalId, byte[] branchId, Transaction.Record[] enqueues, Transaction.Record[] dequeues) @@ -221,12 +211,13 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa if(queue != null) { final long messageId = record.getMessage().getMessageNumber(); - final AbstractServerMessageImpl message = _recoveredMessages.get(messageId); + final ServerMessage message = _recoveredMessages.get(messageId); _unusedMessages.remove(messageId); if(message != null) { - message.incrementReference(); + final MessageReference ref = message.newReference(); + branch.enqueue(queue,message); @@ -239,7 +230,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa { queue.enqueue(message, true, null); - message.decrementReference(); + ref.release(); } catch (AMQException e) { @@ -251,7 +242,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa public void onRollback() { - message.decrementReference(); + ref.release(); } }); } @@ -280,7 +271,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa if(queue != null) { final long messageId = record.getMessage().getMessageNumber(); - final AbstractServerMessageImpl message = _recoveredMessages.get(messageId); + final ServerMessage message = _recoveredMessages.get(messageId); _unusedMessages.remove(messageId); if(message != null) @@ -412,9 +403,8 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa } - public BrokerLinkRecoveryHandler completeBindingRecovery() + public void completeBindingRecovery() { - return this; } public void complete() @@ -529,22 +519,4 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa } } - private class BridgeRecoveryHandlerImpl implements BridgeRecoveryHandler - { - private final BrokerLink _blink; - - public BridgeRecoveryHandlerImpl(final BrokerLink blink) - { - _blink = blink; - } - - public void bridge(final UUID id, final long createTime, final Map<String, String> arguments) - { - _blink.createBridge(id, createTime, arguments); - } - - public void completeBridgeRecoveryForLink() - { - } - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java index d9dc0aa64e..dd3610373f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java +++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java @@ -25,7 +25,6 @@ import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -35,12 +34,8 @@ import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.binding.BindingFactory; -import org.apache.qpid.server.configuration.BrokerConfig; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; import org.apache.qpid.server.configuration.ExchangeConfiguration; import org.apache.qpid.server.configuration.QueueConfiguration; -import org.apache.qpid.server.configuration.VirtualHostConfigType; import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.connection.ConnectionRegistry; import org.apache.qpid.server.connection.IConnectionRegistry; @@ -49,7 +44,6 @@ import org.apache.qpid.server.exchange.DefaultExchangeRegistry; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.messages.VirtualHostMessages; import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject; @@ -61,17 +55,16 @@ import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.server.queue.DefaultQueueRegistry; import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.security.SecurityManager; import org.apache.qpid.server.stats.StatisticsCounter; +import org.apache.qpid.server.stats.StatisticsGatherer; import org.apache.qpid.server.store.Event; import org.apache.qpid.server.store.EventListener; import org.apache.qpid.server.store.HAMessageStore; import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.store.MessageStoreCreator; import org.apache.qpid.server.store.OperationalLoggingListener; import org.apache.qpid.server.txn.DtxRegistry; -import org.apache.qpid.server.virtualhost.plugins.VirtualHostPlugin; -import org.apache.qpid.server.virtualhost.plugins.VirtualHostPluginFactory; public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.RegistryChangeListener, EventListener { @@ -79,23 +72,19 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr private static final int HOUSEKEEPING_SHUTDOWN_TIMEOUT = 5; - private final UUID _qmfId; - private final String _name; private final UUID _id; private final long _createTime = System.currentTimeMillis(); - private final ConcurrentHashMap<BrokerLink,BrokerLink> _links = new ConcurrentHashMap<BrokerLink, BrokerLink>(); - private final ScheduledThreadPoolExecutor _houseKeepingTasks; - private final IApplicationRegistry _appRegistry; + private final VirtualHostRegistry _virtualHostRegistry; - private final SecurityManager _securityManager; + private final StatisticsGatherer _brokerStatisticsGatherer; - private final BrokerConfig _brokerConfig; + private final SecurityManager _securityManager; private final VirtualHostConfiguration _vhostConfig; @@ -120,7 +109,7 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr private final Map<String, LinkRegistry> _linkRegistry = new HashMap<String, LinkRegistry>(); private boolean _blocked; - public VirtualHostImpl(IApplicationRegistry appRegistry, VirtualHostConfiguration hostConfig) throws Exception + public VirtualHostImpl(VirtualHostRegistry virtualHostRegistry, StatisticsGatherer brokerStatisticsGatherer, SecurityManager parentSecurityManager, VirtualHostConfiguration hostConfig) throws Exception { if (hostConfig == null) { @@ -132,19 +121,17 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr throw new IllegalArgumentException("Illegal name (" + hostConfig.getName() + ") for virtualhost."); } - _appRegistry = appRegistry; - _brokerConfig = _appRegistry.getBrokerConfig(); + _virtualHostRegistry = virtualHostRegistry; + _brokerStatisticsGatherer = brokerStatisticsGatherer; _vhostConfig = hostConfig; _name = _vhostConfig.getName(); _dtxRegistry = new DtxRegistry(); - _qmfId = _appRegistry.getConfigStore().createId(); _id = UUIDGenerator.generateVhostUUID(_name); CurrentActor.get().message(VirtualHostMessages.CREATED(_name)); - _securityManager = new SecurityManager(_appRegistry.getSecurityManager()); - _securityManager.configureHostPlugins(_vhostConfig); + _securityManager = new SecurityManager(parentSecurityManager, _vhostConfig.getConfig().getString("security.acl")); _connectionRegistry = new ConnectionRegistry(); _connectionRegistry.addRegistryChangeListener(this); @@ -154,13 +141,12 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr _queueRegistry = new DefaultQueueRegistry(this); _exchangeFactory = new DefaultExchangeFactory(this); - _exchangeFactory.initialise(_vhostConfig); _exchangeRegistry = new DefaultExchangeRegistry(this); _bindingFactory = new BindingFactory(this); - _messageStore = initialiseMessageStore(hostConfig.getMessageStoreClass()); + _messageStore = initialiseMessageStore(hostConfig); configureMessageStore(hostConfig); @@ -187,22 +173,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr return _id; } - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public VirtualHostConfigType getConfigType() - { - return VirtualHostConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getBroker(); - } - public boolean isDurable() { return false; @@ -216,38 +186,9 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr */ private void initialiseHouseKeeping(long period) { - if (period != 0L) { scheduleHouseKeepingTask(period, new VirtualHostHouseKeepingTask()); - - Map<String, VirtualHostPluginFactory> plugins = _appRegistry.getPluginManager().getVirtualHostPlugins(); - - if (plugins != null) - { - for (Map.Entry<String, VirtualHostPluginFactory> entry : plugins.entrySet()) - { - String pluginName = entry.getKey(); - VirtualHostPluginFactory factory = entry.getValue(); - try - { - VirtualHostPlugin plugin = factory.newInstance(this); - - // If we had configuration for the plugin the schedule it. - if (plugin != null) - { - _houseKeepingTasks.scheduleAtFixedRate(plugin, plugin.getDelay() / 2, - plugin.getDelay(), plugin.getTimeUnit()); - - _logger.info("Loaded VirtualHostPlugin:" + plugin); - } - } - catch (RuntimeException e) - { - _logger.error("Unable to load VirtualHostPlugin:" + pluginName + " due to:" + e.getMessage(), e); - } - } - } } } @@ -329,19 +270,34 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr if (!(o instanceof MessageStore)) { - throw new ClassCastException("Message store factory class must implement " + MessageStore.class + + throw new ClassCastException("Message store class must implement " + MessageStore.class + ". Class " + clazz + " does not."); } final MessageStore messageStore = (MessageStore) o; - final MessageStoreLogSubject storeLogSubject = new MessageStoreLogSubject(this, clazz.getSimpleName()); + return messageStore; + } + + private MessageStore initialiseMessageStore(VirtualHostConfiguration hostConfig) throws Exception + { + String storeType = hostConfig.getConfig().getString("store.type"); + MessageStore messageStore = null; + if (storeType == null) + { + messageStore = initialiseMessageStore(hostConfig.getMessageStoreClass()); + } + else + { + messageStore = new MessageStoreCreator().createMessageStore(storeType); + } + + final MessageStoreLogSubject storeLogSubject = new MessageStoreLogSubject(this, messageStore.getClass().getSimpleName()); OperationalLoggingListener.listen(messageStore, storeLogSubject); messageStore.addEventListener(new BeforeActivationListener(), Event.BEFORE_ACTIVATE); messageStore.addEventListener(new AfterActivationListener(), Event.AFTER_ACTIVATE); messageStore.addEventListener(new BeforeCloseListener(), Event.BEFORE_CLOSE); messageStore.addEventListener(new BeforePassivationListener(), Event.BEFORE_PASSIVATE); - return messageStore; } @@ -468,16 +424,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr return _name; } - public BrokerConfig getBroker() - { - return _brokerConfig; - } - - public String getFederationTag() - { - return _brokerConfig.getFederationTag(); - } - public long getCreateTime() { return _createTime; @@ -534,14 +480,9 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr CurrentActor.get().message(VirtualHostMessages.CLOSED()); } - public UUID getBrokerId() - { - return _appRegistry.getBrokerId(); - } - - public IApplicationRegistry getApplicationRegistry() + public VirtualHostRegistry getVirtualHostRegistry() { - return _appRegistry; + return _virtualHostRegistry; } public BindingFactory getBindingFactory() @@ -553,14 +494,14 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr { _messagesDelivered.registerEvent(1L); _dataDelivered.registerEvent(messageSize); - _appRegistry.registerMessageDelivered(messageSize); + _brokerStatisticsGatherer.registerMessageDelivered(messageSize); } public void registerMessageReceived(long messageSize, long timestamp) { _messagesReceived.registerEvent(1L, timestamp); _dataReceived.registerEvent(messageSize, timestamp); - _appRegistry.registerMessageReceived(messageSize, timestamp); + _brokerStatisticsGatherer.registerMessageReceived(messageSize, timestamp); } public StatisticsCounter getMessageReceiptStatistics() @@ -604,51 +545,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr _dataReceived = new StatisticsCounter("bytes-received-" + getName()); } - public BrokerLink createBrokerConnection(UUID id, long createTime, Map<String,String> arguments) - { - BrokerLink blink = new BrokerLink(this, id, createTime, arguments); - // TODO - cope with duplicate broker link creation requests - _links.putIfAbsent(blink,blink); - getConfigStore().addConfiguredObject(blink); - return blink; - } - - public void createBrokerConnection(final String transport, - final String host, - final int port, - final String vhost, - final boolean durable, - final String authMechanism, - final String username, - final String password) - { - BrokerLink blink = new BrokerLink(this, transport, host, port, vhost, durable, authMechanism, username, password); - - // TODO - cope with duplicate broker link creation requests - _links.putIfAbsent(blink,blink); - getConfigStore().addConfiguredObject(blink); - - } - - public void removeBrokerConnection(final String transport, - final String host, - final int port, - final String vhost) - { - removeBrokerConnection(new BrokerLink(this, transport, host, port, vhost, false, null,null,null)); - - } - - public void removeBrokerConnection(BrokerLink blink) - { - blink = _links.get(blink); - if(blink != null) - { - blink.close(); - getConfigStore().removeConfiguredObject(blink); - } - } - public synchronized LinkRegistry getLinkRegistry(String remoteContainerId) { LinkRegistry linkRegistry = _linkRegistry.get(remoteContainerId); @@ -660,11 +556,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr return linkRegistry; } - public ConfigStore getConfigStore() - { - return getApplicationRegistry().getConfigStore(); - } - public DtxRegistry getDtxRegistry() { return _dtxRegistry; diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java index 1be472844a..483e11942b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java @@ -1,140 +1,95 @@ -/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.server.virtualhost;
-
-import org.apache.qpid.common.Closeable;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.registry.ApplicationRegistry;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections; -import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-
-public class VirtualHostRegistry implements Closeable
-{
- private final Map<String, VirtualHost> _registry = new ConcurrentHashMap<String, VirtualHost>();
-
-
- private String _defaultVirtualHostName;
- private ApplicationRegistry _applicationRegistry;
- private final Collection<RegistryChangeListener> _listeners = - Collections.synchronizedCollection(new ArrayList<RegistryChangeListener>()); -
- public VirtualHostRegistry(ApplicationRegistry applicationRegistry)
- {
- _applicationRegistry = applicationRegistry;
- }
-
- public synchronized void registerVirtualHost(VirtualHost host) throws Exception
- {
- if(_registry.containsKey(host.getName()))
- {
- throw new Exception("Virtual Host with name " + host.getName() + " already registered.");
- }
- _registry.put(host.getName(),host);
- synchronized (_listeners) +/* + * + * 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.virtualhost; + +import org.apache.qpid.common.Closeable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + + +public class VirtualHostRegistry implements Closeable +{ + private final Map<String, VirtualHost> _registry = new ConcurrentHashMap<String, VirtualHost>(); + private String _defaultVirtualHostName; + + + public VirtualHostRegistry() + { + super(); + } + + public synchronized void registerVirtualHost(VirtualHost host) + { + if(_registry.containsKey(host.getName())) { - for(RegistryChangeListener listener : _listeners) - { - listener.virtualHostRegistered(host); - } + throw new IllegalArgumentException("Virtual Host with name " + host.getName() + " already registered."); } - }
-
- public synchronized void unregisterVirtualHost(VirtualHost host)
- {
- _registry.remove(host.getName());
- synchronized (_listeners) + _registry.put(host.getName(),host); + } + + public synchronized void unregisterVirtualHost(VirtualHost host) + { + _registry.remove(host.getName()); + } + + public VirtualHost getVirtualHost(String name) + { + if(name == null || name.trim().length() == 0 || "/".equals(name.trim())) { - for(RegistryChangeListener listener : _listeners) - { - listener.virtualHostUnregistered(host); - } + name = getDefaultVirtualHostName(); } - }
-
- public VirtualHost getVirtualHost(String name)
- {
- if(name == null || name.trim().length() == 0 || "/".equals(name.trim()))
- {
- name = getDefaultVirtualHostName();
- }
-
- return _registry.get(name);
- }
-
- public VirtualHost getDefaultVirtualHost()
- {
- return getVirtualHost(getDefaultVirtualHostName());
- }
-
- private String getDefaultVirtualHostName()
- {
- return _defaultVirtualHostName;
- }
-
- public void setDefaultVirtualHostName(String defaultVirtualHostName)
- {
- _defaultVirtualHostName = defaultVirtualHostName;
- }
-
-
- public Collection<VirtualHost> getVirtualHosts()
- {
- return new ArrayList<VirtualHost>(_registry.values());
- }
-
- public ApplicationRegistry getApplicationRegistry()
- {
- return _applicationRegistry;
- }
-
- public ConfigStore getConfigStore()
- {
- return _applicationRegistry.getConfigStore();
- }
-
- public void close()
- {
- for (VirtualHost virtualHost : getVirtualHosts())
- {
- virtualHost.close();
- }
-
- }
- - public static interface RegistryChangeListener + + return _registry.get(name); + } + + public VirtualHost getDefaultVirtualHost() { - void virtualHostRegistered(VirtualHost virtualHost); - void virtualHostUnregistered(VirtualHost virtualHost); + return getVirtualHost(getDefaultVirtualHostName()); + } + private String getDefaultVirtualHostName() + { + return _defaultVirtualHostName; } - public void addRegistryChangeListener(RegistryChangeListener listener) + public void setDefaultVirtualHostName(String defaultVirtualHostName) { - _listeners.add(listener); + _defaultVirtualHostName = defaultVirtualHostName; + } + + + public Collection<VirtualHost> getVirtualHosts() + { + return new ArrayList<VirtualHost>(_registry.values()); + } + + public void close() + { + for (VirtualHost virtualHost : getVirtualHosts()) + { + virtualHost.close(); + } } -}
+} diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/ConfiguredQueueBindingListener.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/ConfiguredQueueBindingListener.java deleted file mode 100644 index 12886f400a..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/ConfiguredQueueBindingListener.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * - * 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.virtualhost.plugins; - -import org.apache.log4j.Logger; - -import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionQueueConfiguration; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.exchange.Exchange.BindingListener; -import org.apache.qpid.server.queue.AMQQueue; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -/** - * This is a listener that caches queues that are configured for slow consumer disconnection. - * - * There should be one listener per virtual host, which can be added to all exchanges on - * that host. - * - * TODO In future, it will be possible to configure the policy at runtime, so only the queue - * itself is cached, and the configuration looked up by the housekeeping thread. This means - * that there may be occasions where the copy of the cache contents retrieved by the thread - * does not contain queues that are configured, or that configured queues are not present. - * - * @see BindingListener - */ -public class ConfiguredQueueBindingListener implements BindingListener -{ - private static final Logger _log = Logger.getLogger(ConfiguredQueueBindingListener.class); - - private String _vhostName; - private Set<AMQQueue> _cache = Collections.synchronizedSet(new HashSet<AMQQueue>()); - - public ConfiguredQueueBindingListener(String vhostName) - { - _vhostName = vhostName; - } - - /** - * @see BindingListener#bindingAdded(Exchange, Binding) - */ - public void bindingAdded(Exchange exchange, Binding binding) - { - processBinding(binding); - } - - /** - * @see BindingListener#bindingRemoved(Exchange, Binding) - */ - public void bindingRemoved(Exchange exchange, Binding binding) - { - processBinding(binding); - } - - private void processBinding(Binding binding) - { - AMQQueue queue = binding.getQueue(); - - SlowConsumerDetectionQueueConfiguration config = - queue.getConfiguration().getConfiguration(SlowConsumerDetectionQueueConfiguration.class.getName()); - if (config != null) - { - _cache.add(queue); - } - else - { - _cache.remove(queue); - } - } - - /** - * Lookup and return the cache of configured {@link AMQQueue}s. - * - * Note that when accessing the cached queues, the {@link java.util.Iterator} is not thread safe - * (see the {@link Collections#synchronizedSet(Set)} documentation) so a copy of the - * cache is returned. - * - * @return a copy of the cached {@link java.util.Set} of queues - */ - public Set<AMQQueue> getQueueCache() - { - return new HashSet<AMQQueue>(_cache); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java deleted file mode 100644 index bd2e30449a..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * - * 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.virtualhost.plugins; - -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionConfiguration; -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionQueueConfiguration; -import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.virtualhost.plugins.logging.SlowConsumerDetectionMessages; -import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPlugin; - -import java.util.Set; -import java.util.concurrent.TimeUnit; - -public class SlowConsumerDetection extends VirtualHostHouseKeepingPlugin -{ - private SlowConsumerDetectionConfiguration _config; - private ConfiguredQueueBindingListener _listener; - - public static class SlowConsumerFactory implements VirtualHostPluginFactory - { - public SlowConsumerDetection newInstance(VirtualHost vhost) - { - SlowConsumerDetectionConfiguration config = vhost.getConfiguration().getConfiguration(SlowConsumerDetectionConfiguration.class.getName()); - - if (config == null) - { - return null; - } - - SlowConsumerDetection plugin = new SlowConsumerDetection(vhost); - plugin.configure(config); - return plugin; - } - } - - /** - * Configures the slow consumer disconnect plugin by adding a listener to each exchange on this - * virtual host to record all the configured queues in a cache for processing by the housekeeping - * thread. - * - * @see org.apache.qpid.server.plugins.Plugin#configure(ConfigurationPlugin) - */ - public void configure(ConfigurationPlugin config) - { - _config = (SlowConsumerDetectionConfiguration) config; - _listener = new ConfiguredQueueBindingListener(getVirtualHost().getName()); - final ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry(); - for (AMQShortString exchangeName : exchangeRegistry.getExchangeNames()) - { - exchangeRegistry.getExchange(exchangeName).addBindingListener(_listener); - } - } - - public SlowConsumerDetection(VirtualHost vhost) - { - super(vhost); - } - - public void execute() - { - CurrentActor.get().message(SlowConsumerDetectionMessages.RUNNING()); - - Set<AMQQueue> cache = _listener.getQueueCache(); - for (AMQQueue q : cache) - { - CurrentActor.get().message(SlowConsumerDetectionMessages.CHECKING_QUEUE(q.getName())); - - try - { - final SlowConsumerDetectionQueueConfiguration config = - q.getConfiguration().getConfiguration(SlowConsumerDetectionQueueConfiguration.class.getName()); - if (checkQueueStatus(q, config)) - { - final SlowConsumerPolicyPlugin policy = config.getPolicy(); - if (policy == null) - { - // We would only expect to see this during shutdown - getLogger().warn("No slow consumer policy for queue " + q.getName()); - } - else - { - policy.performPolicy(q); - } - - } - } - catch (Exception e) - { - // Don't throw exceptions as this will stop the house keeping task from running. - getLogger().error("Exception in SlowConsumersDetection for queue: " + q.getName(), e); - } - } - - CurrentActor.get().message(SlowConsumerDetectionMessages.COMPLETE()); - } - - public long getDelay() - { - return _config.getDelay(); - } - - public TimeUnit getTimeUnit() - { - return _config.getTimeUnit(); - } - - /** - * Check the depth,messageSize,messageAge,messageCount values for this q - * - * @param q the queue to check - * @param config the queue configuration to compare against the queue state - * - * @return true if the queue has reached a threshold. - */ - private boolean checkQueueStatus(AMQQueue q, SlowConsumerDetectionQueueConfiguration config) - { - if (config != null) - { - if (getLogger().isInfoEnabled()) - { - getLogger().info("Retrieved Queue(" + q.getName() + ") Config:" + config); - } - - int count = q.getMessageCount(); - - // First Check message counts - if ((config.getMessageCount() != 0 && count >= config.getMessageCount()) || - // The check queue depth - (config.getDepth() != 0 && q.getQueueDepth() >= config.getDepth()) || - // finally if we have messages on the queue check Arrival time. - // We must check count as OldestArrival time is Long.MAX_LONG when - // there are no messages. - (config.getMessageAge() != 0 && - ((count > 0) && q.getOldestMessageArrivalTime() >= config.getMessageAge()))) - { - - if (getLogger().isDebugEnabled()) - { - getLogger().debug("Detected Slow Consumer on Queue(" + q.getName() + ")"); - getLogger().debug("Queue Count:" + q.getMessageCount() + ":" + config.getMessageCount()); - getLogger().debug("Queue Depth:" + q.getQueueDepth() + ":" + config.getDepth()); - getLogger().debug("Queue Arrival:" + q.getOldestMessageArrivalTime() + ":" + config.getMessageAge()); - } - - return true; - } - } - return false; - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java deleted file mode 100644 index 35f6228ab9..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * 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.virtualhost.plugins; - -import org.apache.qpid.server.plugins.Plugin; - -import java.util.concurrent.TimeUnit; - -public interface VirtualHostPlugin extends Runnable, Plugin -{ - /** - * Long value representing the delay between repeats - * - * @return - */ - public long getDelay(); - - /** - * Option to specify what the delay value represents - * @see java.util.concurrent.TimeUnit for valid value. - * @return - */ - public TimeUnit getTimeUnit(); -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPluginFactory.java deleted file mode 100644 index c8bea18444..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPluginFactory.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - * 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.virtualhost.plugins; - -import org.apache.qpid.server.virtualhost.VirtualHost; - -public interface VirtualHostPluginFactory -{ - public VirtualHostHouseKeepingPlugin newInstance(VirtualHost vhost); -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/SlowConsumerDetection_logmessages.properties b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/SlowConsumerDetection_logmessages.properties deleted file mode 100644 index 03c56910c2..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/SlowConsumerDetection_logmessages.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -# Default File used for all non-defined locales. - -RUNNING = SCD-1001 : Running -COMPLETE = SCD-1002 : Complete -CHECKING_QUEUE = SCD-1003 : Checking Status of Queue {0}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/TopicDeletePolicy_logmessages.properties b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/TopicDeletePolicy_logmessages.properties deleted file mode 100644 index ed4fb1d45a..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/TopicDeletePolicy_logmessages.properties +++ /dev/null @@ -1,22 +0,0 @@ -# -# 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. -# -# Default File used for all non-defined locales. - -DELETING_QUEUE = TDP-1001 : Deleting Queue -DISCONNECTING = TDP-1002 : Disconnecting Session
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicy.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicy.java deleted file mode 100644 index f2f61f204e..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicy.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * - * 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.virtualhost.plugins.policies; - -import org.apache.commons.configuration.ConfigurationException; -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.exchange.TopicExchange; -import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.protocol.AMQSessionModel; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.virtualhost.plugins.logging.TopicDeletePolicyMessages; -import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPlugin; -import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPluginFactory; - -public class TopicDeletePolicy implements SlowConsumerPolicyPlugin -{ - private Logger _logger = Logger.getLogger(TopicDeletePolicy.class); - private TopicDeletePolicyConfiguration _configuration; - - public static class TopicDeletePolicyFactory implements SlowConsumerPolicyPluginFactory - { - public TopicDeletePolicy newInstance(ConfigurationPlugin configuration) throws ConfigurationException - { - TopicDeletePolicyConfiguration config = - configuration.getConfiguration(TopicDeletePolicyConfiguration.class.getName()); - - TopicDeletePolicy policy = new TopicDeletePolicy(); - policy.configure(config); - return policy; - } - - public String getPluginName() - { - return "topicdelete"; - } - - public Class<TopicDeletePolicy> getPluginClass() - { - return TopicDeletePolicy.class; - } - } - - public void performPolicy(AMQQueue q) - { - if (q == null) - { - return; - } - - AMQSessionModel owner = q.getExclusiveOwningSession(); - - // Only process exclusive queues - if (owner == null) - { - return; - } - - //Only process Topics - if (!validateQueueIsATopic(q)) - { - return; - } - - try - { - CurrentActor.get().message(owner.getLogSubject(),TopicDeletePolicyMessages.DISCONNECTING()); - // Close the consumer . this will cause autoDelete Queues to be purged - owner.getConnectionModel(). - closeSession(owner, AMQConstant.RESOURCE_ERROR, - "Consuming to slow."); - - // Actively delete non autoDelete queues if deletePersistent is set - if (!q.isAutoDelete() && (_configuration != null && _configuration.deletePersistent())) - { - CurrentActor.get().message(q.getLogSubject(), TopicDeletePolicyMessages.DELETING_QUEUE()); - q.delete(); - } - - } - catch (AMQException e) - { - _logger.warn("Unable to close consumer:" + owner + ", on queue:" + q.getName()); - } - - } - - /** - * Check the queue bindings to validate the queue is bound to the - * topic exchange. - * - * @param q the Queue - * - * @return true iff Q is bound to a TopicExchange - */ - private boolean validateQueueIsATopic(AMQQueue q) - { - for (Binding binding : q.getBindings()) - { - if (binding.getExchange() instanceof TopicExchange) - { - return true; - } - } - - return false; - } - - public void configure(ConfigurationPlugin config) - { - _configuration = (TopicDeletePolicyConfiguration) config; - } - - @Override - public String toString() - { - return "TopicDelete" + (_configuration == null ? "" : "[" + _configuration + "]"); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfiguration.java deleted file mode 100644 index 48158b7dff..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfiguration.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * 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.virtualhost.plugins.policies; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; - -import java.util.Arrays; -import java.util.List; - -public class TopicDeletePolicyConfiguration extends ConfigurationPlugin -{ - - public static class TopicDeletePolicyConfigurationFactory - implements ConfigurationPluginFactory - { - public ConfigurationPlugin newInstance(String path, - Configuration config) - throws ConfigurationException - { - TopicDeletePolicyConfiguration slowConsumerConfig = - new TopicDeletePolicyConfiguration(); - slowConsumerConfig.setConfiguration(path, config); - return slowConsumerConfig; - } - - public List<String> getParentPaths() - { - return Arrays.asList( - "virtualhosts.virtualhost.queues.slow-consumer-detection.policy.topicDelete", - "virtualhosts.virtualhost.queues.queue.slow-consumer-detection.policy.topicDelete", - "virtualhosts.virtualhost.topics.slow-consumer-detection.policy.topicDelete", - "virtualhosts.virtualhost.topics.topic.slow-consumer-detection.policy.topicDelete"); - } - } - - public String[] getElementsProcessed() - { - return new String[]{"delete-persistent"}; - } - - @Override - public void validateConfiguration() throws ConfigurationException - { - // No validation required. - } - - public boolean deletePersistent() - { - // If we don't have configuration then we don't deletePersistent Queues - return (hasConfiguration() && contains("delete-persistent")); - } - - @Override - public String formatToString() - { - return (deletePersistent()?"delete-durable":""); - } - - -} diff --git a/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPlugin.java b/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPlugin.java deleted file mode 100644 index 7f600abdc9..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPlugin.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * - * 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.slowconsumerdetection.policies; - -import org.apache.qpid.server.plugins.Plugin; -import org.apache.qpid.server.queue.AMQQueue; - -public interface SlowConsumerPolicyPlugin extends Plugin -{ - public void performPolicy(AMQQueue Queue); -} diff --git a/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPluginFactory.java b/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPluginFactory.java deleted file mode 100644 index b2fe6766a6..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPluginFactory.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * - * 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.slowconsumerdetection.policies; - -import org.apache.qpid.server.plugins.PluginFactory; - -public interface SlowConsumerPolicyPluginFactory<P extends SlowConsumerPolicyPlugin> extends PluginFactory<P> -{ -} diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.configuration.ConfigurationStoreFactory b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.configuration.ConfigurationStoreFactory new file mode 100644 index 0000000000..5f75a8c4c9 --- /dev/null +++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.configuration.ConfigurationStoreFactory @@ -0,0 +1,19 @@ +# +# 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. +# +org.apache.qpid.server.configuration.store.factory.JsonConfigurationStoreFactory diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AuthenticationManagerFactory b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AuthenticationManagerFactory new file mode 100644 index 0000000000..8ff67030ef --- /dev/null +++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AuthenticationManagerFactory @@ -0,0 +1,24 @@ +# +# 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. +# +org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManagerFactory +org.apache.qpid.server.security.auth.manager.Base64MD5PasswordFileAuthenticationManagerFactory +org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManagerFactory +org.apache.qpid.server.security.auth.manager.KerberosAuthenticationManagerFactory +org.apache.qpid.server.security.auth.manager.PlainPasswordFileAuthenticationManagerFactory +org.apache.qpid.server.security.auth.manager.SimpleLDAPAuthenticationManagerFactory diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ExchangeType b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ExchangeType new file mode 100644 index 0000000000..4ad646b7a0 --- /dev/null +++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ExchangeType @@ -0,0 +1,22 @@ +# +# 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. +# +org.apache.qpid.server.exchange.DirectExchangeType +org.apache.qpid.server.exchange.TopicExchangeType +org.apache.qpid.server.exchange.FanoutExchangeType +org.apache.qpid.server.exchange.HeadersExchangeType diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.GroupManagerFactory b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.GroupManagerFactory new file mode 100644 index 0000000000..6bfb55ff18 --- /dev/null +++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.GroupManagerFactory @@ -0,0 +1,19 @@ +# +# 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. +# +org.apache.qpid.server.security.group.FileGroupManagerFactory diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.store.MessageStoreFactory b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.store.MessageStoreFactory new file mode 100644 index 0000000000..1357f816b7 --- /dev/null +++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.store.MessageStoreFactory @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.qpid.server.store.derby.DerbyMessageStoreFactory +org.apache.qpid.server.store.MemoryMessageStoreFactory
\ No newline at end of file diff --git a/java/broker/src/main/resources/initial-store.json b/java/broker/src/main/resources/initial-store.json new file mode 100644 index 0000000000..a80ad95bd4 --- /dev/null +++ b/java/broker/src/main/resources/initial-store.json @@ -0,0 +1,58 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +{ + "name": "QpidBroker", + "defaultAuthenticationProvider" : "defaultAuthenticationProvider", + "defaultVirtualHost" : "default", + "authenticationproviders" : [ { + "name" : "defaultAuthenticationProvider", + "authenticationProviderType" : "PlainPasswordFileAuthenticationProvider", + "path" : "${QPID_HOME}/etc/passwd" + } ], + "ports" : [ { + "name" : "5672-AMQP", + "port" : 5672 + }, { + "name" : "8080-HTTP", + "port" : 8080, + "protocols" : [ "HTTP" ] + }, { + "name" : "8999-RMI", + "port" : 8999, + "protocols" : [ "RMI" ] + }, { + "name" : "9099-JMX_RMI", + "port" : 9099, + "protocols" : [ "JMX_RMI" ] + }], + "virtualhosts" : [ { + "name" : "default", + "storeType" : "DERBY", + "storePath" : "${QPID_WORK}/store" + } ], + "plugins" : [ { + "pluginType" : "MANAGEMENT-HTTP", + "name" : "httpManagement" + }, { + "pluginType" : "MANAGEMENT-JMX", + "name" : "jmxManagement" + } ] +}
\ No newline at end of file diff --git a/java/broker/src/test/java/org/apache/qpid/server/AMQChannelTest.java b/java/broker/src/test/java/org/apache/qpid/server/AMQChannelTest.java index fc6cbcb248..e10bdbbb35 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/AMQChannelTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/AMQChannelTest.java @@ -20,23 +20,69 @@ */ package org.apache.qpid.server; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.abstraction.MessagePublishInfo; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.message.MessageContentSource; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.protocol.InternalTestProtocolSession; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.test.utils.QpidTestCase; -public class AMQChannelTest extends InternalBrokerBaseCase +public class AMQChannelTest extends QpidTestCase { private VirtualHost _virtualHost; private AMQProtocolSession _protocolSession; + private Map<Integer,String> _replies; + private Broker _broker; @Override public void setUp() throws Exception { super.setUp(); - _virtualHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHosts().iterator().next(); - _protocolSession = new InternalTestProtocolSession(_virtualHost); + BrokerTestHelper.setUp(); + _virtualHost = BrokerTestHelper.createVirtualHost(getTestName()); + _broker = BrokerTestHelper.createBrokerMock(); + _protocolSession = new InternalTestProtocolSession(_virtualHost, _broker) + { + @Override + public void writeReturn(MessagePublishInfo messagePublishInfo, + ContentHeaderBody header, + MessageContentSource msgContent, + int channelId, + int replyCode, + AMQShortString replyText) throws AMQException + { + _replies.put(replyCode, replyText.asString()); + } + }; + _replies = new HashMap<Integer, String>(); + } + + @Override + public void tearDown() throws Exception + { + try + { + _virtualHost.close(); + } + finally + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } } public void testCompareTo() throws Exception @@ -44,9 +90,54 @@ public class AMQChannelTest extends InternalBrokerBaseCase AMQChannel channel1 = new AMQChannel(_protocolSession, 1, _virtualHost.getMessageStore()); // create a channel with the same channelId but on a different session - AMQChannel channel2 = new AMQChannel(new InternalTestProtocolSession(_virtualHost), 1, _virtualHost.getMessageStore()); + AMQChannel channel2 = new AMQChannel(new InternalTestProtocolSession(_virtualHost, _broker), 1, _virtualHost.getMessageStore()); assertFalse("Unexpected compare result", channel1.compareTo(channel2) == 0); assertEquals("Unexpected compare result", 0, channel1.compareTo(channel1)); } + public void testPublishContentHeaderWhenMessageAuthorizationFails() throws Exception + { + setTestSystemProperty(BrokerProperties.PROPERTY_MSG_AUTH, "true"); + AMQChannel channel = new AMQChannel(_protocolSession, 1, _virtualHost.getMessageStore()); + channel.setLocalTransactional(); + + MessagePublishInfo info = mock(MessagePublishInfo.class); + Exchange e = mock(Exchange.class); + ContentHeaderBody contentHeaderBody= mock(ContentHeaderBody.class); + BasicContentHeaderProperties properties = mock(BasicContentHeaderProperties.class); + + when(contentHeaderBody.getProperties()).thenReturn(properties); + when(info.getExchange()).thenReturn(new AMQShortString("test")); + when(properties.getUserId()).thenReturn(new AMQShortString(_protocolSession.getAuthorizedPrincipal().getName() + "_incorrect")); + + channel.setPublishFrame(info, e); + channel.publishContentHeader(contentHeaderBody); + channel.commit(); + + assertEquals("Unexpected number of replies", 1, _replies.size()); + assertEquals("Message authorization passed", "Access Refused", _replies.get(403)); + } + + public void testPublishContentHeaderWhenMessageAuthorizationPasses() throws Exception + { + setTestSystemProperty(BrokerProperties.PROPERTY_MSG_AUTH, "true"); + AMQChannel channel = new AMQChannel(_protocolSession, 1, _virtualHost.getMessageStore()); + channel.setLocalTransactional(); + + MessagePublishInfo info = mock(MessagePublishInfo.class); + Exchange e = mock(Exchange.class); + ContentHeaderBody contentHeaderBody= mock(ContentHeaderBody.class); + BasicContentHeaderProperties properties = mock(BasicContentHeaderProperties.class); + + when(contentHeaderBody.getProperties()).thenReturn(properties); + when(info.getExchange()).thenReturn(new AMQShortString("test")); + when(properties.getUserId()).thenReturn(new AMQShortString(_protocolSession.getAuthorizedPrincipal().getName())); + + channel.setPublishFrame(info, e); + channel.publishContentHeader(contentHeaderBody); + channel.commit(); + + assertEquals("Unexpected number of replies", 0, _replies.size()); + } + } diff --git a/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java b/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java index 43824e713f..16b459b5d4 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java @@ -22,91 +22,36 @@ package org.apache.qpid.server; import org.apache.qpid.test.utils.QpidTestCase; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - - public class BrokerOptionsTest extends QpidTestCase { private BrokerOptions _options; - - private static final int TEST_PORT1 = 6789; - private static final int TEST_PORT2 = 6790; - protected void setUp() { _options = new BrokerOptions(); } - - public void testDefaultPort() - { - assertEquals(Collections.<Integer>emptySet(), _options.getPorts()); - } - public void testOverriddenPort() + public void testDefaultConfigurationStoreType() { - _options.addPort(TEST_PORT1); - assertEquals(Collections.singleton(TEST_PORT1), _options.getPorts()); + assertEquals("json", _options.getConfigurationStoreType()); } - public void testManyOverriddenPorts() + public void testOverriddenConfigurationStoreType() { - _options.addPort(TEST_PORT1); - _options.addPort(TEST_PORT2); - final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2})); - assertEquals(expectedPorts, _options.getPorts()); + _options.setConfigurationStoreType("dby"); + assertEquals("dby", _options.getConfigurationStoreType()); } - public void testDuplicateOverriddenPortsAreSilentlyIgnored() + public void testDefaultConfigurationStoreLocation() { - _options.addPort(TEST_PORT1); - _options.addPort(TEST_PORT2); - _options.addPort(TEST_PORT1); // duplicate - should be silently ignored - final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2})); - assertEquals(expectedPorts, _options.getPorts()); + assertNull(_options.getConfigurationStoreLocation()); } - public void testDefaultSSLPort() - { - assertEquals(Collections.<Integer>emptySet(), _options.getSSLPorts()); - } - - public void testOverriddenSSLPort() - { - _options.addSSLPort(TEST_PORT1); - assertEquals(Collections.singleton(TEST_PORT1), _options.getSSLPorts()); - } - - public void testManyOverriddenSSLPorts() - { - _options.addSSLPort(TEST_PORT1); - _options.addSSLPort(TEST_PORT2); - final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2})); - assertEquals(expectedPorts, _options.getSSLPorts()); - } - - public void testDuplicateOverriddenSSLPortsAreSilentlyIgnored() - { - _options.addSSLPort(TEST_PORT1); - _options.addSSLPort(TEST_PORT2); - _options.addSSLPort(TEST_PORT1); // duplicate - should be silently ignored - final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2})); - assertEquals(expectedPorts, _options.getSSLPorts()); - } - - public void testDefaultConfigFile() - { - assertNull(_options.getConfigFile()); - } - - public void testOverriddenConfigFile() + public void testOverriddenConfigurationStoreLocation() { final String testConfigFile = "etc/mytestconfig.xml"; - _options.setConfigFile(testConfigFile); - assertEquals(testConfigFile, _options.getConfigFile()); + _options.setConfigurationStoreLocation(testConfigFile); + assertEquals(testConfigFile, _options.getConfigurationStoreLocation()); } public void testDefaultLogConfigFile() @@ -121,109 +66,85 @@ public class BrokerOptionsTest extends QpidTestCase assertEquals(testLogConfigFile, _options.getLogConfigFile()); } - public void testDefaultJmxPortRegistryServer() + public void testDefaultLogWatchFrequency() { - assertNull(_options.getJmxPortRegistryServer()); + assertEquals(0L, _options.getLogWatchFrequency()); } - public void testJmxPortRegistryServer() + public void testOverridenLogWatchFrequency() { - _options.setJmxPortRegistryServer(TEST_PORT1); - assertEquals(Integer.valueOf(TEST_PORT1), _options.getJmxPortRegistryServer()); + final int myFreq = 10 * 1000; + + _options.setLogWatchFrequency(myFreq); + assertEquals(myFreq, _options.getLogWatchFrequency()); } - public void testDefaultJmxPortConnectorServer() - { - assertNull(_options.getJmxPortConnectorServer()); - } - public void testJmxPortConnectorServer() + public void testDefaultInitialConfigurationStoreType() { - _options.setJmxPortConnectorServer(TEST_PORT1); - assertEquals(Integer.valueOf(TEST_PORT1), _options.getJmxPortConnectorServer()); + assertEquals("json", _options.getInitialConfigurationStoreType()); } - public void testQpidHomeExposesSysProperty() + public void testOverriddenInitialConfigurationStoreType() { - assertEquals(System.getProperty("QPID_HOME"), _options.getQpidHome()); - } - - public void testDefaultExcludesPortFor0_10() - { - assertEquals(Collections.EMPTY_SET, _options.getExcludedPorts(ProtocolExclusion.v0_10)); - } - - public void testOverriddenExcludesPortFor0_10() - { - _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT1); - assertEquals(Collections.singleton(TEST_PORT1), _options.getExcludedPorts(ProtocolExclusion.v0_10)); + _options.setInitialConfigurationStoreType("dby"); + assertEquals("dby", _options.getInitialConfigurationStoreType()); } - public void testManyOverriddenExcludedPortFor0_10() + public void testDefaultInitialConfigurationStoreLocation() { - _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT1); - _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT2); - final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2})); - assertEquals(expectedPorts, _options.getExcludedPorts(ProtocolExclusion.v0_10)); + assertNull(_options.getInitialConfigurationStoreLocation()); } - public void testDuplicatedOverriddenExcludedPortFor0_10AreSilentlyIgnored() + public void testOverriddenInitialConfigurationStoreLocation() { - _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT1); - _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT2); - final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2})); - assertEquals(expectedPorts, _options.getExcludedPorts(ProtocolExclusion.v0_10)); + final String testConfigFile = "etc/mytestconfig.xml"; + _options.setInitialConfigurationStoreLocation(testConfigFile); + assertEquals(testConfigFile, _options.getInitialConfigurationStoreLocation()); } - - public void testDefaultBind() + + public void testDefaultManagementMode() { - assertNull(_options.getBind()); + assertEquals(false, _options.isManagementMode()); } - - public void testOverriddenBind() + + public void testOverriddenDefaultManagementMode() { - final String bind = "192.168.0.1"; - _options.setBind(bind); - assertEquals(bind, _options.getBind()); + _options.setManagementMode(true); + assertEquals(true, _options.isManagementMode()); } - public void testDefaultLogWatchFrequency() + public void testDefaultManagementModeRmiPort() { - assertEquals(0L, _options.getLogWatchFrequency()); + assertEquals(0, _options.getManagementModeRmiPort()); } - public void testOverridenLogWatchFrequency() + public void testOverriddenDefaultManagementModeRmiPort() { - final int myFreq = 10 * 1000; - - _options.setLogWatchFrequency(myFreq); - assertEquals(myFreq, _options.getLogWatchFrequency()); + _options.setManagementModeRmiPort(5555); + assertEquals(5555, _options.getManagementModeRmiPort()); } - public void testDefaultIncludesPortFor0_10() + public void testDefaultManagementModeConnectorPort() { - assertEquals(Collections.EMPTY_SET, _options.getIncludedPorts(ProtocolInclusion.v0_10)); + assertEquals(0, _options.getManagementModeConnectorPort()); } - public void testOverriddenIncludesPortFor0_10() + public void testOverriddenDefaultManagementModeConnectorPort() { - _options.addIncludedPort(ProtocolInclusion.v0_10, TEST_PORT1); - assertEquals(Collections.singleton(TEST_PORT1), _options.getIncludedPorts(ProtocolInclusion.v0_10)); + _options.setManagementModeConnectorPort(5555); + assertEquals(5555, _options.getManagementModeConnectorPort()); } - public void testManyOverriddenIncludedPortFor0_10() + public void testDefaultManagementModeHttpPort() { - _options.addIncludedPort(ProtocolInclusion.v0_10, TEST_PORT1); - _options.addIncludedPort(ProtocolInclusion.v0_10, TEST_PORT2); - final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2})); - assertEquals(expectedPorts, _options.getIncludedPorts(ProtocolInclusion.v0_10)); + assertEquals(0, _options.getManagementModeHttpPort()); } - public void testDuplicatedOverriddenIncludedPortFor0_10AreSilentlyIgnored() + public void testOverriddenDefaultManagementModeHttpPort() { - _options.addIncludedPort(ProtocolInclusion.v0_10, TEST_PORT1); - _options.addIncludedPort(ProtocolInclusion.v0_10, TEST_PORT2); - final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2})); - assertEquals(expectedPorts, _options.getIncludedPorts(ProtocolInclusion.v0_10)); + _options.setManagementModeHttpPort(5555); + assertEquals(5555, _options.getManagementModeHttpPort()); } + } diff --git a/java/broker/src/test/java/org/apache/qpid/server/MainTest.java b/java/broker/src/test/java/org/apache/qpid/server/MainTest.java index ffd607574e..cab54b1310 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/MainTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/MainTest.java @@ -23,8 +23,6 @@ package org.apache.qpid.server; import org.apache.commons.cli.CommandLine; import org.apache.qpid.test.utils.QpidTestCase; -import java.util.EnumSet; - /** * Test to verify the command line parsing within the Main class, by * providing it a series of command line arguments and verifying the @@ -36,149 +34,135 @@ public class MainTest extends QpidTestCase { BrokerOptions options = startDummyMain(""); - assertTrue(options.getPorts().isEmpty()); - assertTrue(options.getSSLPorts().isEmpty()); - assertEquals(null, options.getJmxPortRegistryServer()); - assertEquals(null, options.getConfigFile()); + assertEquals("json", options.getConfigurationStoreType()); + assertEquals(null, options.getConfigurationStoreLocation()); assertEquals(null, options.getLogConfigFile()); - assertEquals(null, options.getBind()); - - for(ProtocolExclusion pe : EnumSet.allOf(ProtocolExclusion.class)) - { - assertEquals(0, options.getExcludedPorts(pe).size()); - } + assertEquals(0, options.getLogWatchFrequency()); + assertEquals("json", options.getInitialConfigurationStoreType()); + assertEquals(null, options.getInitialConfigurationStoreLocation()); - for(ProtocolInclusion pe : EnumSet.allOf(ProtocolInclusion.class)) - { - assertEquals(0, options.getIncludedPorts(pe).size()); - } + assertFalse(options.isManagementMode()); + assertEquals(0, options.getManagementModeConnectorPort()); + assertEquals(0, options.getManagementModeRmiPort()); + assertEquals(0, options.getManagementModeHttpPort()); } - public void testPortOverriddenSingle() + public void testConfigurationStoreLocation() { - BrokerOptions options = startDummyMain("-p 1234"); + BrokerOptions options = startDummyMain("-sp abcd/config.xml"); + assertEquals("abcd/config.xml", options.getConfigurationStoreLocation()); - assertTrue(options.getPorts().contains(1234)); - assertEquals(1, options.getPorts().size()); - assertTrue(options.getSSLPorts().isEmpty()); + options = startDummyMain("-store-path abcd/config2.xml"); + assertEquals("abcd/config2.xml", options.getConfigurationStoreLocation()); } - public void testPortOverriddenMultiple() + public void testConfigurationStoreType() { - BrokerOptions options = startDummyMain("-p 1234 -p 4321"); + BrokerOptions options = startDummyMain("-st dby"); + assertEquals("dby", options.getConfigurationStoreType()); - assertTrue(options.getPorts().contains(1234)); - assertTrue(options.getPorts().contains(4321)); - assertEquals(2, options.getPorts().size()); - assertTrue(options.getSSLPorts().isEmpty()); + options = startDummyMain("-store-type bdb"); + assertEquals("bdb", options.getConfigurationStoreType()); } - public void testSSLPortOverriddenSingle() + public void testLogConfig() { - BrokerOptions options = startDummyMain("-s 5678"); + BrokerOptions options = startDummyMain("-l wxyz/log4j.xml"); - assertTrue(options.getSSLPorts().contains(5678)); - assertEquals(1, options.getSSLPorts().size()); - assertTrue(options.getPorts().isEmpty()); + assertEquals("wxyz/log4j.xml", options.getLogConfigFile()); } - public void testSSLPortOverriddenMultiple() + public void testLogWatch() { - BrokerOptions options = startDummyMain("-s 5678 -s 8765"); + BrokerOptions options = startDummyMain("-w 9"); - assertTrue(options.getSSLPorts().contains(5678)); - assertTrue(options.getSSLPorts().contains(8765)); - assertEquals(2, options.getSSLPorts().size()); - assertTrue(options.getPorts().isEmpty()); + assertEquals(9, options.getLogWatchFrequency()); } - public void testNonSSLandSSLPortsOverridden() + public void testVersion() { - BrokerOptions options = startDummyMain("-p 5678 -s 8765"); + final TestMain main = new TestMain("-v".split("\\s")); - assertTrue(options.getPorts().contains(5678)); - assertTrue(options.getSSLPorts().contains(8765)); - assertEquals(1, options.getPorts().size()); - assertEquals(1, options.getSSLPorts().size()); + assertNotNull("Command line not parsed correctly", main.getCommandLine()); + assertTrue("Parsed command line didnt pick up version option", main.getCommandLine().hasOption("v")); } - public void testJmxPortRegistryServerOverridden() + public void testHelp() { - BrokerOptions options = startDummyMain("--jmxregistryport 3456"); - - assertEquals(Integer.valueOf(3456), options.getJmxPortRegistryServer()); + final TestMain main = new TestMain("-h".split("\\s")); - options = startDummyMain("-m 3457"); - assertEquals(Integer.valueOf(3457), options.getJmxPortRegistryServer()); + assertNotNull("Command line not parsed correctly", main.getCommandLine()); + assertTrue("Parsed command line didnt pick up help option", main.getCommandLine().hasOption("h")); } - public void testJmxPortConnectorServerOverridden() + public void testInitailConfigurationStoreLocation() { - BrokerOptions options = startDummyMain("--jmxconnectorport 3456"); + BrokerOptions options = startDummyMain("-isp abcd/config.xml"); + assertEquals("abcd/config.xml", options.getInitialConfigurationStoreLocation()); - assertEquals(Integer.valueOf(3456), options.getJmxPortConnectorServer()); + options = startDummyMain("-initial-store-path abcd/config.xml"); + assertEquals("abcd/config.xml", options.getInitialConfigurationStoreLocation()); } - public void testExclude0_10() + public void testInitialConfigurationStoreType() { - BrokerOptions options = startDummyMain("-p 3456 --exclude-0-10 3456"); + BrokerOptions options = startDummyMain("-ist dby"); + assertEquals("dby", options.getInitialConfigurationStoreType()); - assertTrue(options.getPorts().contains(3456)); - assertEquals(1, options.getPorts().size()); - assertTrue(options.getExcludedPorts(ProtocolExclusion.v0_10).contains(3456)); - assertEquals(1, options.getExcludedPorts(ProtocolExclusion.v0_10).size()); - assertEquals(0, options.getExcludedPorts(ProtocolExclusion.v0_9_1).size()); - } - - public void testConfig() - { - BrokerOptions options = startDummyMain("-c abcd/config.xml"); + options = startDummyMain("-initial-store-type bdb"); + assertEquals("bdb", options.getInitialConfigurationStoreType()); - assertEquals("abcd/config.xml", options.getConfigFile()); } - public void testLogConfig() + public void testManagementMode() { - BrokerOptions options = startDummyMain("-l wxyz/log4j.xml"); + BrokerOptions options = startDummyMain("-mm"); + assertTrue(options.isManagementMode()); - assertEquals("wxyz/log4j.xml", options.getLogConfigFile()); + options = startDummyMain("--management-mode"); + assertTrue(options.isManagementMode()); } - public void testLogWatch() + public void testManagementModeRmiPort() { - BrokerOptions options = startDummyMain("-w 9"); + BrokerOptions options = startDummyMain("-mm -rmi 7777"); + assertTrue(options.isManagementMode()); + assertEquals(7777, options.getManagementModeRmiPort()); - assertEquals(9, options.getLogWatchFrequency()); + options = startDummyMain("-mm --jmxregistryport 7777"); + assertTrue(options.isManagementMode()); + assertEquals(7777, options.getManagementModeRmiPort()); + + options = startDummyMain("-rmi 7777"); + assertEquals(0, options.getManagementModeRmiPort()); } - public void testVersion() + public void testManagementModeConnectorPort() { - final TestMain main = new TestMain("-v".split("\\s")); + BrokerOptions options = startDummyMain("-mm -jmxrmi 8888"); + assertTrue(options.isManagementMode()); + assertEquals(8888, options.getManagementModeConnectorPort()); - assertNotNull("Command line not parsed correctly", main.getCommandLine()); - assertTrue("Parsed command line didnt pick up version option", main.getCommandLine().hasOption("v")); + options = startDummyMain("-mm --jmxconnectorport 8888"); + assertTrue(options.isManagementMode()); + assertEquals(8888, options.getManagementModeConnectorPort()); + + options = startDummyMain("-jmxrmi 8888"); + assertEquals(0, options.getManagementModeConnectorPort()); } - public void testHelp() + public void testManagementModeHttpPort() { - final TestMain main = new TestMain("-h".split("\\s")); + BrokerOptions options = startDummyMain("-mm -http 9999"); + assertTrue(options.isManagementMode()); + assertEquals(9999, options.getManagementModeHttpPort()); - assertNotNull("Command line not parsed correctly", main.getCommandLine()); - assertTrue("Parsed command line didnt pick up help option", main.getCommandLine().hasOption("h")); - } + options = startDummyMain("-mm --httpport 9999"); + assertTrue(options.isManagementMode()); + assertEquals(9999, options.getManagementModeHttpPort()); - public void testInclude010() - { - BrokerOptions options = startDummyMain("-p 5678 --include-0-10 5678"); - - assertTrue(options.getPorts().contains(5678)); - assertEquals(1, options.getPorts().size()); - assertTrue(options.getIncludedPorts(ProtocolInclusion.v0_10).contains(5678)); - assertEquals(1, options.getIncludedPorts(ProtocolInclusion.v0_10).size()); - assertEquals(0, options.getIncludedPorts(ProtocolInclusion.v0_9_1).size()); - assertEquals(0, options.getIncludedPorts(ProtocolInclusion.v0_9).size()); - assertEquals(0, options.getIncludedPorts(ProtocolInclusion.v0_8).size()); - assertEquals(0, options.getIncludedPorts(ProtocolInclusion.v1_0).size()); + options = startDummyMain("-http 9999"); + assertEquals(0, options.getManagementModeHttpPort()); } private BrokerOptions startDummyMain(String commandLine) diff --git a/java/broker/src/test/java/org/apache/qpid/server/TransactionTimeoutHelperTest.java b/java/broker/src/test/java/org/apache/qpid/server/TransactionTimeoutHelperTest.java index 9081dc49d6..96078d766c 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/TransactionTimeoutHelperTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/TransactionTimeoutHelperTest.java @@ -18,67 +18,131 @@ */ package org.apache.qpid.server; -import static org.mockito.Matchers.any; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.apache.qpid.server.logging.messages.ChannelMessages.IDLE_TXN_LOG_HIERARCHY; +import static org.apache.qpid.server.logging.messages.ChannelMessages.OPEN_TXN_LOG_HIERARCHY; +import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.same; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; +import org.apache.qpid.server.TransactionTimeoutHelper.CloseAction; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.LogMessage; import org.apache.qpid.server.logging.LogSubject; -import org.apache.qpid.server.logging.RootMessageLogger; import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.txn.ServerTransaction; import org.apache.qpid.test.utils.QpidTestCase; +import org.hamcrest.Description; +import org.mockito.ArgumentMatcher; public class TransactionTimeoutHelperTest extends QpidTestCase { - private final LogMessage _logMessage = mock(LogMessage.class); private final LogActor _logActor = mock(LogActor.class); private final LogSubject _logSubject = mock(LogSubject.class); + private final ServerTransaction _transaction = mock(ServerTransaction.class); + private final CloseAction _closeAction = mock(CloseAction.class); private TransactionTimeoutHelper _transactionTimeoutHelper; - private RootMessageLogger _rootMessageLogger; + private long _now; - public void testLogIfNecessary() + public void testNotTransactional() throws Exception { - _transactionTimeoutHelper.logIfNecessary(99, 100, _logMessage, ""); - verifyZeroInteractions(_logActor, _logMessage); + when(_transaction.isTransactional()).thenReturn(false); - _transactionTimeoutHelper.logIfNecessary(101, 100, _logMessage, ""); - verify(_logActor).message(_logSubject, _logMessage); + _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 5, 10, 5, 10); + + verifyZeroInteractions(_logActor, _closeAction); + } + + public void testOpenTransactionProducesWarningOnly() throws Exception + { + final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61); + + configureMockTransaction(sixtyOneSecondsAgo, sixtyOneSecondsAgo); + + _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, SECONDS.toMillis(30), 0, 0, 0); + + verify(_logActor).message(same(_logSubject), isLogMessage(OPEN_TXN_LOG_HIERARCHY, "CHN-1007 : Open Transaction : 61,\\d{3} ms")); + verifyZeroInteractions(_closeAction); + } + + public void testOpenTransactionProducesTimeoutActionOnly() throws Exception + { + final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61); + + configureMockTransaction(sixtyOneSecondsAgo, sixtyOneSecondsAgo); + + _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 0, SECONDS.toMillis(30), 0, 0); + + verify(_closeAction).doTimeoutAction("Open transaction timed out"); + verifyZeroInteractions(_logActor); } - public void testLogIfNecessaryWhenOperationalLoggingDisabled() + public void testOpenTransactionProducesWarningAndTimeoutAction() throws Exception { - //disable the operational logging - when(_rootMessageLogger.isMessageEnabled( - same(_logActor), any(LogSubject.class), any(String.class))) - .thenReturn(false); - - //verify the actor is never asked to log a message - _transactionTimeoutHelper.logIfNecessary(101, 100, _logMessage, ""); - verify(_logActor, never()).message(any(LogMessage.class)); - verify(_logActor, never()).message(any(LogSubject.class), any(LogMessage.class)); + final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61); + + configureMockTransaction(sixtyOneSecondsAgo, sixtyOneSecondsAgo); + + _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, SECONDS.toMillis(15), SECONDS.toMillis(30), 0, 0); + + verify(_logActor).message(same(_logSubject), isLogMessage(OPEN_TXN_LOG_HIERARCHY, "CHN-1007 : Open Transaction : 61,\\d{3} ms")); + verify(_closeAction).doTimeoutAction("Open transaction timed out"); } - public void testIsTimedOut() + public void testIdleTransactionProducesWarningOnly() throws Exception { - assertFalse("Shouldn't have timed out", _transactionTimeoutHelper.isTimedOut(199,200)); - assertTrue("Should have timed out", _transactionTimeoutHelper.isTimedOut(201,200)); + final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61); + final long thrityOneSecondsAgo = _now - SECONDS.toMillis(31); + + configureMockTransaction(sixtyOneSecondsAgo, thrityOneSecondsAgo); + + _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 0, 0, SECONDS.toMillis(30), 0); + + verify(_logActor).message(same(_logSubject), isLogMessage(IDLE_TXN_LOG_HIERARCHY, "CHN-1008 : Idle Transaction : 31,\\d{3} ms")); + verifyZeroInteractions(_closeAction); } - /** - * If TransactionTimeout is disabled, the timeout will be 0. This test verifies - * that the helper methods respond negatively in this scenario. - */ - public void testTransactionTimeoutDisabled() + public void testIdleTransactionProducesTimeoutActionOnly() throws Exception { - assertFalse("Shouldn't have timed out", _transactionTimeoutHelper.isTimedOut(201,0)); + final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61); + final long thrityOneSecondsAgo = _now - SECONDS.toMillis(31); + + configureMockTransaction(sixtyOneSecondsAgo, thrityOneSecondsAgo); - _transactionTimeoutHelper.logIfNecessary(99, 0, _logMessage, ""); - verifyZeroInteractions(_logActor, _logMessage); + _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 0, 0, 0, SECONDS.toMillis(30)); + + verify(_closeAction).doTimeoutAction("Idle transaction timed out"); + verifyZeroInteractions(_logActor); + } + + public void testIdleTransactionProducesWarningAndTimeoutAction() throws Exception + { + final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61); + final long thrityOneSecondsAgo = _now - SECONDS.toMillis(31); + + configureMockTransaction(sixtyOneSecondsAgo, thrityOneSecondsAgo); + + _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 0, 0, SECONDS.toMillis(15), SECONDS.toMillis(30)); + + verify(_logActor).message(same(_logSubject), isLogMessage(IDLE_TXN_LOG_HIERARCHY, "CHN-1008 : Idle Transaction : 31,\\d{3} ms")); + verify(_closeAction).doTimeoutAction("Idle transaction timed out"); + } + + public void testIdleAndOpenWarnings() throws Exception + { + final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61); + final long thirtyOneSecondsAgo = _now - SECONDS.toMillis(31); + + configureMockTransaction(sixtyOneSecondsAgo, thirtyOneSecondsAgo); + + _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, SECONDS.toMillis(60), 0, SECONDS.toMillis(30), 0); + + verify(_logActor).message(same(_logSubject), isLogMessage(IDLE_TXN_LOG_HIERARCHY, "CHN-1008 : Idle Transaction : 31,\\d{3} ms")); + verify(_logActor).message(same(_logSubject), isLogMessage(OPEN_TXN_LOG_HIERARCHY, "CHN-1007 : Open Transaction : 61,\\d{3} ms")); + verifyZeroInteractions(_closeAction); } @Override @@ -88,14 +152,79 @@ public class TransactionTimeoutHelperTest extends QpidTestCase CurrentActor.set(_logActor); - _rootMessageLogger = mock(RootMessageLogger.class); - when(_logActor.getRootMessageLogger()).thenReturn(_rootMessageLogger); + _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject, _closeAction); + _now = System.currentTimeMillis(); + } + + @Override + protected void tearDown() throws Exception + { + try + { + super.tearDown(); + } + finally + { + CurrentActor.remove(); + } + } - when(_rootMessageLogger.isMessageEnabled( - same(_logActor), any(LogSubject.class), any(String.class))) - .thenReturn(true); + private void configureMockTransaction(final long startTime, final long updateTime) + { + when(_transaction.isTransactional()).thenReturn(true); + when(_transaction.getTransactionStartTime()).thenReturn(startTime); + when(_transaction.getTransactionUpdateTime()).thenReturn(updateTime); + } - _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject); + private LogMessage isLogMessage(String expectedlogHierarchy, String expectedText) + { + return argThat(new IsLogMessage(expectedlogHierarchy, expectedText)); } + class IsLogMessage extends ArgumentMatcher<LogMessage> + { + private final String _expectedLogHierarchy; + private final String _expectedLogMessageMatches; + private String _hierarchyMatchesFailure; + private String _logMessageMatchesFailure; + + public IsLogMessage(String expectedlogHierarchy, String expectedLogMessageMatches) + { + _expectedLogHierarchy = expectedlogHierarchy; + _expectedLogMessageMatches = expectedLogMessageMatches; + } + + public boolean matches(Object arg) + { + LogMessage logMessage = (LogMessage)arg; + + boolean hierarchyMatches = logMessage.getLogHierarchy().equals(_expectedLogHierarchy); + boolean logMessageMatches = logMessage.toString().matches(_expectedLogMessageMatches); + + if (!hierarchyMatches) + { + _hierarchyMatchesFailure = "LogHierarchy does not match. Expected " + _expectedLogHierarchy + " actual " + logMessage.getLogHierarchy(); + } + + if (!logMessageMatches) + { + _logMessageMatchesFailure = "LogMessage does not match. Expected " + _expectedLogMessageMatches + " actual " + logMessage.toString(); + } + + return hierarchyMatches && logMessageMatches; + } + + @Override + public void describeTo(Description description) + { + if (_hierarchyMatchesFailure != null) + { + description.appendText(_hierarchyMatchesFailure); + } + if (_logMessageMatchesFailure != null) + { + description.appendText(_logMessageMatchesFailure); + } + } + } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/ack/AcknowledgeTest.java b/java/broker/src/test/java/org/apache/qpid/server/ack/AcknowledgeTest.java index b3223f16c4..4d6d60906d 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/ack/AcknowledgeTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/ack/AcknowledgeTest.java @@ -22,14 +22,72 @@ package org.apache.qpid.server.ack; import org.apache.qpid.AMQException; +import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.AMQChannel; +import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.protocol.InternalTestProtocolSession; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.server.queue.SimpleAMQQueue; +import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.store.TestableMemoryMessageStore; +import org.apache.qpid.server.util.BrokerTestHelper; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.test.utils.QpidTestCase; import java.util.List; -public class AcknowledgeTest extends InternalBrokerBaseCase +public class AcknowledgeTest extends QpidTestCase { + private AMQChannel _channel; + private SimpleAMQQueue _queue; + private MessageStore _messageStore; + private String _queueName; + + @Override + public void setUp() throws Exception + { + super.setUp(); + BrokerTestHelper.setUp(); + _channel = BrokerTestHelper.createChannel(); + VirtualHost virtualHost = _channel.getVirtualHost(); + _queueName = getTestName(); + _queue = BrokerTestHelper.createQueue(_queueName, virtualHost); + _messageStore = virtualHost.getMessageStore(); + Exchange defaultExchange = virtualHost.getExchangeRegistry().getDefaultExchange(); + virtualHost.getBindingFactory().addBinding(_queueName, _queue, defaultExchange, null); + } + + @Override + public void tearDown() throws Exception + { + try + { + if (_channel != null) + { + _channel.getVirtualHost().close(); + } + } + finally + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } + } + + private AMQChannel getChannel() + { + return _channel; + } + + private InternalTestProtocolSession getSession() + { + return (InternalTestProtocolSession)_channel.getProtocolSession(); + } + + private SimpleAMQQueue getQueue() + { + return _queue; + } public void testTransactionalSingleAck() throws AMQException { @@ -70,7 +128,7 @@ public class AcknowledgeTest extends InternalBrokerBaseCase checkStoreContents(0); //Send required messsages to the queue - publishMessages(getSession(), getChannel(), sendMessageCount); + BrokerTestHelper.publishMessages(getChannel(), sendMessageCount, _queueName, ExchangeDefaults.DEFAULT_EXCHANGE_NAME.asString()); if (getChannel().isTransactional()) { @@ -84,7 +142,7 @@ public class AcknowledgeTest extends InternalBrokerBaseCase assertEquals("Channel should have no unacked msgs ", 0, getChannel().getUnacknowledgedMessageMap().size()); //Subscribe to the queue - AMQShortString subscriber = subscribe(getSession(), getChannel(), getQueue()); + AMQShortString subscriber = _channel.subscribeToQueue(null, _queue, true, null, false, true); getQueue().deliverAsync(); @@ -117,4 +175,9 @@ public class AcknowledgeTest extends InternalBrokerBaseCase checkStoreContents(remainingUnackedMessages); } + private void checkStoreContents(int messageCount) + { + assertEquals("Message header count incorrect in the MetaDataMap", messageCount, ((TestableMemoryMessageStore) _messageStore).getMessageCount()); + } + } diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java new file mode 100644 index 0000000000..fa1bd966a7 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java @@ -0,0 +1,144 @@ +/* + * + * 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.configuration; + +import java.io.File; +import java.io.StringWriter; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.test.utils.QpidTestCase; +import org.apache.qpid.test.utils.TestFileUtils; +import org.apache.qpid.util.FileUtils; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.SerializationConfig; + +public class BrokerConfigurationStoreCreatorTest extends QpidTestCase +{ + private File _userStoreLocation; + private BrokerConfigurationStoreCreator _storeCreator; + + public void setUp() throws Exception + { + super.setUp(); + + // check whether QPID_HOME JVM system property is set + if (QPID_HOME == null) + { + // set the properties in order to resolve the defaults store settings + setTestSystemProperty("QPID_HOME", TMP_FOLDER); + } + _storeCreator = new BrokerConfigurationStoreCreator(); + _userStoreLocation = new File(TMP_FOLDER, "_store_" + System.currentTimeMillis() + "_" + getTestName()); + } + + public void tearDown() throws Exception + { + try + { + super.tearDown(); + } + finally + { + if (_userStoreLocation != null) + { + FileUtils.delete(_userStoreLocation, true); + } + } + } + + public void testCreateJsonStore() + { + ConfigurationEntryStore store = _storeCreator.createStore(_userStoreLocation.getAbsolutePath(), "json", null, null); + assertNotNull("Store was not created", store); + assertTrue("File should exists", _userStoreLocation.exists()); + assertTrue("File size should be greater than 0", _userStoreLocation.length() > 0); + JsonConfigurationEntryStore jsonStore = new JsonConfigurationEntryStore(); + jsonStore.open(_userStoreLocation.getAbsolutePath()); + Set<UUID> childrenIds = jsonStore.getRootEntry().getChildrenIds(); + assertFalse("Unexpected children: " + childrenIds, childrenIds.isEmpty()); + } + + public void testCreateJsonStoreFromInitialStore() throws Exception + { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true); + + Map<String, Object> brokerObjectMap = new HashMap<String, Object>(); + UUID brokerId = UUID.randomUUID(); + brokerObjectMap.put(Broker.ID, brokerId); + brokerObjectMap.put("name", "Test"); + + StringWriter sw = new StringWriter(); + objectMapper.writeValue(sw, brokerObjectMap); + + String brokerJson = sw.toString(); + + File _storeFile = TestFileUtils.createTempFile(this, ".json", brokerJson); + + ConfigurationEntryStore store = _storeCreator.createStore(_userStoreLocation.getAbsolutePath(), "json", _storeFile.getAbsolutePath(), "json"); + assertNotNull("Store was not created", store); + assertTrue("File should exists", _userStoreLocation.exists()); + assertTrue("File size should be greater than 0", _userStoreLocation.length() > 0); + JsonConfigurationEntryStore jsonStore = new JsonConfigurationEntryStore(); + jsonStore.open(_userStoreLocation.getAbsolutePath()); + ConfigurationEntry entry = jsonStore.getRootEntry(); + assertEquals("Unexpected root id", brokerId, entry.getId()); + Map<String, Object> attributes = entry.getAttributes(); + assertNotNull("Unexpected attributes: " + attributes, attributes); + assertEquals("Unexpected attributes size: " + attributes.size(), 1, attributes.size()); + assertEquals("Unexpected attribute name: " + attributes.get("name"), "Test", attributes.get("name")); + Set<UUID> childrenIds = entry.getChildrenIds(); + assertTrue("Unexpected children: " + childrenIds, childrenIds.isEmpty()); + } + + public void testCreateDerbyStore() + { + //TODO: Implement DERBY store + try + { + _storeCreator.createStore(_userStoreLocation.getAbsolutePath(), "derby", null, null); + fail("Store is not yet supported"); + } + catch(IllegalConfigurationException e) + { + // pass + } + } + + public void testCreateXmlStore() throws Exception + { + try + { + _storeCreator.createStore(_userStoreLocation.getAbsolutePath(), "xml", null, null); + fail("Store is not yet supported"); + } + catch(IllegalConfigurationException e) + { + // pass + } + } + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerPropertiesTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerPropertiesTest.java new file mode 100644 index 0000000000..5e9e19ffaf --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerPropertiesTest.java @@ -0,0 +1,51 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration; + +import java.util.Locale; + +import org.apache.qpid.test.utils.QpidTestCase; + +public class BrokerPropertiesTest extends QpidTestCase +{ + public void testGetLocaleDefault() + { + Locale locale = BrokerProperties.getLocale(); + assertEquals("Unexpected locale", Locale.US, locale); + } + + public void testGetLocaleSetWithJVMProperty() + { + setTestSystemProperty(BrokerProperties.PROPERTY_LOCALE, "en_GB"); + Locale locale = BrokerProperties.getLocale(); + assertEquals("Unexpected locale", Locale.UK, locale); + } + + public void testGetLocaleSetWithJVMPropertyInUnexpectedFormat() + { + setTestSystemProperty(BrokerProperties.PROPERTY_LOCALE, "penguins_ANTARCTIC_Moubray_Bay"); + Locale locale = BrokerProperties.getLocale(); + assertEquals("Unexpected locale language", "penguins", locale.getLanguage()); + assertEquals("Unexpected locale country", "ANTARCTIC", locale.getCountry()); + assertEquals("Unexpected locale country", "Moubray_Bay", locale.getVariant()); + } + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/MockConnectionConfig.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/MockConnectionConfig.java deleted file mode 100644 index 00e5cd1222..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/configuration/MockConnectionConfig.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * - * 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.configuration; - -import java.util.UUID; - -public class MockConnectionConfig implements ConnectionConfig -{ - - public MockConnectionConfig(UUID _qmfId, ConnectionConfigType _configType, - ConfiguredObject<ConnectionConfigType, ConnectionConfig> _parent, boolean _durable, - long _createTime, VirtualHostConfig _virtualHost, String _address, Boolean _incoming, - Boolean _systemConnection, Boolean _federationLink, String _authId, String _remoteProcessName, - Integer _remotePID, Integer _remoteParentPID, ConfigStore _configStore, Boolean _shadow) - { - super(); - this._qmfId = _qmfId; - this._configType = _configType; - this._parent = _parent; - this._durable = _durable; - this._createTime = _createTime; - this._virtualHost = _virtualHost; - this._address = _address; - this._incoming = _incoming; - this._systemConnection = _systemConnection; - this._federationLink = _federationLink; - this._authId = _authId; - this._remoteProcessName = _remoteProcessName; - this._remotePID = _remotePID; - this._remoteParentPID = _remoteParentPID; - this._configStore = _configStore; - this._shadow = _shadow; - } - - private UUID _qmfId; - private ConnectionConfigType _configType; - private ConfiguredObject<ConnectionConfigType, ConnectionConfig> _parent; - private boolean _durable; - private long _createTime; - private VirtualHostConfig _virtualHost; - private String _address; - private Boolean _incoming; - private Boolean _systemConnection; - private Boolean _federationLink; - private String _authId; - private String _remoteProcessName; - private Integer _remotePID; - private Integer _remoteParentPID; - private ConfigStore _configStore; - private Boolean _shadow; - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - @Override - public ConnectionConfigType getConfigType() - { - return _configType; - } - - @Override - public ConfiguredObject<ConnectionConfigType, ConnectionConfig> getParent() - { - return _parent; - } - - @Override - public boolean isDurable() - { - return _durable; - } - - @Override - public long getCreateTime() - { - return _createTime; - } - - @Override - public VirtualHostConfig getVirtualHost() - { - return _virtualHost; - } - - @Override - public String getAddress() - { - return _address; - } - - @Override - public Boolean isIncoming() - { - return _incoming; - } - - @Override - public Boolean isSystemConnection() - { - return _systemConnection; - } - - @Override - public Boolean isFederationLink() - { - return _federationLink; - } - - @Override - public String getAuthId() - { - return _authId; - } - - @Override - public String getRemoteProcessName() - { - return _remoteProcessName; - } - - @Override - public Integer getRemotePID() - { - return _remotePID; - } - - @Override - public Integer getRemoteParentPID() - { - return _remoteParentPID; - } - - @Override - public ConfigStore getConfigStore() - { - return _configStore; - } - - @Override - public Boolean isShadow() - { - return _shadow; - } - - @Override - public void mgmtClose() - { - } - -} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java index 3c5b85cd90..0bb65479ce 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java @@ -20,25 +20,31 @@ */ package org.apache.qpid.server.configuration; +import static org.mockito.Mockito.when; + import junit.framework.TestCase; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.util.TestApplicationRegistry; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.util.BrokerTestHelper; public class QueueConfigurationTest extends TestCase { - private VirtualHostConfiguration _emptyConf; private PropertiesConfiguration _env; private VirtualHostConfiguration _fullHostConf; + private Broker _broker; + @Override public void setUp() throws Exception { + super.setUp(); + BrokerTestHelper.setUp(); + _broker = BrokerTestHelper.createBrokerMock(); _env = new PropertiesConfiguration(); - _emptyConf = new VirtualHostConfiguration("test", _env); + _emptyConf = new VirtualHostConfiguration("test", _env, _broker); PropertiesConfiguration fullEnv = new PropertiesConfiguration(); fullEnv.setProperty("queues.maximumMessageAge", 1); @@ -49,35 +55,41 @@ public class QueueConfigurationTest extends TestCase fullEnv.setProperty("queues.deadLetterQueues", true); fullEnv.setProperty("queues.maximumDeliveryCount", 5); - _fullHostConf = new VirtualHostConfiguration("test", fullEnv); + _fullHostConf = new VirtualHostConfiguration("test", fullEnv, _broker); } + @Override + public void tearDown() throws Exception + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } + public void testMaxDeliveryCount() throws Exception { - try - { - ApplicationRegistry registry = new TestApplicationRegistry(new ServerConfiguration(_env)); - ApplicationRegistry.initialise(registry); - - // Check default value - QueueConfiguration qConf = new QueueConfiguration("test", _emptyConf); - assertEquals("Unexpected default server configuration for max delivery count ", 0, qConf.getMaxDeliveryCount()); - - // Check explicit value - VirtualHostConfiguration vhostConfig = overrideConfiguration("maximumDeliveryCount", 7); - qConf = new QueueConfiguration("test", vhostConfig); - assertEquals("Unexpected host configuration for max delivery count", 7, qConf.getMaxDeliveryCount()); - - // Check inherited value - qConf = new QueueConfiguration("test", _fullHostConf); - assertEquals("Unexpected queue configuration for max delivery count", 5, qConf.getMaxDeliveryCount()); - - } - finally - { - ApplicationRegistry.remove(); - } + // broker MAXIMUM_DELIVERY_ATTEMPTS attribute is not set + when(_broker.getAttribute(Broker.MAXIMUM_DELIVERY_ATTEMPTS)).thenReturn(null); + + // Check default value + QueueConfiguration qConf = new QueueConfiguration("test", _emptyConf); + assertEquals("Unexpected default server configuration for max delivery count ", 0, qConf.getMaxDeliveryCount()); + + // set broker MAXIMUM_DELIVERY_ATTEMPTS attribute to 2 + when(_broker.getAttribute(Broker.MAXIMUM_DELIVERY_ATTEMPTS)).thenReturn(2); + + // Check that queue inherits the MAXIMUM_DELIVERY_ATTEMPTS value from broker + qConf = new QueueConfiguration("test", _emptyConf); + assertEquals("Unexpected default server configuration for max delivery count ", 2, qConf.getMaxDeliveryCount()); + + // Check explicit value + VirtualHostConfiguration vhostConfig = overrideConfiguration("maximumDeliveryCount", 7); + qConf = new QueueConfiguration("test", vhostConfig); + assertEquals("Unexpected host configuration for max delivery count", 7, qConf.getMaxDeliveryCount()); + + // Check inherited value + qConf = new QueueConfiguration("test", _fullHostConf); + assertEquals("Unexpected queue configuration for max delivery count", 5, qConf.getMaxDeliveryCount()); } /** @@ -87,28 +99,28 @@ public class QueueConfigurationTest extends TestCase */ public void testIsDeadLetterQueueEnabled() throws Exception { - try - { - ApplicationRegistry registry = new TestApplicationRegistry(new ServerConfiguration(_env)); - ApplicationRegistry.initialise(registry); - - // Check default value - QueueConfiguration qConf = new QueueConfiguration("test", _emptyConf); - assertFalse("Unexpected queue configuration for dead letter enabled attribute", qConf.isDeadLetterQueueEnabled()); - - // Check explicit value - VirtualHostConfiguration vhostConfig = overrideConfiguration("deadLetterQueues", true); - qConf = new QueueConfiguration("test", vhostConfig); - assertTrue("Unexpected queue configuration for dead letter enabled attribute", qConf.isDeadLetterQueueEnabled()); - - // Check inherited value - qConf = new QueueConfiguration("test", _fullHostConf); - assertTrue("Unexpected queue configuration for dead letter enabled attribute", qConf.isDeadLetterQueueEnabled()); - } - finally - { - ApplicationRegistry.remove(); - } + // enable dead letter queues broker wide + when(_broker.getAttribute(Broker.DEAD_LETTER_QUEUE_ENABLED)).thenReturn(true); + + // Check that queue inherits the broker setting + QueueConfiguration qConf = new QueueConfiguration("test", _emptyConf); + assertTrue("Unexpected queue configuration for dead letter enabled attribute", qConf.isDeadLetterQueueEnabled()); + + // broker DEAD_LETTER_QUEUE_ENABLED is not set + when(_broker.getAttribute(Broker.DEAD_LETTER_QUEUE_ENABLED)).thenReturn(null); + + // Check that queue dead letter queue is not enabled + qConf = new QueueConfiguration("test", _emptyConf); + assertFalse("Unexpected queue configuration for dead letter enabled attribute", qConf.isDeadLetterQueueEnabled()); + + // Check explicit value + VirtualHostConfiguration vhostConfig = overrideConfiguration("deadLetterQueues", true); + qConf = new QueueConfiguration("test", vhostConfig); + assertTrue("Unexpected queue configuration for dead letter enabled attribute", qConf.isDeadLetterQueueEnabled()); + + // Check inherited value + qConf = new QueueConfiguration("test", _fullHostConf); + assertTrue("Unexpected queue configuration for dead letter enabled attribute", qConf.isDeadLetterQueueEnabled()); } public void testGetMaximumMessageAge() throws ConfigurationException @@ -178,27 +190,28 @@ public class QueueConfigurationTest extends TestCase public void testGetMinimumAlertRepeatGap() throws Exception { - try - { - ApplicationRegistry registry = new TestApplicationRegistry(new ServerConfiguration(_env)); - ApplicationRegistry.initialise(registry); - // Check default value - QueueConfiguration qConf = new QueueConfiguration("test", _emptyConf); - assertEquals(ServerConfiguration.DEFAULT_MINIMUM_ALERT_REPEAT_GAP, qConf.getMinimumAlertRepeatGap()); - - // Check explicit value - VirtualHostConfiguration vhostConfig = overrideConfiguration("minimumAlertRepeatGap", 2); - qConf = new QueueConfiguration("test", vhostConfig); - assertEquals(2, qConf.getMinimumAlertRepeatGap()); - - // Check inherited value - qConf = new QueueConfiguration("test", _fullHostConf); - assertEquals(1, qConf.getMinimumAlertRepeatGap()); - } - finally - { - ApplicationRegistry.remove(); - } + // set broker attribute ALERT_REPEAT_GAP to 10 + when(_broker.getAttribute(Broker.ALERT_REPEAT_GAP)).thenReturn(10); + + // check that broker level setting is available on queue configuration + QueueConfiguration qConf = new QueueConfiguration("test", _emptyConf); + assertEquals(10, qConf.getMinimumAlertRepeatGap()); + + // remove configuration for ALERT_REPEAT_GAP on broker level + when(_broker.getAttribute(Broker.ALERT_REPEAT_GAP)).thenReturn(null); + + // Check default value + qConf = new QueueConfiguration("test", _emptyConf); + assertEquals(0, qConf.getMinimumAlertRepeatGap()); + + // Check explicit value + VirtualHostConfiguration vhostConfig = overrideConfiguration("minimumAlertRepeatGap", 2); + qConf = new QueueConfiguration("test", vhostConfig); + assertEquals(2, qConf.getMinimumAlertRepeatGap()); + + // Check inherited value + qConf = new QueueConfiguration("test", _fullHostConf); + assertEquals(1, qConf.getMinimumAlertRepeatGap()); } public void testSortQueueConfiguration() throws ConfigurationException @@ -235,6 +248,6 @@ public class QueueConfigurationTest extends TestCase config.addConfiguration(_fullHostConf.getConfig()); config.addConfiguration(queueConfig); - return new VirtualHostConfiguration("test", config); + return new VirtualHostConfiguration("test", config, _broker); } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java deleted file mode 100644 index 660ff5e7d4..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java +++ /dev/null @@ -1,1766 +0,0 @@ -/* - * - * 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.configuration; - -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.XMLConfiguration; - -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.protocol.AmqpProtocolVersion; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry; -import org.apache.qpid.server.util.TestApplicationRegistry; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.virtualhost.VirtualHostRegistry; -import org.apache.qpid.test.utils.QpidTestCase; - -import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; -import java.util.Locale; - -import javax.net.ssl.KeyManagerFactory; - -public class ServerConfigurationTest extends QpidTestCase -{ - private XMLConfiguration _config = new XMLConfiguration(); - private ServerConfiguration _serverConfig = null; - - @Override - protected void setUp() throws Exception - { - super.setUp(); - _serverConfig = new ServerConfiguration(_config); - ApplicationRegistry.initialise(new TestApplicationRegistry(_serverConfig)); - } - - @Override - protected void tearDown() throws Exception - { - super.tearDown(); - ApplicationRegistry.remove(); - } - - public void testSetJMXPortRegistryServer() throws ConfigurationException - { - _serverConfig.initialise(); - _serverConfig.setJMXPortRegistryServer(23); - assertEquals(23, _serverConfig.getJMXPortRegistryServer()); - } - - public void testGetJMXPortRegistryServer() throws ConfigurationException - { - _config.setProperty(ServerConfiguration.MGMT_JMXPORT_REGISTRYSERVER, 42); - _serverConfig.initialise(); - assertEquals(42, _serverConfig.getJMXPortRegistryServer()); - } - - public void testDefaultJMXPortRegistryServer() throws ConfigurationException - { - _serverConfig.initialise(); - assertEquals(8999, _serverConfig.getJMXPortRegistryServer()); - } - - public void testSetJMXPortConnectorServer() throws ConfigurationException - { - ServerConfiguration serverConfig = new ServerConfiguration(_config); - serverConfig.setJMXPortConnectorServer(67); - assertEquals(67, serverConfig.getJMXConnectorServerPort()); - } - - public void testGetJMXPortConnectorServer() throws ConfigurationException - { - _config.setProperty(ServerConfiguration.MGMT_JMXPORT_CONNECTORSERVER, 67); - ServerConfiguration serverConfig = new ServerConfiguration(_config); - assertEquals(67, serverConfig.getJMXConnectorServerPort()); - } - - public void testDefaultJMXPortConnectorServer() throws ConfigurationException - { - ServerConfiguration serverConfig = new ServerConfiguration(_config); - assertEquals(ServerConfiguration.DEFAULT_JMXPORT_REGISTRYSERVER + ServerConfiguration.JMXPORT_CONNECTORSERVER_OFFSET, - serverConfig.getJMXConnectorServerPort()); - } - - public void testGetPlatformMbeanserver() throws ConfigurationException - { - _serverConfig.initialise(); - assertEquals(true, _serverConfig.getPlatformMbeanserver()); - - // Check value we set - _config.setProperty("management.platform-mbeanserver", false); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(false, _serverConfig.getPlatformMbeanserver()); - } - - public void testGetPluginDirectory() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(null, _serverConfig.getPluginDirectory()); - - // Check value we set - _config.setProperty("plugin-directory", "/path/to/plugins"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals("/path/to/plugins", _serverConfig.getPluginDirectory()); - } - - public void testGetCacheDirectory() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(null, _serverConfig.getCacheDirectory()); - - // Check value we set - _config.setProperty("cache-directory", "/path/to/cache"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals("/path/to/cache", _serverConfig.getCacheDirectory()); - } - - public void testGetFrameSize() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(65536, _serverConfig.getFrameSize()); - - // Check value we set - _config.setProperty("advanced.framesize", "23"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(23, _serverConfig.getFrameSize()); - } - - public void testGetStatusEnabled() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(ServerConfiguration.DEFAULT_STATUS_UPDATES.equalsIgnoreCase("on"), - _serverConfig.getStatusUpdatesEnabled()); - - // Check disabling we set - _config.setProperty(ServerConfiguration.STATUS_UPDATES, "off"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(false, _serverConfig.getStatusUpdatesEnabled()); - - // Check invalid values don't cause error but result in disabled - _config.setProperty(ServerConfiguration.STATUS_UPDATES, "Yes Please"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(false, _serverConfig.getStatusUpdatesEnabled()); - - } - public void testGetSynchedClocks() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(false, _serverConfig.getSynchedClocks()); - - // Check value we set - _config.setProperty("advanced.synced-clocks", true); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(true, _serverConfig.getSynchedClocks()); - } - - public void testGetLocale() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - - // The Default is what ever the VMs default is - Locale defaultLocale = Locale.getDefault(); - - assertEquals(defaultLocale, _serverConfig.getLocale()); - - - //Test Language only - Locale update = new Locale("es"); - _config.setProperty(ServerConfiguration.ADVANCED_LOCALE, "es"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(update, _serverConfig.getLocale()); - - //Test Language and Country - update = new Locale("es","ES"); - _config.setProperty(ServerConfiguration.ADVANCED_LOCALE, "es_ES"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(update, _serverConfig.getLocale()); - - //Test Language and Country and Variant - update = new Locale("es","ES", "Traditional_WIN"); - _config.setProperty(ServerConfiguration.ADVANCED_LOCALE, "es_ES_Traditional_WIN"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(update, _serverConfig.getLocale()); - } - - - public void testGetMsgAuth() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(false, _serverConfig.getMsgAuth()); - - // Check value we set - _config.setProperty("security.msg-auth", true); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(true, _serverConfig.getMsgAuth()); - } - - public void testGetManagementKeyStorePath() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(null, _serverConfig.getManagementKeyStorePath()); - - // Check value we set - _config.setProperty("management.ssl.keyStorePath", "a"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals("a", _serverConfig.getManagementKeyStorePath()); - } - - public void testGetManagementSSLEnabled() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(false, _serverConfig.getManagementSSLEnabled()); - - // Check value we set - _config.setProperty("management.ssl.enabled", true); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(true, _serverConfig.getManagementSSLEnabled()); - } - - public void testGetManagementKeystorePassword() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(null, _serverConfig.getManagementKeyStorePassword()); - - // Check value we set - _config.setProperty("management.ssl.keyStorePassword", "a"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals("a", _serverConfig.getManagementKeyStorePassword()); - } - - public void testGetQueueAutoRegister() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(true, _serverConfig.getQueueAutoRegister()); - - // Check value we set - _config.setProperty("queue.auto_register", false); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(false, _serverConfig.getQueueAutoRegister()); - } - - public void testGetJMXManagementEnabled() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(true, _serverConfig.getJMXManagementEnabled()); - - // Check value we set - _config.setProperty("management.enabled", false); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(false, _serverConfig.getJMXManagementEnabled()); - } - - public void testGetManagementRightsInferAllAccess() throws Exception - { - _serverConfig.initialise(); - - //check default - assertTrue("default should be true", _serverConfig.getManagementRightsInferAllAccess()); - - //update it - _config.setProperty("management.managementRightsInferAllAccess", "false"); - assertFalse("New value should be false", _serverConfig.getManagementRightsInferAllAccess()); - } - - public void testGetHeartBeatDelay() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(5, _serverConfig.getHeartBeatDelay()); - - // Check value we set - _config.setProperty("heartbeat.delay", 23); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(23, _serverConfig.getHeartBeatDelay()); - } - - public void testGetHeartBeatTimeout() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(2.0, _serverConfig.getHeartBeatTimeout()); - - // Check value we set - _config.setProperty("heartbeat.timeoutFactor", 2.3); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(2.3, _serverConfig.getHeartBeatTimeout()); - } - - public void testGetMaximumMessageAge() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(0, _serverConfig.getMaximumMessageAge()); - - // Check value we set - _config.setProperty("maximumMessageAge", 10L); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(10, _serverConfig.getMaximumMessageAge()); - } - - public void testGetMaximumMessageCount() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(0, _serverConfig.getMaximumMessageCount()); - - // Check value we set - _config.setProperty("maximumMessageCount", 10L); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(10, _serverConfig.getMaximumMessageCount()); - } - - public void testGetMaximumQueueDepth() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(0, _serverConfig.getMaximumQueueDepth()); - - // Check value we set - _config.setProperty("maximumQueueDepth", 10L); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(10, _serverConfig.getMaximumQueueDepth()); - } - - public void testGetMaximumMessageSize() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(0, _serverConfig.getMaximumMessageSize()); - - // Check value we set - _config.setProperty("maximumMessageSize", 10L); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(10, _serverConfig.getMaximumMessageSize()); - } - - public void testGetMinimumAlertRepeatGap() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(30000l, _serverConfig.getMinimumAlertRepeatGap()); - - // Check value we set - _config.setProperty("minimumAlertRepeatGap", 10L); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(10, _serverConfig.getMinimumAlertRepeatGap()); - } - - public void testGetProcessors() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(4, _serverConfig.getConnectorProcessors()); - - // Check value we set - _config.setProperty("connector.processors", 10); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(10, _serverConfig.getConnectorProcessors()); - } - - public void testGetPorts() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertNotNull(_serverConfig.getPorts()); - assertEquals(1, _serverConfig.getPorts().size()); - assertEquals(5672, _serverConfig.getPorts().get(0)); - - - // Check value we set - _config.setProperty("connector.port", "10"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertNotNull(_serverConfig.getPorts()); - assertEquals(1, _serverConfig.getPorts().size()); - assertEquals("10", _serverConfig.getPorts().get(0)); - } - - public void testGetBind() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(WILDCARD_ADDRESS, _serverConfig.getBind()); - - // Check value we set - _config.setProperty("connector.bind", "a"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals("a", _serverConfig.getBind()); - } - - public void testGetReceiveBufferSize() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(ServerConfiguration.DEFAULT_BUFFER_SIZE, _serverConfig.getReceiveBufferSize()); - - // Check value we set - _config.setProperty("connector.socketReceiveBuffer", "23"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(23, _serverConfig.getReceiveBufferSize()); - } - - public void testGetWriteBufferSize() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(ServerConfiguration.DEFAULT_BUFFER_SIZE, _serverConfig.getWriteBufferSize()); - - // Check value we set - _config.setProperty("connector.socketWriteBuffer", "23"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(23, _serverConfig.getWriteBufferSize()); - } - - public void testGetTcpNoDelay() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(true, _serverConfig.getTcpNoDelay()); - - // Check value we set - _config.setProperty("connector.tcpNoDelay", false); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(false, _serverConfig.getTcpNoDelay()); - } - - public void testGetEnableSSL() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(false, _serverConfig.getEnableSSL()); - - // Check value we set - _config.setProperty("connector.ssl.enabled", true); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(true, _serverConfig.getEnableSSL()); - } - - public void testGetSSLOnly() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(false, _serverConfig.getSSLOnly()); - - // Check value we set - _config.setProperty("connector.ssl.sslOnly", true); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(true, _serverConfig.getSSLOnly()); - } - - public void testGetSSLPorts() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertNotNull(_serverConfig.getSSLPorts()); - assertEquals(1, _serverConfig.getSSLPorts().size()); - assertEquals(ServerConfiguration.DEFAULT_SSL_PORT, _serverConfig.getSSLPorts().get(0)); - - - // Check value we set - _config.setProperty("connector.ssl.port", "10"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertNotNull(_serverConfig.getSSLPorts()); - assertEquals(1, _serverConfig.getSSLPorts().size()); - assertEquals("10", _serverConfig.getSSLPorts().get(0)); - } - - public void testGetConnectorKeystorePath() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertNull(_serverConfig.getConnectorKeyStorePath()); - - // Check value we set - _config.setProperty("connector.ssl.keyStorePath", "a"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals("a", _serverConfig.getConnectorKeyStorePath()); - - // Ensure we continue to support the old name keystorePath - _config.clearProperty("connector.ssl.keyStorePath"); - _config.setProperty("connector.ssl.keystorePath", "b"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals("b", _serverConfig.getConnectorKeyStorePath()); - } - - public void testGetConnectorKeystorePassword() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertNull(_serverConfig.getConnectorKeyStorePassword()); - - // Check value we set - _config.setProperty("connector.ssl.keyStorePassword", "a"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals("a", _serverConfig.getConnectorKeyStorePassword()); - - // Ensure we continue to support the old name keystorePassword - _config.clearProperty("connector.ssl.keyStorePassword"); - _config.setProperty("connector.ssl.keystorePassword", "b"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals("b", _serverConfig.getConnectorKeyStorePassword()); - } - - public void testConnectorGetKeyManagerAlgorithm() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(KeyManagerFactory.getDefaultAlgorithm(), _serverConfig.getConnectorKeyManagerFactoryAlgorithm()); - - // Check value we set - _config.setProperty("connector.ssl.keyManagerFactoryAlgorithm", "a"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals("a", _serverConfig.getConnectorKeyManagerFactoryAlgorithm()); - - // Ensure we continue to support the old name certType - _config.clearProperty("connector.ssl.keyManagerFactoryAlgorithm"); - _config.setProperty("connector.ssl.certType", "b"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals("b", _serverConfig.getConnectorKeyManagerFactoryAlgorithm()); - } - - public void testGetHousekeepingCheckPeriod() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(30000, _serverConfig.getHousekeepingCheckPeriod()); - - // Check value we set - _config.setProperty("housekeeping.checkPeriod", 23L); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - _serverConfig.setHousekeepingCheckPeriod(42L); - assertEquals(42, _serverConfig.getHousekeepingCheckPeriod()); - } - - public void testSingleConfiguration() throws IOException, ConfigurationException - { - File fileA = File.createTempFile(getClass().getName(), null); - fileA.deleteOnExit(); - FileWriter out = new FileWriter(fileA); - out.write("<broker><connector><port>2342</port><ssl><port>4235</port></ssl></connector></broker>"); - out.close(); - ServerConfiguration conf = new ServerConfiguration(fileA); - conf.initialise(); - assertEquals("4235", conf.getSSLPorts().get(0)); - } - - public void testCombinedConfiguration() throws IOException, ConfigurationException - { - File mainFile = File.createTempFile(getClass().getName(), null); - File fileA = File.createTempFile(getClass().getName(), null); - File fileB = File.createTempFile(getClass().getName(), null); - - mainFile.deleteOnExit(); - fileA.deleteOnExit(); - fileB.deleteOnExit(); - - FileWriter out = new FileWriter(mainFile); - out.write("<configuration><system/>"); - out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>"); - out.write("<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>"); - out.write("</configuration>"); - out.close(); - - out = new FileWriter(fileA); - out.write("<broker><connector><port>2342</port><ssl><port>4235</port></ssl></connector></broker>"); - out.close(); - - out = new FileWriter(fileB); - out.write("<broker><connector><ssl><port>2345</port></ssl></connector></broker>"); - out.close(); - - ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); - config.initialise(); - assertEquals("4235", config.getSSLPorts().get(0)); // From first file, not - // overriden by second - assertNotNull(config.getPorts()); - assertEquals(1, config.getPorts().size()); - assertEquals("2342", config.getPorts().get(0)); // From the first file, not - // present in the second - } - - public void testVariableInterpolation() throws Exception - { - File mainFile = File.createTempFile(getClass().getName(), null); - - mainFile.deleteOnExit(); - - FileWriter out = new FileWriter(mainFile); - out.write("<broker>\n"); - out.write("\t<work>foo</work>\n"); - out.write("\t<management><ssl><keyStorePath>${work}</keyStorePath></ssl></management>\n"); - out.write("</broker>\n"); - out.close(); - - ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); - config.initialise(); - assertEquals("Did not get correct interpolated value", - "foo", config.getManagementKeyStorePath()); - } - - private void writeConfigFile(File mainFile, boolean allow) throws IOException { - writeConfigFile(mainFile, allow, true, null, "test"); - } - - private void writeConfigFile(File mainFile, boolean allow, boolean includeVhosts, File vhostsFile, String name) throws IOException { - FileWriter out = new FileWriter(mainFile); - out.write("<broker>\n"); - out.write("\t<management><enabled>false</enabled></management>\n"); - out.write("\t<security>\n"); - out.write("\t\t<pd-auth-manager>\n"); - out.write("\t\t\t<principal-database>\n"); - out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n"); - out.write("\t\t\t\t<attributes>\n"); - out.write("\t\t\t\t\t<attribute>\n"); - out.write("\t\t\t\t\t\t<name>passwordFile</name>\n"); - out.write("\t\t\t\t\t\t<value>/dev/null</value>\n"); - out.write("\t\t\t\t\t</attribute>\n"); - out.write("\t\t\t\t</attributes>\n"); - out.write("\t\t\t</principal-database>\n"); - out.write("\t\t</pd-auth-manager>\n"); - out.write("\t\t<firewall>\n"); - out.write("\t\t\t<rule access=\""+ ((allow) ? "allow" : "deny") +"\" network=\"127.0.0.1\"/>"); - out.write("\t\t</firewall>\n"); - out.write("\t</security>\n"); - if (includeVhosts) - { - out.write("\t<virtualhosts>\n"); - out.write("\t\t<default>test</default>\n"); - out.write("\t\t<virtualhost>\n"); - out.write(String.format("\t\t\t<name>%s</name>\n", name)); - out.write(String.format("\t\t<%s> \n", name)); - out.write("\t\t\t<exchanges>\n"); - out.write("\t\t\t\t<exchange>\n"); - out.write("\t\t\t\t\t<type>topic</type>\n"); - out.write(String.format("\t\t\t\t\t<name>%s.topic</name>\n", name)); - out.write("\t\t\t\t\t<durable>true</durable>\n"); - out.write("\t\t\t\t</exchange>\n"); - out.write("\t\tt</exchanges>\n"); - out.write(String.format("\t\t</%s> \n", name)); - out.write("\t\t</virtualhost>\n"); - out.write("\t</virtualhosts>\n"); - } - if (vhostsFile != null) - { - out.write("\t<virtualhosts>"+vhostsFile.getAbsolutePath()+"</virtualhosts>\n"); - } - out.write("</broker>\n"); - out.close(); - } - - private void writeTestFishConfigFile(File mainFile) throws IOException { - FileWriter out = new FileWriter(mainFile); - out.write("<broker>\n"); - out.write("\t<management><enabled>false</enabled></management>\n"); - out.write("\t<security>\n"); - out.write("\t\t<pd-auth-manager>\n"); - out.write("\t\t\t<principal-database>\n"); - out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n"); - out.write("\t\t\t\t<attributes>\n"); - out.write("\t\t\t\t\t<attribute>\n"); - out.write("\t\t\t\t\t\t<name>passwordFile</name>\n"); - out.write("\t\t\t\t\t\t<value>/dev/null</value>\n"); - out.write("\t\t\t\t\t</attribute>\n"); - out.write("\t\t\t\t</attributes>\n"); - out.write("\t\t\t</principal-database>\n"); - out.write("\t\t</pd-auth-manager>\n"); - out.write("\t\t<firewall>\n"); - out.write("\t\t\t<rule access=\"allow\" network=\"127.0.0.1\"/>"); - out.write("\t\t</firewall>\n"); - out.write("\t</security>\n"); - out.write("\t<virtualhosts>\n"); - out.write("\t\t<virtualhost>\n"); - out.write("\t\t\t<name>test</name>\n"); - out.write("\t\t<test> \n"); - out.write("\t\t\t<exchanges>\n"); - out.write("\t\t\t\t<exchange>\n"); - out.write("\t\t\t\t\t<type>topic</type>\n"); - out.write("\t\t\t\t\t<name>test.topic</name>\n"); - out.write("\t\t\t\t\t<durable>true</durable>\n"); - out.write("\t\t\t\t</exchange>\n"); - out.write("\t\tt</exchanges>\n"); - out.write("\t\t</test> \n"); - out.write("\t\t</virtualhost>\n"); - out.write("\t\t<virtualhost>\n"); - out.write("\t\t\t<name>fish</name>\n"); - out.write("\t\t<fish> \n"); - out.write("\t\t\t<exchanges>\n"); - out.write("\t\t\t\t<exchange>\n"); - out.write("\t\t\t\t\t<type>topic</type>\n"); - out.write("\t\t\t\t\t<name>fish.topic</name>\n"); - out.write("\t\t\t\t\t<durable>false</durable>\n"); - out.write("\t\t\t\t</exchange>\n"); - out.write("\t\tt</exchanges>\n"); - out.write("\t\t</fish> \n"); - out.write("\t\t</virtualhost>\n"); - out.write("\t</virtualhosts>\n"); - out.write("</broker>\n"); - out.close(); - } - - private void writeVirtualHostsFile(File vhostsFile, String name) throws IOException { - FileWriter out = new FileWriter(vhostsFile); - out.write("<virtualhosts>\n"); - out.write(String.format("\t\t<default>%s</default>\n", name)); - out.write("\t<virtualhost>\n"); - out.write(String.format("\t\t<name>%s</name>\n", name)); - out.write(String.format("\t\t<%s>\n", name)); - out.write("\t\t\t<exchanges>\n"); - out.write("\t\t\t\t<exchange>\n"); - out.write("\t\t\t\t\t<type>topic</type>\n"); - out.write("\t\t\t\t\t<name>test.topic</name>\n"); - out.write("\t\t\t\t\t<durable>true</durable>\n"); - out.write("\t\t\t\t</exchange>\n"); - out.write("\t\tt</exchanges>\n"); - out.write(String.format("\t\t</%s>\n", name)); - out.write("\t</virtualhost>\n"); - out.write("</virtualhosts>\n"); - out.close(); - } - - private void writeMultiVirtualHostsFile(File vhostsFile) throws IOException { - FileWriter out = new FileWriter(vhostsFile); - out.write("<virtualhosts>\n"); - out.write("\t<virtualhost>\n"); - out.write("\t\t<name>topic</name>\n"); - out.write("\t\t<topic>\n"); - out.write("\t\t\t<exchanges>\n"); - out.write("\t\t\t\t<exchange>\n"); - out.write("\t\t\t\t\t<type>topic</type>\n"); - out.write("\t\t\t\t\t<name>test.topic</name>\n"); - out.write("\t\t\t\t\t<durable>true</durable>\n"); - out.write("\t\t\t\t</exchange>\n"); - out.write("\t\tt</exchanges>\n"); - out.write("\t\t</topic>\n"); - out.write("\t</virtualhost>\n"); - out.write("\t<virtualhost>\n"); - out.write("\t\t<name>fanout</name>\n"); - out.write("\t\t<fanout>\n"); - out.write("\t\t\t<exchanges>\n"); - out.write("\t\t\t\t<exchange>\n"); - out.write("\t\t\t\t\t<type>fanout</type>\n"); - out.write("\t\t\t\t\t<name>test.fanout</name>\n"); - out.write("\t\t\t\t\t<durable>true</durable>\n"); - out.write("\t\t\t\t</exchange>\n"); - out.write("\t\tt</exchanges>\n"); - out.write("\t\t</fanout>\n"); - out.write("\t</virtualhost>\n"); - out.write("</virtualhosts>\n"); - out.close(); - } - - private void writeMultipleVhostsConfigFile(File mainFile, File[] vhostsFileArray) throws IOException { - FileWriter out = new FileWriter(mainFile); - out.write("<broker>\n"); - out.write("\t<management><enabled>false</enabled></management>\n"); - out.write("\t<security>\n"); - out.write("\t\t<pd-auth-manager>\n"); - out.write("\t\t\t<principal-database>\n"); - out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n"); - out.write("\t\t\t\t<attributes>\n"); - out.write("\t\t\t\t\t<attribute>\n"); - out.write("\t\t\t\t\t\t<name>passwordFile</name>\n"); - out.write("\t\t\t\t\t\t<value>/dev/null</value>\n"); - out.write("\t\t\t\t\t</attribute>\n"); - out.write("\t\t\t\t</attributes>\n"); - out.write("\t\t\t</principal-database>\n"); - out.write("\t\t</pd-auth-manager>\n"); - out.write("\t\t<firewall>\n"); - out.write("\t\t\t<rule access=\"allow\" network=\"127.0.0.1\"/>"); - out.write("\t\t</firewall>\n"); - out.write("\t</security>\n"); - for (File vhostsFile : vhostsFileArray) - { - out.write("\t<virtualhosts>"+vhostsFile.getAbsolutePath()+"</virtualhosts>\n"); - } - out.write("</broker>\n"); - out.close(); - } - - private void writeCombinedConfigFile(File mainFile, File fileA, File fileB) throws Exception - { - FileWriter out = new FileWriter(mainFile); - out.write("<configuration><system/>"); - out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>"); - out.write("<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>"); - out.write("</configuration>"); - out.close(); - } - - /** - * Test that configuration loads correctly when virtual hosts are specified in the main - * configuration file only. - * <p> - * Test for QPID-2361 - */ - public void testInternalVirtualhostConfigFile() throws Exception - { - // Write out config - File mainFile = File.createTempFile(getClass().getName(), "config"); - mainFile.deleteOnExit(); - writeConfigFile(mainFile, false, true, null, "test"); - - // Load config - ApplicationRegistry.remove(); - ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile); - ApplicationRegistry.initialise(reg); - - // Test config - VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry(); - String defaultVirtualHost = reg.getConfiguration().getDefaultVirtualHost(); - VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test"); - Exchange exchange = virtualHost.getExchangeRegistry().getExchange(new AMQShortString("test.topic")); - - assertEquals("Incorrect default host", "test", defaultVirtualHost); - assertEquals("Incorrect virtualhost count", 1, virtualHostRegistry.getVirtualHosts().size()); - assertEquals("Incorrect virtualhost name", "test", virtualHost.getName()); - assertEquals("Incorrect exchange type", "topic", exchange.getType().getName().toString()); - } - - /** - * Test that configuration loads correctly when virtual hosts are specified in an external - * configuration file only. - * <p> - * Test for QPID-2361 - */ - public void testExternalVirtualhostXMLFile() throws Exception - { - // Write out config - File mainFile = File.createTempFile(getClass().getName(), "config"); - mainFile.deleteOnExit(); - File vhostsFile = File.createTempFile(getClass().getName(), "vhosts"); - vhostsFile.deleteOnExit(); - writeConfigFile(mainFile, false, false, vhostsFile, null); - writeVirtualHostsFile(vhostsFile, "test"); - - // Load config - ApplicationRegistry.remove(); - ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile); - ApplicationRegistry.initialise(reg); - - // Test config - VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry(); - String defaultVirtualHost = reg.getConfiguration().getDefaultVirtualHost(); - VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test"); - Exchange exchange = virtualHost.getExchangeRegistry().getExchange(new AMQShortString("test.topic")); - - assertEquals("Incorrect default host", "test", defaultVirtualHost); - assertEquals("Incorrect virtualhost count", 1, virtualHostRegistry.getVirtualHosts().size()); - assertEquals("Incorrect virtualhost name", "test", virtualHost.getName()); - assertEquals("Incorrect exchange type", "topic", exchange.getType().getName().toString()); - } - - /** - * Test that configuration loads correctly when virtual hosts are specified in an external - * configuration file only, with two vhosts that have different properties. - * <p> - * Test for QPID-2361 - */ - public void testExternalMultiVirtualhostXMLFile() throws Exception - { - // Write out vhosts - File vhostsFile = File.createTempFile(getClass().getName(), "vhosts-multi"); - vhostsFile.deleteOnExit(); - writeMultiVirtualHostsFile(vhostsFile); - - // Write out config - File mainFile = File.createTempFile(getClass().getName(), "config"); - mainFile.deleteOnExit(); - writeConfigFile(mainFile, false, false, vhostsFile, null); - - // Load config - ApplicationRegistry.remove(); - ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile); - ApplicationRegistry.initialise(reg); - - // Test config - VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry(); - - assertEquals("Incorrect virtualhost count", 2, virtualHostRegistry.getVirtualHosts().size()); - - // test topic host - VirtualHost topicVirtualHost = virtualHostRegistry.getVirtualHost("topic"); - Exchange topicExchange = topicVirtualHost.getExchangeRegistry().getExchange(new AMQShortString("test.topic")); - - assertEquals("Incorrect topic virtualhost name", "topic", topicVirtualHost.getName()); - assertEquals("Incorrect topic exchange type", "topic", topicExchange.getType().getName().toString()); - - // Test fanout host - VirtualHost fanoutVirtualHost = virtualHostRegistry.getVirtualHost("fanout"); - Exchange fanoutExchange = fanoutVirtualHost.getExchangeRegistry().getExchange(new AMQShortString("test.fanout")); - - assertEquals("Incorrect fanout virtualhost name", "fanout", fanoutVirtualHost.getName()); - assertEquals("Incorrect fanout exchange type", "fanout", fanoutExchange.getType().getName().toString()); - } - - /** - * Test that configuration does not load when virtual hosts are specified in both the main - * configuration file and an external file. Should throw a {@link ConfigurationException}. - * <p> - * Test for QPID-2361 - */ - public void testInternalAndExternalVirtualhostXMLFile() throws Exception - { - // Write out vhosts - File vhostsFile = File.createTempFile(getClass().getName(), "vhosts"); - vhostsFile.deleteOnExit(); - writeVirtualHostsFile(vhostsFile, "test"); - - // Write out config - File mainFile = File.createTempFile(getClass().getName(), "config"); - mainFile.deleteOnExit(); - writeConfigFile(mainFile, false, true, vhostsFile, "test"); - - // Load config - try - { - ApplicationRegistry.remove(); - ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile); - ApplicationRegistry.initialise(reg); - fail("Different virtualhost XML configurations not allowed"); - } - catch (ConfigurationException ce) - { - assertEquals("Incorrect error message", "Only one of external or embedded virtualhosts configuration allowed.", ce.getMessage()); - } - } - - /** - * Test that configuration does not load when virtual hosts are specified in multiple external - * files. Should throw a {@link ConfigurationException}. - * <p> - * Test for QPID-2361 - */ - public void testMultipleInternalVirtualhostXMLFile() throws Exception - { - // Write out vhosts - File vhostsFileOne = File.createTempFile(getClass().getName(), "vhosts-one"); - vhostsFileOne.deleteOnExit(); - writeVirtualHostsFile(vhostsFileOne, "one"); - File vhostsFileTwo = File.createTempFile(getClass().getName(), "vhosts-two"); - vhostsFileTwo.deleteOnExit(); - writeVirtualHostsFile(vhostsFileTwo, "two"); - - // Write out config - File mainFile = File.createTempFile(getClass().getName(), "config"); - mainFile.deleteOnExit(); - writeMultipleVhostsConfigFile(mainFile, new File[] { vhostsFileOne, vhostsFileTwo }); - - // Load config - try - { - ApplicationRegistry.remove(); - ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile); - ApplicationRegistry.initialise(reg); - fail("Multiple virtualhost XML configurations not allowed"); - } - catch (ConfigurationException ce) - { - assertEquals("Incorrect error message", - "Only one external virtualhosts configuration file allowed, multiple filenames found.", - ce.getMessage()); - } - } - - /** - * Test that configuration loads correctly when virtual hosts are specified in an external - * configuration file in the first of two configurations and embedded in the second. This - * will throe a {@link ConfigurationException} since the configurations have different - * types. - * <p> - * Test for QPID-2361 - */ - public void testCombinedDifferentVirtualhostConfig() throws Exception - { - // Write out vhosts config - File vhostsFile = File.createTempFile(getClass().getName(), "vhosts"); - vhostsFile.deleteOnExit(); - writeVirtualHostsFile(vhostsFile, "external"); - - // Write out combined config file - File mainFile = File.createTempFile(getClass().getName(), "main"); - File fileA = File.createTempFile(getClass().getName(), "a"); - File fileB = File.createTempFile(getClass().getName(), "b"); - mainFile.deleteOnExit(); - fileA.deleteOnExit(); - fileB.deleteOnExit(); - writeCombinedConfigFile(mainFile, fileA, fileB); - writeConfigFile(fileA, false, false, vhostsFile, null); - writeConfigFile(fileB, false); - - // Load config - try - { - ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); - config.initialise(); - fail("Different virtualhost XML configurations not allowed"); - } - catch (ConfigurationException ce) - { - assertEquals("Incorrect error message", "Only one of external or embedded virtualhosts configuration allowed.", ce.getMessage()); - } - } - - /** - * Test that configuration loads correctly when virtual hosts are specified two overriding configurations - * each with an embedded virtualhost section. The first configuration section should be used. - * <p> - * Test for QPID-2361 - */ - public void testCombinedConfigEmbeddedVirtualhost() throws Exception - { - // Write out combined config file - File mainFile = File.createTempFile(getClass().getName(), "main"); - File fileA = File.createTempFile(getClass().getName(), "a"); - File fileB = File.createTempFile(getClass().getName(), "b"); - mainFile.deleteOnExit(); - fileA.deleteOnExit(); - fileB.deleteOnExit(); - writeCombinedConfigFile(mainFile, fileA, fileB); - writeConfigFile(fileA, false, true, null, "a"); - writeConfigFile(fileB, false, true, null, "b"); - - // Load config - ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); - config.initialise(); - - // Test config - VirtualHostConfiguration virtualHost = config.getVirtualHostConfig("a"); - - assertEquals("Incorrect virtualhost count", 1, config.getVirtualHosts().length); - assertEquals("Incorrect virtualhost name", "a", virtualHost.getName()); - } - - /** - * Test that configuration loads correctly when virtual hosts are specified two overriding configurations - * each with an external virtualhost XML file. The first configuration file should be used. - * <p> - * Test for QPID-2361 - */ - public void testCombinedConfigExternalVirtualhost() throws Exception - { - // Write out vhosts config - File vhostsOne = File.createTempFile(getClass().getName(), "vhosts-one"); - vhostsOne.deleteOnExit(); - writeVirtualHostsFile(vhostsOne, "one"); - File vhostsTwo = File.createTempFile(getClass().getName(), "vhosts-two"); - vhostsTwo.deleteOnExit(); - writeVirtualHostsFile(vhostsTwo, "two"); - - // Write out combined config file - File mainFile = File.createTempFile(getClass().getName(), "main"); - File fileA = File.createTempFile(getClass().getName(), "a"); - File fileB = File.createTempFile(getClass().getName(), "b"); - mainFile.deleteOnExit(); - fileA.deleteOnExit(); - fileB.deleteOnExit(); - writeCombinedConfigFile(mainFile, fileA, fileB); - writeConfigFile(fileA, false, false, vhostsOne, null); - writeConfigFile(fileB, false, false, vhostsTwo, null); - - // Load config - ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); - config.initialise(); - - // Test config - VirtualHostConfiguration virtualHost = config.getVirtualHostConfig("one"); - - assertEquals("Incorrect virtualhost count", 1, config.getVirtualHosts().length); - assertEquals("Incorrect virtualhost name", "one", virtualHost.getName()); - } - - /** - * Test that configuration loads correctly when an overriding virtualhost configuration resets - * a property of an embedded virtualhost section. The overriding configuration property value - * should be used. - * <p> - * Test for QPID-2361 - */ - public void testCombinedConfigEmbeddedVirtualhostOverride() throws Exception - { - // Write out combined config file - File mainFile = File.createTempFile(getClass().getName(), "main"); - File fileA = File.createTempFile(getClass().getName(), "override"); - File fileB = File.createTempFile(getClass().getName(), "config"); - mainFile.deleteOnExit(); - fileA.deleteOnExit(); - fileB.deleteOnExit(); - writeCombinedConfigFile(mainFile, fileA, fileB); - writeTestFishConfigFile(fileB); - - // Write out overriding virtualhosts section - FileWriter out = new FileWriter(fileA); - out.write("<broker>\n"); - out.write("<virtualhosts>\n"); - out.write("\t<virtualhost>\n"); - out.write("\t\t<test>\n"); - out.write("\t\t\t<exchanges>\n"); - out.write("\t\t\t\t<exchange>\n"); - out.write("\t\t\t\t\t<durable>false</durable>\n"); - out.write("\t\t\t\t</exchange>\n"); - out.write("\t\tt</exchanges>\n"); - out.write("\t\t</test>\n"); - out.write("\t\t<fish>\n"); - out.write("\t\t\t<exchanges>\n"); - out.write("\t\t\t\t<exchange>\n"); - out.write("\t\t\t\t\t<durable>true</durable>\n"); - out.write("\t\t\t\t</exchange>\n"); - out.write("\t\tt</exchanges>\n"); - out.write("\t\t</fish>\n"); - out.write("\t</virtualhost>\n"); - out.write("</virtualhosts>\n"); - out.write("</broker>\n"); - out.close(); - - // Load config - ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); - config.initialise(); - - // Test config - VirtualHostConfiguration testHost = config.getVirtualHostConfig("test"); - ExchangeConfiguration testExchange = testHost.getExchangeConfiguration("test.topic"); - VirtualHostConfiguration fishHost = config.getVirtualHostConfig("fish"); - ExchangeConfiguration fishExchange = fishHost.getExchangeConfiguration("fish.topic"); - - assertEquals("Incorrect virtualhost count", 2, config.getVirtualHosts().length); - assertEquals("Incorrect virtualhost name", "test", testHost.getName()); - assertFalse("Incorrect exchange durable property", testExchange.getDurable()); - assertEquals("Incorrect virtualhost name", "fish", fishHost.getName()); - assertTrue("Incorrect exchange durable property", fishExchange.getDurable()); - } - - /** - * Test that configuration loads correctly when the virtualhost configuration is a set of overriding - * configuration files that resets a property of a virtualhost. The opmost overriding configuration - * property value should be used. - * <p> - * Test for QPID-2361 - */ - public void testCombinedVirtualhostOverride() throws Exception - { - // Write out combined config file - File mainFile = File.createTempFile(getClass().getName(), "main"); - File vhostsFile = File.createTempFile(getClass().getName(), "vhosts"); - File fileA = File.createTempFile(getClass().getName(), "vhosts-override"); - File fileB = File.createTempFile(getClass().getName(), "vhosts-base"); - mainFile.deleteOnExit(); - vhostsFile.deleteOnExit(); - fileA.deleteOnExit(); - fileB.deleteOnExit(); - writeConfigFile(mainFile, true, false, vhostsFile, null); - writeCombinedConfigFile(vhostsFile, fileA, fileB); - - // Write out overriding virtualhosts sections - FileWriter out = new FileWriter(fileA); - out.write("<virtualhosts>\n"); - out.write("\t<virtualhost>\n"); - out.write("\t\t<test>\n"); - out.write("\t\t\t<exchanges>\n"); - out.write("\t\t\t\t<exchange>\n"); - out.write("\t\t\t\t\t<durable>false</durable>\n"); - out.write("\t\t\t\t</exchange>\n"); - out.write("\t\tt</exchanges>\n"); - out.write("\t\t</test>\n"); - out.write("\t</virtualhost>\n"); - out.write("</virtualhosts>\n"); - out.close(); - writeVirtualHostsFile(fileB, "test"); - - // Load config - ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); - config.initialise(); - - // Test config - VirtualHostConfiguration testHost = config.getVirtualHostConfig("test"); - ExchangeConfiguration testExchange = testHost.getExchangeConfiguration("test.topic"); - - assertEquals("Incorrect virtualhost count", 1, config.getVirtualHosts().length); - assertEquals("Incorrect virtualhost name", "test", testHost.getName()); - assertFalse("Incorrect exchange durable property", testExchange.getDurable()); - } - - /** - * Test that configuration loads correctly when the virtualhost configuration is a set of overriding - * configuration files that define multiple virtualhosts, one per file. Only the virtualhosts defined in - * the topmost file should be used. - * <p> - * Test for QPID-2361 - */ - public void testCombinedMultipleVirtualhosts() throws Exception - { - // Write out combined config file - File mainFile = File.createTempFile(getClass().getName(), "main"); - File vhostsFile = File.createTempFile(getClass().getName(), "vhosts"); - File fileA = File.createTempFile(getClass().getName(), "vhosts-one"); - File fileB = File.createTempFile(getClass().getName(), "vhosts-two"); - mainFile.deleteOnExit(); - vhostsFile.deleteOnExit(); - fileA.deleteOnExit(); - fileB.deleteOnExit(); - writeConfigFile(mainFile, true, false, vhostsFile, null); - writeCombinedConfigFile(vhostsFile, fileA, fileB); - - // Write both virtualhosts definitions - writeVirtualHostsFile(fileA, "test-one"); - writeVirtualHostsFile(fileB, "test-two"); - - // Load config - ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); - config.initialise(); - - // Test config - VirtualHostConfiguration oneHost = config.getVirtualHostConfig("test-one"); - - assertEquals("Incorrect virtualhost count", 1, config.getVirtualHosts().length); - assertEquals("Incorrect virtualhost name", "test-one", oneHost.getName()); - } - - /** - * Test that a non-existent virtualhost file throws a {@link ConfigurationException}. - * <p> - * Test for QPID-2624 - */ - public void testNonExistantVirtualhosts() throws Exception - { - // Write out combined config file - File mainFile = File.createTempFile(getClass().getName(), "main"); - File vhostsFile = new File("doesnotexist"); - mainFile.deleteOnExit(); - writeConfigFile(mainFile, true, false, vhostsFile, null); - - // Load config - try - { - ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); - config.initialise(); - } - catch (ConfigurationException ce) - { - assertEquals("Virtualhosts file does not exist", ce.getMessage()); - } - catch (Exception e) - { - fail("Should throw a ConfigurationException"); - } - } - - /** - * Tests that element disabledFeatures allows features that would - * otherwise be advertised by the broker to be turned off. - */ - public void testDisabledFeatures() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - _serverConfig = new ServerConfiguration(_config); - assertEquals("Unexpected size", 0, _serverConfig.getDisabledFeatures().size()); - - // Check value we set - _config.addProperty("disabledFeatures", "qpid.feature1"); - _config.addProperty("disabledFeatures", "qpid.feature2"); - _serverConfig = new ServerConfiguration(_config); - - assertEquals("Unexpected size",2, _serverConfig.getDisabledFeatures().size()); - assertTrue("Unexpected contents", _serverConfig.getDisabledFeatures().contains("qpid.feature1")); - } - - /** - * Tests that the old element security.jmx.access (that used to be used - * to define JMX access rights) is rejected. - */ - public void testManagementAccessRejected() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - - // Check value we set - _config.setProperty("security.jmx.access(0)", "jmxremote.access"); - _serverConfig = new ServerConfiguration(_config); - - try - { - _serverConfig.initialise(); - fail("Exception not thrown"); - } - catch (ConfigurationException ce) - { - assertEquals("Incorrect error message", - "Validation error : security/jmx/access is no longer a supported element within the configuration xml.", - ce.getMessage()); - } - } - - /** - * Tests that the old element security.jmx.principal-database (that used to define the - * principal database used for JMX authentication) is rejected. - */ - public void testManagementPrincipalDatabaseRejected() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - - // Check value we set - _config.setProperty("security.jmx.principal-database(0)", "mydb"); - _serverConfig = new ServerConfiguration(_config); - - try - { - _serverConfig.initialise(); - fail("Exception not thrown"); - } - catch (ConfigurationException ce) - { - assertEquals("Incorrect error message", - "Validation error : security/jmx/principal-database is no longer a supported element within the configuration xml.", - ce.getMessage()); - } - } - - /** - * Tests that the old element security.principal-databases. ... (that used to define - * principal databases) is rejected. - */ - public void testPrincipalDatabasesRejected() throws ConfigurationException - { - _serverConfig.initialise(); - - // Check value we set - _config.setProperty("security.principal-databases.principal-database.class", "myclass"); - _serverConfig = new ServerConfiguration(_config); - - try - { - _serverConfig.initialise(); - fail("Exception not thrown"); - } - catch (ConfigurationException ce) - { - assertEquals("Incorrect error message", - "Validation error : security/principal-databases is no longer supported within the configuration xml.", - ce.getMessage()); - } - } - - /** - * Tests that the old element housekeeping.expiredMessageCheckPeriod. ... (that was - * replaced by housekeeping.checkPeriod) is rejected. - */ - public void testExpiredMessageCheckPeriodRejected() throws ConfigurationException - { - _serverConfig.initialise(); - - // Check value we set - _config.setProperty("housekeeping.expiredMessageCheckPeriod", 23L); - _serverConfig = new ServerConfiguration(_config); - - try - { - _serverConfig.initialise(); - fail("Exception not thrown"); - } - catch (ConfigurationException ce) - { - assertEquals("Incorrect error message", - "Validation error : housekeeping/expiredMessageCheckPeriod must be replaced by housekeeping/checkPeriod.", - ce.getMessage()); - } - } - - public void testMaxDeliveryCountDefault() throws Exception - { - final ServerConfiguration serverConfig = new ServerConfiguration(_config); - assertEquals(0, serverConfig.getMaxDeliveryCount()); - } - - public void testMaxDeliveryCount() throws Exception - { - _config.setProperty("maximumDeliveryCount", 5); - final ServerConfiguration serverConfig = new ServerConfiguration(_config); - assertEquals(5, serverConfig.getMaxDeliveryCount()); - } - - /** - * Test XML configuration file correctly enables dead letter queues - */ - public void testDeadLetterQueueConfigurationFile() throws Exception - { - // Write config - File xml = File.createTempFile(getClass().getName(), "xml"); - xml.deleteOnExit(); - FileWriter config = new FileWriter(xml); - config.write("<broker>\n"); - writeSecurity(config); - config.write("<deadLetterQueues>true</deadLetterQueues>\n"); - config.write("<virtualhosts>\n"); - config.write("<virtualhost>\n"); - config.write("<name>test</name>\n"); - config.write("<test>\n"); - config.write("<queues>\n"); - config.write("<deadLetterQueues>false</deadLetterQueues>\n"); - config.write("<queue>\n"); - config.write("<name>biggles</name>\n"); - config.write("<biggles>\n"); - config.write("<deadLetterQueues>true</deadLetterQueues>\n"); - config.write("</biggles>\n"); - config.write("</queue>\n"); - config.write("<queue>\n"); - config.write("<name>beetle</name>\n"); - config.write("<beetle />\n"); - config.write("</queue>\n"); - config.write("</queues>\n"); - config.write("</test>\n"); - config.write("</virtualhost>\n"); - config.write("<virtualhost>\n"); - config.write("<name>extra</name>\n"); - config.write("<extra>\n"); - config.write("<queues>\n"); - config.write("<queue>\n"); - config.write("<name>r2d2</name>\n"); - config.write("<r2d2>\n"); - config.write("<deadLetterQueues>false</deadLetterQueues>\n"); - config.write("</r2d2>\n"); - config.write("</queue>\n"); - config.write("<queue>\n"); - config.write("<name>c3p0</name>\n"); - config.write("<c3p0 />\n"); - config.write("</queue>\n"); - config.write("</queues>\n"); - config.write("</extra>\n"); - config.write("</virtualhost>\n"); - config.write("</virtualhosts>\n"); - config.write("</broker>\n"); - config.close(); - - // Load config - ApplicationRegistry.remove(); - ApplicationRegistry registry = new ConfigurationFileApplicationRegistry(xml); - ApplicationRegistry.initialise(registry); - ServerConfiguration serverConfiguration = ApplicationRegistry.getInstance().getConfiguration(); - - VirtualHostConfiguration test = serverConfiguration.getVirtualHostConfig("test"); - assertNotNull("Host 'test' is not found", test); - VirtualHostConfiguration extra = serverConfiguration.getVirtualHostConfig("extra"); - assertNotNull("Host 'extra' is not found", test); - - QueueConfiguration biggles = test.getQueueConfiguration("biggles"); - QueueConfiguration beetle = test.getQueueConfiguration("beetle"); - QueueConfiguration r2d2 = extra.getQueueConfiguration("r2d2"); - QueueConfiguration c3p0 = extra.getQueueConfiguration("c3p0"); - - // Validate config - assertTrue("Broker DLQ should be configured as enabled", serverConfiguration.isDeadLetterQueueEnabled()); - assertFalse("Test vhost DLQ should be configured as disabled", test.isDeadLetterQueueEnabled()); - assertTrue("Extra vhost DLQ should be enabled, using broker default", extra.isDeadLetterQueueEnabled()); - assertTrue("Biggles queue DLQ should be configured as enabled", biggles.isDeadLetterQueueEnabled()); - assertFalse("Beetle queue DLQ should be disabled, using test vhost default", beetle.isDeadLetterQueueEnabled()); - assertFalse("R2D2 queue DLQ should be configured as disabled", r2d2.isDeadLetterQueueEnabled()); - assertTrue("C3P0 queue DLQ should be enabled, using broker default", c3p0.isDeadLetterQueueEnabled()); - } - - public void testIsAmqp010enabled() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(true, _serverConfig.isAmqp010enabled()); - - // Check value we set - _config.setProperty(ServerConfiguration.CONNECTOR_AMQP010ENABLED, false); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(false, _serverConfig.isAmqp010enabled()); - } - - public void testIsAmqp091enabled() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(true, _serverConfig.isAmqp091enabled()); - - // Check value we set - _config.setProperty(ServerConfiguration.CONNECTOR_AMQP091ENABLED, false); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(false, _serverConfig.isAmqp091enabled()); - } - - public void testIsAmqp09enabled() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(true, _serverConfig.isAmqp09enabled()); - - // Check value we set - _config.setProperty(ServerConfiguration.CONNECTOR_AMQP09ENABLED, false); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(false, _serverConfig.isAmqp09enabled()); - } - - public void testIsAmqp08enabled() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(true, _serverConfig.isAmqp08enabled()); - - // Check value we set - _config.setProperty(ServerConfiguration.CONNECTOR_AMQP08ENABLED, false); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(false, _serverConfig.isAmqp08enabled()); - } - - public void testPortInclude08() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(true, _serverConfig.getPortInclude08().isEmpty()); - - // Check values we set - _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_08, "1"); - _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_08, "2"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(2, _serverConfig.getPortInclude08().size()); - assertTrue(_serverConfig.getPortInclude08().contains("1")); - assertTrue(_serverConfig.getPortInclude08().contains("2")); - } - - public void testPortInclude09() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(true, _serverConfig.getPortInclude09().isEmpty()); - - // Check values we set - _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_09, "3"); - _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_09, "4"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(2, _serverConfig.getPortInclude09().size()); - assertTrue(_serverConfig.getPortInclude09().contains("3")); - assertTrue(_serverConfig.getPortInclude09().contains("4")); - } - - public void testPortInclude091() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(true, _serverConfig.getPortInclude091().isEmpty()); - - // Check values we set - _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_091, "5"); - _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_091, "6"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(2, _serverConfig.getPortInclude091().size()); - assertTrue(_serverConfig.getPortInclude091().contains("5")); - assertTrue(_serverConfig.getPortInclude091().contains("6")); - } - - public void testPortInclude010() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(true, _serverConfig.getPortInclude010().isEmpty()); - - // Check values we set - _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_010, "7"); - _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_010, "8"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(2, _serverConfig.getPortInclude010().size()); - assertTrue(_serverConfig.getPortInclude010().contains("7")); - assertTrue(_serverConfig.getPortInclude010().contains("8")); - } - - public void testPortInclude10() throws ConfigurationException - { - // Check default - _serverConfig.initialise(); - assertEquals(true, _serverConfig.getPortInclude10().isEmpty()); - - // Check values we set - _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_10, "9"); - _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_10, "10"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(2, _serverConfig.getPortInclude10().size()); - assertTrue(_serverConfig.getPortInclude10().contains("9")); - assertTrue(_serverConfig.getPortInclude10().contains("10")); - } - - public void testGetDefaultSupportedProtocolReply() throws Exception - { - // Check default - _serverConfig.initialise(); - assertNull("unexpected default value", _serverConfig.getDefaultSupportedProtocolReply()); - - // Check values we set - _config.addProperty(ServerConfiguration.CONNECTOR_AMQP_SUPPORTED_REPLY, "v0_10"); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(AmqpProtocolVersion.v0_10, _serverConfig.getDefaultSupportedProtocolReply()); - } - - public void testDefaultAuthenticationManager() throws Exception - { - // Check default - _serverConfig.initialise(); - assertNull("unexpected default value", _serverConfig.getDefaultAuthenticationManager()); - - // Check values we set - String testAuthManager = "myauthmanager"; - _config.addProperty("security.default-auth-manager", testAuthManager); - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals(testAuthManager, _serverConfig.getDefaultAuthenticationManager()); - } - - public void testPortAuthenticationMappingsDefault() throws Exception - { - _serverConfig.initialise(); - assertEquals("unexpected default number of port/authmanager mappings", 0, _serverConfig.getPortAuthenticationMappings().size()); - } - - public void testPortAuthenticationMappingsWithSingleMapping() throws Exception - { - String testAuthManager = "myauthmanager"; - _config.addProperty("security.port-mappings.port-mapping.port", 1234); - _config.addProperty("security.port-mappings.port-mapping.auth-manager", testAuthManager); - - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - assertEquals("unexpected number of port/authmanager mappings", 1, _serverConfig.getPortAuthenticationMappings().size()); - assertEquals("unexpected mapping for port", testAuthManager, _serverConfig.getPortAuthenticationMappings().get(1234)); - } - - public void testPortAuthenticationMappingsWithManyMapping() throws Exception - { - String testAuthManager1 = "myauthmanager1"; - String testAuthManager2 = "myauthmanager2"; - _config.addProperty("security.port-mappings.port-mapping(-1).port", 1234); - _config.addProperty("security.port-mappings.port-mapping.auth-manager", testAuthManager1); - - _config.addProperty("security.port-mappings.port-mapping(-1).port", 2345); - _config.addProperty("security.port-mappings.port-mapping.auth-manager", testAuthManager2); - - _serverConfig = new ServerConfiguration(_config); - _serverConfig.initialise(); - - assertEquals("unexpected number of port/authmanager mappings", 2, _serverConfig.getPortAuthenticationMappings().size()); - assertEquals("unexpected mapping for port", testAuthManager1, _serverConfig.getPortAuthenticationMappings().get(1234)); - assertEquals("unexpected mapping for port", testAuthManager2, _serverConfig.getPortAuthenticationMappings().get(2345)); - } - - public void testPortAuthenticationMappingWithMissingAuthManager() throws Exception - { - _config.addProperty("security.port-mappings.port-mapping(-1).port", 1234); - // no auth manager defined for port - _serverConfig = new ServerConfiguration(_config); - try - { - _serverConfig.initialise(); - fail("Exception not thrown"); - } - catch(ConfigurationException ce) - { - // PASS - assertEquals("Incorrect error message", - "Validation error: Each port-mapping must have exactly one port and exactly one auth-manager.", - ce.getMessage()); - } - } - - /** - * Convenience method to output required security preamble for broker config - */ - private void writeSecurity(Writer out) throws Exception - { - out.write("\t<management><enabled>false</enabled></management>\n"); - out.write("\t<security>\n"); - out.write("\t\t<pd-auth-manager>\n"); - out.write("\t\t\t<principal-database>\n"); - out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n"); - out.write("\t\t\t\t<attributes>\n"); - out.write("\t\t\t\t\t<attribute>\n"); - out.write("\t\t\t\t\t\t<name>passwordFile</name>\n"); - out.write("\t\t\t\t\t\t<value>/dev/null</value>\n"); - out.write("\t\t\t\t\t</attribute>\n"); - out.write("\t\t\t\t</attributes>\n"); - out.write("\t\t\t</principal-database>\n"); - out.write("\t\t</pd-auth-manager>\n"); - out.write("\t</security>\n"); - } -} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/TopicConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/TopicConfigurationTest.java deleted file mode 100644 index caf74a89ec..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/configuration/TopicConfigurationTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * - * 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.configuration; - -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.AMQException; -import org.apache.qpid.AMQInternalException; -import org.apache.qpid.AMQSecurityException; -import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.queue.AMQQueueFactory; -import org.apache.qpid.server.util.InternalBrokerBaseCase; - -/** - * Test of the new Topic configuration processing - */ -public class TopicConfigurationTest extends InternalBrokerBaseCase -{ - - @Override - public void configure() - { - getConfigXml().addProperty("virtualhosts.virtualhost.test.topics.topic.name", "stocks.nyse.appl"); - - getConfigXml().addProperty("virtualhosts.virtualhost.test.topics.topic(1).subscriptionName", getName()+":stockSubscription"); - - getConfigXml().addProperty("virtualhosts.virtualhost.test.topics.topic(2).name", "stocks.nyse.orcl"); - getConfigXml().addProperty("virtualhosts.virtualhost.test.topics.topic(2).subscriptionName", getName()+":stockSubscription"); - } - - /** - * Test that a TopicConfig object is created and attached to the queue when it is bound to the topic exchange. - * - - * @throws ConfigurationException - * @throws AMQSecurityException - */ - public void testTopicCreation() throws ConfigurationException, AMQSecurityException, AMQInternalException - { - Exchange topicExchange = getVirtualHost().getExchangeRegistry().getExchange(ExchangeDefaults.TOPIC_EXCHANGE_NAME); - getVirtualHost().getBindingFactory().addBinding("stocks.nyse.appl", getQueue(), topicExchange, null); - - TopicConfig config = getQueue().getConfiguration().getConfiguration(TopicConfig.class.getName()); - - assertNotNull("Queue should have topic configuration bound to it.", config); - assertEquals("Configuration name not correct", "stocks.nyse.appl", config.getName()); - } - - /** - * Test that a queue created for a subscription correctly has topic - * configuration selected based on the subscription and topic name. - * - * @throws ConfigurationException - * @throws AMQException - */ - public void testSubscriptionWithTopicCreation() throws ConfigurationException, AMQException - { - - AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), getName()+":stockSubscription", false, "testowner", - false, false, getVirtualHost(), null); - - getVirtualHost().getQueueRegistry().registerQueue(queue); - Exchange defaultExchange = getVirtualHost().getExchangeRegistry().getDefaultExchange(); - getVirtualHost().getBindingFactory().addBinding(getName(), queue, defaultExchange, null); - - - Exchange topicExchange = getVirtualHost().getExchangeRegistry().getExchange(ExchangeDefaults.TOPIC_EXCHANGE_NAME); - getVirtualHost().getBindingFactory().addBinding("stocks.nyse.orcl", queue, topicExchange, null); - - TopicConfig config = queue.getConfiguration().getConfiguration(TopicConfig.class.getName()); - - assertNotNull("Queue should have topic configuration bound to it.", config); - assertEquals("Configuration subscription name not correct", getName() + ":stockSubscription", config.getSubscriptionName()); - assertEquals("Configuration name not correct", "stocks.nyse.orcl", config.getName()); - - } - - /** - * Test that a queue created for a subscription correctly has topic - * configuration attached here this should be the generic topic section - * with just the subscriptionName - * - * @throws ConfigurationException - * @throws AMQException - */ - public void testSubscriptionCreation() throws ConfigurationException, AMQException - { - - AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID() ,getName()+":stockSubscription", false, "testowner", - false, false, getVirtualHost(), null); - - getVirtualHost().getQueueRegistry().registerQueue(queue); - Exchange defaultExchange = getVirtualHost().getExchangeRegistry().getDefaultExchange(); - getVirtualHost().getBindingFactory().addBinding(getName(), queue, defaultExchange, null); - - - Exchange topicExchange = getVirtualHost().getExchangeRegistry().getExchange(ExchangeDefaults.TOPIC_EXCHANGE_NAME); - getVirtualHost().getBindingFactory().addBinding("stocks.nyse.ibm", queue, topicExchange, null); - - TopicConfig config = queue.getConfiguration().getConfiguration(TopicConfig.class.getName()); - - assertNotNull("Queue should have topic configuration bound to it.", config); - assertEquals("Configuration subscription name not correct", getName() + ":stockSubscription", config.getSubscriptionName()); - assertEquals("Configuration name not correct", "#", config.getName()); - - } - - - -} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java index 50e7f0588b..570bd004c5 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java @@ -19,24 +19,69 @@ */ package org.apache.qpid.server.configuration; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.XMLConfiguration; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.queue.AMQPriorityQueue; import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.store.TestableMemoryMessageStore; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; +import org.apache.qpid.test.utils.QpidTestCase; -public class VirtualHostConfigurationTest extends InternalBrokerBaseCase +public class VirtualHostConfigurationTest extends QpidTestCase { + private VirtualHostRegistry _virtualHostRegistry; + private XMLConfiguration _configXml; + private Broker _broker; @Override - public void createBroker() + public void setUp() throws Exception { - // Prevent auto broker startup + super.setUp(); + BrokerTestHelper.setUp(); + _configXml = new XMLConfiguration(); + _configXml.addProperty("virtualhosts.virtualhost(-1).name", getName()); + _configXml.addProperty("virtualhosts.virtualhost(-1)."+getName()+".store.class", TestableMemoryMessageStore.class.getName()); + _virtualHostRegistry = new VirtualHostRegistry(); + _broker = mock(Broker.class); + when(_broker.getAttribute(Broker.HOUSEKEEPING_CHECK_PERIOD)).thenReturn(30000l); + } + + @Override + public void tearDown() throws Exception + { + try + { + if (_virtualHostRegistry != null) + { + _virtualHostRegistry.close(); + } + } + finally + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } + } + + private XMLConfiguration getConfigXml() + { + return _configXml; + } + + private VirtualHost createVirtualHost(String hostName) throws Exception + { + Configuration config = getConfigXml().subset("virtualhosts.virtualhost." + XmlConfigurationUtilities.escapeTagName(hostName)); + VirtualHostConfiguration virtualHostConfiguration = new VirtualHostConfiguration(hostName, config, _broker); + return BrokerTestHelper.createVirtualHost(virtualHostConfiguration, _virtualHostRegistry); } public void testQueuePriority() throws Exception @@ -65,11 +110,7 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase getConfigXml().addProperty("virtualhosts.virtualhost.testQueuePriority.queues.queue.ntest.priority", "false"); - // Start the broker now. - super.createBroker(); - - VirtualHost vhost = - ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName()); + VirtualHost vhost = createVirtualHost(getName()); // Check that atest was a priority queue with 5 priorities AMQQueue atest = vhost.getQueueRegistry().getQueue(new AMQShortString("atest")); @@ -102,11 +143,7 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase getConfigXml().addProperty("virtualhosts.virtualhost.testQueueAlerts.queues(-1).queue(-1).name(-1)", "btest"); - // Start the broker now. - super.createBroker(); - - VirtualHost vhost = - ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName()); + VirtualHost vhost = createVirtualHost(getName()); // Check specifically configured values AMQQueue aTest = vhost.getQueueRegistry().getQueue(new AMQShortString("atest")); @@ -129,11 +166,7 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + ".queues.queue.biggles.maximumDeliveryCount", 4); getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + ".queues(-1).queue(-1).name", "beetle"); - // Start the broker now. - super.createBroker(); - - // Get vhosts - VirtualHost test = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName()); + VirtualHost test = createVirtualHost(getName()); // Enabled specifically assertEquals("Test vhost MDC was configured as enabled", 5 ,test.getConfiguration().getMaxDeliveryCount()); @@ -163,12 +196,8 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + "Extra.queues(-1).queue(-1).name", "c3p0"); getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + "Extra.store.class", TestableMemoryMessageStore.class.getName()); - // Start the broker now. - super.createBroker(); - - // Get vhosts - VirtualHost test = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName()); - VirtualHost extra = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName() + "Extra"); + VirtualHost test = createVirtualHost(getName()); + VirtualHost extra = createVirtualHost(getName() + "Extra"); // Enabled specifically assertTrue("Test vhost DLQ was configured as enabled", test.getConfiguration().isDeadLetterQueueEnabled()); @@ -215,38 +244,13 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase getConfigXml().addProperty("virtualhosts.virtualhost.testHouseKeepingThreadCount.housekeeping.poolSize", initialPoolSize); - // Start the broker now. - super.createBroker(); - - VirtualHost vhost = - ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName()); + VirtualHost vhost = createVirtualHost(getName()); assertEquals("HouseKeeping PoolSize not set correctly.", initialPoolSize, vhost.getHouseKeepingPoolSize()); } /** - * Test default house keeping tasks - * - * @throws Exception - */ - public void testDefaultHouseKeepingTasks() throws Exception - { - // Start the broker now. - super.createBroker(); - - VirtualHost vhost = - ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName()); - - assertEquals("Default houseKeeping task count incorrect.", 2, - vhost.getHouseKeepingTaskCount()); - - // Currently the two are tasks: - // ExpiredMessageTask from VirtualHost - // UpdateTask from the QMF ManagementExchange - } - - /** * Test that we can dynamically change the thread pool size * * @throws Exception @@ -258,11 +262,7 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase getConfigXml().addProperty("virtualhosts.virtualhost.testDynamicHouseKeepingPoolSizeChange.housekeeping.poolSize", initialPoolSize); - // Start the broker now. - super.createBroker(); - - VirtualHost vhost = - ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName()); + VirtualHost vhost = createVirtualHost(getName()); assertEquals("HouseKeeping PoolSize not set correctly.", initialPoolSize, vhost.getHouseKeepingPoolSize()); @@ -286,7 +286,7 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase try { - super.createBroker(); + createVirtualHost(getName()); fail("Exception not thrown"); } catch(ConfigurationException ce) @@ -309,7 +309,7 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase try { - super.createBroker(); + createVirtualHost(getName()); fail("Exception not thrown"); } catch (ConfigurationException ce) @@ -320,4 +320,41 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase ce.getMessage()); } } + + /* + * Tests that the queues with dots in the names are fully supported. The XML configuration + * had problems with handling the tags containing dots due to the design of the Apache Commons + * Configuration library. The dots need to be escaped when accessing the XML configuration. + */ + public void testDotsInQueueName() throws Exception + { + // Set up vhosts and queue + getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + ".queues(-1).queue(-1).name", "dot.in.a.name"); + // Add a single property which is inside the <dot.in.a.name> queue tag - the maximum delivery count + getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + ".queues.queue.dot..in..a..name.maximumDeliveryCount", 5); + + VirtualHost test = createVirtualHost(getName()); + + // Check, that the property stored within the <dot.in.a.name> tag has been properly loaded + assertEquals("queue with dots in its name has been properly loaded", 5, test.getConfiguration().getQueueConfiguration("dot.in.a.name").getMaxDeliveryCount()); + } + + /* + * Tests that the virtual hosts with dots in the names are fully supported. The XML + * configuration had problems with handling the tags containing dots due to the design + * of the Apache Commons Configuration library. The dots need to be escaped when + * accessing the XML configuration. + */ + public void testDotsInVirtualHostName() throws Exception + { + // Set up vhosts + getConfigXml().addProperty("virtualhosts.virtualhost.name", "dot.in.a.name"); + // Add a single property which is inside the <dot.in.a.name> virtual host tag - the message store + getConfigXml().addProperty("virtualhosts.virtualhost.dot..in..a..name.store.class", TestableMemoryMessageStore.class.getName()); + + VirtualHost test = createVirtualHost("dot.in.a.name"); + + // Check, that the property stored within the <dot.in.a.name> tag has been properly loaded + assertEquals("virtual host with dots in the name has been properly loaded", TestableMemoryMessageStore.class.getName(), test.getMessageStore().getClass().getName()); + } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/plugins/AbstractConfigurationTest.java index 14c7b8cb20..674abbfeb7 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/plugins/AbstractConfigurationTest.java @@ -24,7 +24,7 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.XMLConfiguration; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.test.utils.QpidTestCase; import java.util.List; @@ -32,14 +32,14 @@ import java.util.List; * Test that verifies that given a Configuration a ConfigurationPlugin can * process and validate that data. */ -public class ConfigurationPluginTest extends InternalBrokerBaseCase +public class AbstractConfigurationTest extends QpidTestCase { private static final double DOUBLE = 3.14; private static final long POSITIVE_LONG = 1000; private static final long NEGATIVE_LONG = -1000; private static final int LIST_SIZE = 3; - class ConfigPlugin extends ConfigurationPlugin + class TestConfigPlugin extends AbstractConfiguration { @Override public String[] getElementsProcessed() @@ -68,7 +68,7 @@ public class ConfigurationPluginTest extends InternalBrokerBaseCase } - private ConfigPlugin _plugin; + private TestConfigPlugin _plugin; @Override public void setUp() throws Exception @@ -93,7 +93,7 @@ public class ConfigurationPluginTest extends InternalBrokerBaseCase CompositeConfiguration composite = new CompositeConfiguration(); composite.addConfiguration(xmlconfig); - _plugin = new ConfigPlugin(); + _plugin = new TestConfigPlugin(); try { @@ -110,7 +110,7 @@ public class ConfigurationPluginTest extends InternalBrokerBaseCase public void testHasConfiguration() { assertTrue("Plugin has no configuration ", _plugin.hasConfiguration()); - _plugin = new ConfigPlugin(); + _plugin = new TestConfigPlugin(); assertFalse("Plugins has configuration", _plugin.hasConfiguration()); } @@ -142,7 +142,7 @@ public class ConfigurationPluginTest extends InternalBrokerBaseCase catch (ConfigurationException e) { assertEquals("negativeLong should not be reported as positive", - "ConfigPlugin: unable to configure invalid negativeLong:" + NEGATIVE_LONG, e.getMessage()); + "TestConfigPlugin: unable to configure invalid negativeLong:" + NEGATIVE_LONG, e.getMessage()); } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java new file mode 100644 index 0000000000..c1ebe26f52 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java @@ -0,0 +1,405 @@ +/* + * + * 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.configuration.startup; + +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.UUID; + +import junit.framework.TestCase; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.logging.LogRecorder; +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.model.KeyStore; +import org.apache.qpid.server.model.Plugin; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; +import org.apache.qpid.server.model.adapter.PortFactory; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.security.group.GroupPrincipalAccessor; +import org.apache.qpid.server.stats.StatisticsGatherer; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; + +public class BrokerRecovererTest extends TestCase +{ + private BrokerRecoverer _brokerRecoverer; + private ConfigurationEntry _brokerEntry = mock(ConfigurationEntry.class); + + private UUID _brokerId = UUID.randomUUID(); + private Map<String, Collection<ConfigurationEntry>> _brokerEntryChildren = new HashMap<String, Collection<ConfigurationEntry>>(); + private ConfigurationEntry _authenticationProviderEntry1; + private AuthenticationProvider _authenticationProvider1; + + @Override + protected void setUp() throws Exception + { + super.setUp(); + + _brokerRecoverer = new BrokerRecoverer(mock(AuthenticationProviderFactory.class), mock(PortFactory.class), mock(StatisticsGatherer.class), + mock(VirtualHostRegistry.class), mock(LogRecorder.class), mock(RootMessageLogger.class), mock(TaskExecutor.class)); + when(_brokerEntry.getId()).thenReturn(_brokerId); + when(_brokerEntry.getChildren()).thenReturn(_brokerEntryChildren); + + //Add a base AuthenticationProvider for all tests + _authenticationProvider1 = mock(AuthenticationProvider.class); + when(_authenticationProvider1.getName()).thenReturn("authenticationProvider1"); + _authenticationProviderEntry1 = mock(ConfigurationEntry.class); + _brokerEntryChildren.put(AuthenticationProvider.class.getSimpleName(), Arrays.asList(_authenticationProviderEntry1)); + } + + public void testCreateBrokerAttributes() + { + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(Broker.DEFAULT_VIRTUAL_HOST, "test"); + attributes.put(Broker.DEFAULT_AUTHENTICATION_PROVIDER, "authenticationProvider1"); + attributes.put(Broker.ALERT_THRESHOLD_MESSAGE_AGE, 9l); + attributes.put(Broker.ALERT_THRESHOLD_MESSAGE_COUNT, 8l); + attributes.put(Broker.ALERT_THRESHOLD_QUEUE_DEPTH, 7l); + attributes.put(Broker.ALERT_THRESHOLD_MESSAGE_SIZE, 6l); + attributes.put(Broker.ALERT_REPEAT_GAP, 5l); + attributes.put(Broker.FLOW_CONTROL_SIZE_BYTES, 5l); + attributes.put(Broker.FLOW_CONTROL_RESUME_SIZE_BYTES, 3l); + attributes.put(Broker.MAXIMUM_DELIVERY_ATTEMPTS, 2); + attributes.put(Broker.DEAD_LETTER_QUEUE_ENABLED, true); + attributes.put(Broker.HOUSEKEEPING_CHECK_PERIOD, 1l); + attributes.put(Broker.ACL_FILE, "/path/to/acl"); + attributes.put(Broker.SESSION_COUNT_LIMIT, 1000); + attributes.put(Broker.HEART_BEAT_DELAY, 2000); + attributes.put(Broker.STATISTICS_REPORTING_PERIOD, 4000); + attributes.put(Broker.STATISTICS_REPORTING_RESET_ENABLED, true); + + Map<String, Object> entryAttributes = new HashMap<String, Object>(); + for (Map.Entry<String, Object> attribute : attributes.entrySet()) + { + String value = convertToString(attribute.getValue()); + entryAttributes.put(attribute.getKey(), value); + } + + when(_brokerEntry.getAttributes()).thenReturn(entryAttributes); + + final ConfigurationEntry virtualHostEntry = mock(ConfigurationEntry.class); + String typeName = VirtualHost.class.getSimpleName(); + when(virtualHostEntry.getType()).thenReturn(typeName); + _brokerEntryChildren.put(typeName, Arrays.asList(virtualHostEntry)); + final VirtualHost virtualHost = mock(VirtualHost.class); + when(virtualHost.getName()).thenReturn("test"); + + RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[] { virtualHostEntry, _authenticationProviderEntry1 }, + new ConfiguredObject[] { virtualHost, _authenticationProvider1 }); + Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry); + assertNotNull(broker); + assertEquals(_brokerId, broker.getId()); + + for (Map.Entry<String, Object> attribute : attributes.entrySet()) + { + Object attributeValue = broker.getAttribute(attribute.getKey()); + assertEquals("Unexpected value of attribute '" + attribute.getKey() + "'", attribute.getValue(), attributeValue); + } + } + + public void testCreateBrokerWithVirtualHost() + { + final ConfigurationEntry virtualHostEntry = mock(ConfigurationEntry.class); + + String typeName = VirtualHost.class.getSimpleName(); + when(virtualHostEntry.getType()).thenReturn(typeName); + _brokerEntryChildren.put(typeName, Arrays.asList(virtualHostEntry)); + + final VirtualHost virtualHost = mock(VirtualHost.class); + + RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{virtualHostEntry, _authenticationProviderEntry1}, + new ConfiguredObject[]{virtualHost, _authenticationProvider1}); + + Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry); + + assertNotNull(broker); + assertEquals(_brokerId, broker.getId()); + assertEquals(1, broker.getVirtualHosts().size()); + assertEquals(virtualHost, broker.getVirtualHosts().iterator().next()); + } + + public void testCreateBrokerWithPorts() + { + ConfigurationEntry portEntry = mock(ConfigurationEntry.class); + Port port = mock(Port.class); + _brokerEntryChildren.put(Port.class.getSimpleName(), Arrays.asList(portEntry)); + + RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{portEntry, _authenticationProviderEntry1}, + new ConfiguredObject[]{port, _authenticationProvider1}); + + Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry); + + assertNotNull(broker); + assertEquals(_brokerId, broker.getId()); + assertEquals(Collections.singletonList(port), broker.getPorts()); + } + + public void testCreateBrokerWithoutAuthenticationProviderThrowsException() + { + assertNotNull("expected to remove the base entry", _brokerEntryChildren.remove(AuthenticationProvider.class.getSimpleName())); + assertTrue("should be empty", _brokerEntryChildren.isEmpty()); + + RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[0], new ConfiguredObject[0]); + + try + { + _brokerRecoverer.create(recovererProvider, _brokerEntry); + fail("should have thrown an exception due to missing authentication provider configuration"); + } + catch(IllegalConfigurationException e) + { + //expected + } + } + + public void testCreateBrokerWithOneAuthenticationProvider() + { + RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{_authenticationProviderEntry1}, + new ConfiguredObject[]{_authenticationProvider1}); + + Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry); + + assertNotNull(broker); + assertEquals(_brokerId, broker.getId()); + assertEquals(Collections.singletonList(_authenticationProvider1), broker.getAuthenticationProviders()); + } + + public void testCreateBrokerWithMultipleAuthenticationProvidersAndNoDefaultThrowsException() + { + AuthenticationProvider authenticationProvider2 = mock(AuthenticationProvider.class); + when(authenticationProvider2.getName()).thenReturn("authenticationProvider2"); + ConfigurationEntry authenticationProviderEntry2 = mock(ConfigurationEntry.class); + _brokerEntryChildren.put(AuthenticationProvider.class.getSimpleName(), Arrays.asList(_authenticationProviderEntry1, authenticationProviderEntry2)); + + Map<String,Object> emptyBrokerAttributes = new HashMap<String,Object>(); + when(_brokerEntry.getAttributes()).thenReturn(emptyBrokerAttributes); + + RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{authenticationProviderEntry2, _authenticationProviderEntry1}, + new ConfiguredObject[]{authenticationProvider2, _authenticationProvider1}); + try + { + _brokerRecoverer.create(recovererProvider, _brokerEntry); + fail("should have thrown an exception due to missing authentication provider default"); + } + catch(IllegalConfigurationException e) + { + //expected + } + } + + public void testCreateBrokerWithMultipleAuthenticationProvidersAndPorts() + { + //Create a second authentication provider + AuthenticationProvider authenticationProvider2 = mock(AuthenticationProvider.class); + when(authenticationProvider2.getName()).thenReturn("authenticationProvider2"); + ConfigurationEntry authenticationProviderEntry2 = mock(ConfigurationEntry.class); + _brokerEntryChildren.put(AuthenticationProvider.class.getSimpleName(), Arrays.asList(_authenticationProviderEntry1, authenticationProviderEntry2)); + + //Set the default authentication provider + Map<String,Object> brokerAtttributes = new HashMap<String,Object>(); + when(_brokerEntry.getAttributes()).thenReturn(brokerAtttributes); + brokerAtttributes.put(Broker.DEFAULT_AUTHENTICATION_PROVIDER, "authenticationProvider2"); + + //Add a couple ports, one with a defined authentication provider and + //one without (which should then use the default) + ConfigurationEntry portEntry1 = mock(ConfigurationEntry.class); + Port port1 = mock(Port.class); + when(port1.getName()).thenReturn("port1"); + when(port1.getPort()).thenReturn(5671); + when(port1.getAttribute(Port.AUTHENTICATION_MANAGER)).thenReturn("authenticationProvider1"); + ConfigurationEntry portEntry2 = mock(ConfigurationEntry.class); + Port port2 = mock(Port.class); + when(port2.getName()).thenReturn("port2"); + when(port2.getPort()).thenReturn(5672); + _brokerEntryChildren.put(Port.class.getSimpleName(), Arrays.asList(portEntry1, portEntry2)); + + RecovererProvider recovererProvider = createRecoveryProvider( + new ConfigurationEntry[]{portEntry1, portEntry2, authenticationProviderEntry2, _authenticationProviderEntry1}, + new ConfiguredObject[]{port1, port2, authenticationProvider2, _authenticationProvider1}); + + Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry); + + assertNotNull(broker); + assertEquals("Unexpected number of authentication providers", 2,broker.getAuthenticationProviders().size()); + + Collection<Port> ports = broker.getPorts(); + assertEquals("Unexpected number of ports", 2, ports.size()); + assertTrue(ports.contains(port1)); + assertTrue(ports.contains(port2)); + + verify(port1).setAuthenticationProvider(any(AuthenticationProvider.class)); + verify(port1).setAuthenticationProvider(_authenticationProvider1); + + verify(port2).setAuthenticationProvider(any(AuthenticationProvider.class)); + verify(port2).setAuthenticationProvider(authenticationProvider2); + } + + public void testCreateBrokerAssignsGroupAccessorToAuthenticationProviders() + { + //Create a second authentication provider + AuthenticationProvider authenticationProvider2 = mock(AuthenticationProvider.class); + when(authenticationProvider2.getName()).thenReturn("authenticationProvider2"); + ConfigurationEntry authenticationProviderEntry2 = mock(ConfigurationEntry.class); + _brokerEntryChildren.put(AuthenticationProvider.class.getSimpleName(), Arrays.asList(_authenticationProviderEntry1, authenticationProviderEntry2)); + + //Set the default authentication provider + Map<String,Object> brokerAtttributes = new HashMap<String,Object>(); + when(_brokerEntry.getAttributes()).thenReturn(brokerAtttributes); + brokerAtttributes.put(Broker.DEFAULT_AUTHENTICATION_PROVIDER, "authenticationProvider2"); + + //Create a group provider + ConfigurationEntry groupProviderEntry = mock(ConfigurationEntry.class); + GroupProvider groupProvider = mock(GroupProvider.class); + _brokerEntryChildren.put(GroupProvider.class.getSimpleName(), Arrays.asList(groupProviderEntry)); + + RecovererProvider recovererProvider = createRecoveryProvider( + new ConfigurationEntry[]{groupProviderEntry, authenticationProviderEntry2, _authenticationProviderEntry1}, + new ConfiguredObject[]{groupProvider, authenticationProvider2, _authenticationProvider1}); + + Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry); + + assertNotNull(broker); + assertEquals("Unexpected number of authentication providers", 2, broker.getAuthenticationProviders().size()); + + //verify that a GroupAcessor was added to the AuthenticationProviders + verify(_authenticationProvider1).setGroupAccessor(any(GroupPrincipalAccessor.class)); + verify(authenticationProvider2).setGroupAccessor(any(GroupPrincipalAccessor.class)); + } + + public void testCreateBrokerWithGroupProvider() + { + ConfigurationEntry groupProviderEntry = mock(ConfigurationEntry.class); + GroupProvider groupProvider = mock(GroupProvider.class); + _brokerEntryChildren.put(GroupProvider.class.getSimpleName(), Arrays.asList(groupProviderEntry)); + + RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{groupProviderEntry, _authenticationProviderEntry1}, + new ConfiguredObject[]{groupProvider, _authenticationProvider1}); + + Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry); + + assertNotNull(broker); + assertEquals(_brokerId, broker.getId()); + assertEquals(Collections.singletonList(groupProvider), broker.getGroupProviders()); + } + + public void testCreateBrokerWithPlugins() + { + ConfigurationEntry pluginEntry = mock(ConfigurationEntry.class); + Plugin plugin = mock(Plugin.class); + _brokerEntryChildren.put(Plugin.class.getSimpleName(), Arrays.asList(pluginEntry)); + + RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{pluginEntry, _authenticationProviderEntry1}, + new ConfiguredObject[]{plugin, _authenticationProvider1}); + + Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry); + + assertNotNull(broker); + assertEquals(_brokerId, broker.getId()); + assertEquals(Collections.singleton(plugin), new HashSet<ConfiguredObject>(broker.getChildren(Plugin.class))); + } + + public void testCreateBrokerWithKeyStores() + { + ConfigurationEntry pluginEntry = mock(ConfigurationEntry.class); + KeyStore keyStore = mock(KeyStore.class); + _brokerEntryChildren.put(KeyStore.class.getSimpleName(), Arrays.asList(pluginEntry)); + + RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{pluginEntry, _authenticationProviderEntry1}, + new ConfiguredObject[]{keyStore, _authenticationProvider1}); + + Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry); + + assertNotNull(broker); + assertEquals(_brokerId, broker.getId()); + assertEquals(Collections.singleton(keyStore), new HashSet<ConfiguredObject>(broker.getChildren(KeyStore.class))); + } + + public void testCreateBrokerWithTrustStores() + { + ConfigurationEntry pluginEntry = mock(ConfigurationEntry.class); + TrustStore trustStore = mock(TrustStore.class); + _brokerEntryChildren.put(TrustStore.class.getSimpleName(), Arrays.asList(pluginEntry)); + + RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{pluginEntry, _authenticationProviderEntry1}, + new ConfiguredObject[]{trustStore, _authenticationProvider1}); + + Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry); + + assertNotNull(broker); + assertEquals(_brokerId, broker.getId()); + assertEquals(Collections.singleton(trustStore), new HashSet<ConfiguredObject>(broker.getChildren(TrustStore.class))); + } + + private String convertToString(Object attributeValue) + { + return String.valueOf(attributeValue); + } + + private RecovererProvider createRecoveryProvider(final ConfigurationEntry[] entries, final ConfiguredObject[] objectsToRecoverer) + { + RecovererProvider recovererProvider = new RecovererProvider() + { + @Override + public ConfiguredObjectRecoverer<? extends ConfiguredObject> getRecoverer(String type) + { + @SuppressWarnings({ "unchecked", "rawtypes" }) + final ConfiguredObjectRecoverer<? extends ConfiguredObject> recovever = new ConfiguredObjectRecoverer() + { + @Override + public ConfiguredObject create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents) + { + for (int i = 0; i < entries.length; i++) + { + ConfigurationEntry e = entries[i]; + if (entry == e) + { + return objectsToRecoverer[i]; + } + } + return null; + } + }; + + return recovever; + } + }; + return recovererProvider; + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProviderTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProviderTest.java new file mode 100644 index 0000000000..c95f67beb9 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProviderTest.java @@ -0,0 +1,62 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.startup; + +import static org.mockito.Mockito.mock; +import junit.framework.TestCase; + +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.logging.LogRecorder; +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.model.Plugin; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.stats.StatisticsGatherer; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; + +public class DefaultRecovererProviderTest extends TestCase +{ + public void testGetRecoverer() + { + String[] supportedTypes = {Broker.class.getSimpleName(), + VirtualHost.class.getSimpleName(), AuthenticationProvider.class.getSimpleName(), + GroupProvider.class.getSimpleName(), Plugin.class.getSimpleName(), Port.class.getSimpleName()}; + + // mocking the required object + StatisticsGatherer statisticsGatherer = mock(StatisticsGatherer.class); + VirtualHostRegistry virtualHostRegistry = mock(VirtualHostRegistry.class); + LogRecorder logRecorder = mock(LogRecorder.class); + RootMessageLogger rootMessageLogger = mock(RootMessageLogger.class); + TaskExecutor taskExecutor = mock(TaskExecutor.class); + + DefaultRecovererProvider provider = new DefaultRecovererProvider(statisticsGatherer, virtualHostRegistry, logRecorder, rootMessageLogger, taskExecutor); + for (String configuredObjectType : supportedTypes) + { + ConfiguredObjectRecoverer<?> recovever = provider.getRecoverer(configuredObjectType); + assertNotNull("Null recoverer for type: " + configuredObjectType, recovever); + } + } + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/GroupProviderRecovererTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/GroupProviderRecovererTest.java new file mode 100644 index 0000000000..6713574e4b --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/GroupProviderRecovererTest.java @@ -0,0 +1,97 @@ +/* + * + * 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.configuration.startup; +import static org.mockito.Mockito.*; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.plugin.GroupManagerFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; +import org.apache.qpid.server.security.group.GroupManager; + +import junit.framework.TestCase; + +public class GroupProviderRecovererTest extends TestCase +{ + + private UUID _id; + private Map<String, Object> _attributes; + + private GroupManagerFactory _factory; + private QpidServiceLoader<GroupManagerFactory> _groupManagerServiceLoader; + private Broker _broker; + private ConfigurationEntry _configurationEntry; + + @SuppressWarnings("unchecked") + protected void setUp() throws Exception + { + super.setUp(); + _id = UUID.randomUUID(); + _attributes = new HashMap<String, Object>(); + + _factory = mock(GroupManagerFactory.class); + + _groupManagerServiceLoader = mock(QpidServiceLoader.class); + when(_groupManagerServiceLoader.instancesOf(GroupManagerFactory.class)).thenReturn(Collections.singletonList(_factory )); + + _broker = mock(Broker.class); + + _configurationEntry = mock(ConfigurationEntry.class); + when(_configurationEntry.getId()).thenReturn(_id); + when(_configurationEntry.getAttributes()).thenReturn(_attributes); + } + + public void testCreate() + { + GroupManager groupManager = mock(GroupManager.class); + String name = groupManager.getClass().getSimpleName(); + when(_factory.createInstance(_attributes)).thenReturn(groupManager); + GroupProviderRecoverer groupProviderRecoverer = new GroupProviderRecoverer(_groupManagerServiceLoader); + GroupProvider groupProvider = groupProviderRecoverer.create(null, _configurationEntry, _broker); + assertNotNull("Null group provider", groupProvider); + assertEquals("Unexpected name", name, groupProvider.getName()); + assertEquals("Unexpected ID", _id, groupProvider.getId()); + } + + public void testCreateThrowsExceptionWhenNoGroupManagerIsCreated() + { + when(_factory.createInstance(_attributes)).thenReturn(null); + + GroupProviderRecoverer groupProviderRecoverer = new GroupProviderRecoverer(_groupManagerServiceLoader); + try + { + groupProviderRecoverer.create(null, _configurationEntry, _broker); + fail("Configuration exception should be thrown when group manager is not created"); + } + catch(IllegalConfigurationException e) + { + // pass + } + } + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/KeyStoreRecovererTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/KeyStoreRecovererTest.java new file mode 100644 index 0000000000..0d7dc1bb06 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/KeyStoreRecovererTest.java @@ -0,0 +1,111 @@ +/* + * + * 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.configuration.startup; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.KeyStore; +import org.apache.qpid.server.model.TrustStore; + +import junit.framework.TestCase; + +public class KeyStoreRecovererTest extends TestCase +{ + + public void testCreateWithAllAttributesProvided() + { + Map<String, Object> attributes = getKeyStoreAttributes(); + + UUID id = UUID.randomUUID(); + Broker broker = mock(Broker.class); + ConfigurationEntry entry = mock(ConfigurationEntry.class); + when(entry.getAttributes()).thenReturn(attributes); + when(entry.getId()).thenReturn(id); + + KeyStoreRecoverer recovever = new KeyStoreRecoverer(); + + KeyStore KeyStore = recovever.create(null, entry, broker); + assertNotNull("Key store configured object is not created", KeyStore); + assertEquals(id, KeyStore.getId()); + assertEquals("my-secret-password", KeyStore.getPassword()); + + assertNull("Password was unexpectedly returned from configured object", KeyStore.getAttribute(TrustStore.PASSWORD)); + + // password attribute should not be exposed by a key store configured object + // so, we should set password value to null in the map being used to create the key store configured object + attributes.put(KeyStore.PASSWORD, null); + for (Map.Entry<String, Object> attribute : attributes.entrySet()) + { + Object attributeValue = KeyStore.getAttribute(attribute.getKey()); + assertEquals("Unexpected value of attribute '" + attribute.getKey() + "'", attribute.getValue(), attributeValue); + } + } + + private Map<String, Object> getKeyStoreAttributes() + { + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(KeyStore.NAME, getName()); + attributes.put(KeyStore.PATH, "/path/to/KeyStore"); + attributes.put(KeyStore.PASSWORD, "my-secret-password"); + attributes.put(KeyStore.TYPE, "NON-JKS"); + attributes.put(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM, "NON-STANDARD"); + attributes.put(KeyStore.CERTIFICATE_ALIAS, "my-cert-alias"); + attributes.put(KeyStore.DESCRIPTION, "description"); + return attributes; + } + + public void testCreateWithMissedRequiredAttributes() + { + Map<String, Object> attributes = getKeyStoreAttributes(); + + UUID id = UUID.randomUUID(); + Broker broker = mock(Broker.class); + ConfigurationEntry entry = mock(ConfigurationEntry.class); + when(entry.getId()).thenReturn(id); + + KeyStoreRecoverer recovever = new KeyStoreRecoverer(); + + String[] mandatoryProperties = {KeyStore.NAME, KeyStore.PATH, KeyStore.PASSWORD}; + for (int i = 0; i < mandatoryProperties.length; i++) + { + Map<String, Object> properties = new HashMap<String, Object>(attributes); + properties.remove(mandatoryProperties[i]); + when(entry.getAttributes()).thenReturn(properties); + try + { + recovever.create(null, entry, broker); + fail("Cannot create key store without a " + mandatoryProperties[i]); + } + catch(IllegalArgumentException e) + { + // pass + } + } + } + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/PluginRecovererTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/PluginRecovererTest.java new file mode 100644 index 0000000000..42fd742407 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/PluginRecovererTest.java @@ -0,0 +1,117 @@ +/* + * + * 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.configuration.startup; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import junit.framework.TestCase; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Plugin; +import org.apache.qpid.server.plugin.PluginFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; + +public class PluginRecovererTest extends TestCase +{ + private UUID _id; + private Map<String, Object> _attributes; + + private PluginFactory _factory; + private QpidServiceLoader<PluginFactory> _pluginFactoryServiceLoader; + private Broker _broker; + private ConfigurationEntry _configurationEntry; + + @SuppressWarnings("unchecked") + protected void setUp() throws Exception + { + super.setUp(); + _id = UUID.randomUUID(); + _attributes = new HashMap<String, Object>(); + + _factory = mock(PluginFactory.class); + + _pluginFactoryServiceLoader = mock(QpidServiceLoader.class); + when(_pluginFactoryServiceLoader.instancesOf(PluginFactory.class)).thenReturn(Collections.singletonList(_factory )); + + _broker = mock(Broker.class); + + _configurationEntry = mock(ConfigurationEntry.class); + when(_configurationEntry.getId()).thenReturn(_id); + when(_configurationEntry.getAttributes()).thenReturn(_attributes); + } + + public void testCreate() + { + Plugin pluginFromFactory = mock(Plugin.class); + when(pluginFromFactory.getId()).thenReturn(_id); + when(_factory.createInstance(_id, _attributes, _broker)).thenReturn(pluginFromFactory); + + PluginRecoverer pluginRecoverer = new PluginRecoverer(_pluginFactoryServiceLoader); + ConfiguredObject pluginFromRecoverer = pluginRecoverer.create(null, _configurationEntry, _broker); + assertNotNull("Null group provider", pluginFromRecoverer); + assertSame("Unexpected plugin", pluginFromFactory, pluginFromRecoverer); + assertEquals("Unexpected ID", _id, pluginFromRecoverer.getId()); + } + + public void testCreateThrowsExceptionForUnexpectedId() + { + Plugin pluginFromFactory = mock(Plugin.class); + when(pluginFromFactory.getId()).thenReturn(UUID.randomUUID()); + when(_factory.createInstance(_id, _attributes, _broker)).thenReturn(pluginFromFactory); + + PluginRecoverer pluginRecoverer = new PluginRecoverer(_pluginFactoryServiceLoader); + try + { + pluginRecoverer.create(null, _configurationEntry, _broker); + fail("An exception should be thrown for incorrect id"); + } + catch(IllegalStateException e) + { + //pass + } + } + + public void testCreateThrowsExceptionWhenNoPluginIsCreated() + { + when(_factory.createInstance(_id, _attributes, _broker)).thenReturn(null); + + PluginRecoverer pluginRecoverer = new PluginRecoverer(_pluginFactoryServiceLoader); + try + { + pluginRecoverer.create(null, _configurationEntry, _broker); + fail("Configuration exception should be thrown when plugin is not created"); + } + catch(IllegalConfigurationException e) + { + // pass + } + } + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/TrustStoreRecovererTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/TrustStoreRecovererTest.java new file mode 100644 index 0000000000..3b64f45c80 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/TrustStoreRecovererTest.java @@ -0,0 +1,108 @@ +/* + * + * 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.configuration.startup; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.test.utils.QpidTestCase; + +public class TrustStoreRecovererTest extends QpidTestCase +{ + public void testCreateWithAllAttributesProvided() + { + Map<String, Object> attributes = getTrustStoreAttributes(); + + UUID id = UUID.randomUUID(); + Broker broker = mock(Broker.class); + ConfigurationEntry entry = mock(ConfigurationEntry.class); + when(entry.getAttributes()).thenReturn(attributes); + when(entry.getId()).thenReturn(id); + + TrustStoreRecoverer recovever = new TrustStoreRecoverer(); + + TrustStore trustStore = recovever.create(null, entry, broker); + assertNotNull("Trust store configured object is not created", trustStore); + assertEquals(id, trustStore.getId()); + assertEquals("my-secret-password", trustStore.getPassword()); + + assertNull("Password was unexpectedly returned from configured object", trustStore.getAttribute(TrustStore.PASSWORD)); + + // password attribute should not be exposed by a trust store configured object + // so, we should set password value to null in the map being used to create the trust store configured object + attributes.put(TrustStore.PASSWORD, null); + for (Map.Entry<String, Object> attribute : attributes.entrySet()) + { + Object attributeValue = trustStore.getAttribute(attribute.getKey()); + assertEquals("Unexpected value of attribute '" + attribute.getKey() + "'", attribute.getValue(), attributeValue); + } + } + + private Map<String, Object> getTrustStoreAttributes() + { + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(TrustStore.NAME, getName()); + attributes.put(TrustStore.PATH, "/path/to/truststore"); + attributes.put(TrustStore.PASSWORD, "my-secret-password"); + attributes.put(TrustStore.TYPE, "NON-JKS"); + attributes.put(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM, "NON-STANDARD"); + attributes.put(TrustStore.DESCRIPTION, "Description"); + return attributes; + } + + public void testCreateWithMissedRequiredAttributes() + { + Map<String, Object> attributes = getTrustStoreAttributes(); + + UUID id = UUID.randomUUID(); + Broker broker = mock(Broker.class); + ConfigurationEntry entry = mock(ConfigurationEntry.class); + when(entry.getAttributes()).thenReturn(attributes); + when(entry.getId()).thenReturn(id); + + TrustStoreRecoverer recovever = new TrustStoreRecoverer(); + + String[] mandatoryProperties = {TrustStore.NAME, TrustStore.PATH, TrustStore.PASSWORD}; + for (int i = 0; i < mandatoryProperties.length; i++) + { + Map<String, Object> properties = new HashMap<String, Object>(attributes); + properties.remove(mandatoryProperties[i]); + when(entry.getAttributes()).thenReturn(properties); + try + { + recovever.create(null, entry, broker); + fail("Cannot create key store without a " + mandatoryProperties[i]); + } + catch(IllegalArgumentException e) + { + // pass + } + } + } + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostRecovererTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostRecovererTest.java new file mode 100644 index 0000000000..57d219f85f --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostRecovererTest.java @@ -0,0 +1,124 @@ +/* + * + * 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.configuration.startup; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.stats.StatisticsGatherer; + +public class VirtualHostRecovererTest extends TestCase +{ + public void testCreate() + { + StatisticsGatherer statisticsGatherer = mock(StatisticsGatherer.class); + SecurityManager securityManager = mock(SecurityManager.class); + ConfigurationEntry entry = mock(ConfigurationEntry.class); + Broker parent = mock(Broker.class); + when(parent.getSecurityManager()).thenReturn(securityManager); + + VirtualHostRecoverer recoverer = new VirtualHostRecoverer(statisticsGatherer); + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(VirtualHost.NAME, getName()); + attributes.put(VirtualHost.CONFIG_PATH, "/path/to/virtualhost.xml"); + when(entry.getAttributes()).thenReturn(attributes); + + VirtualHost host = recoverer.create(null, entry, parent); + + assertNotNull("Null is returned", host); + assertEquals("Unexpected name", getName(), host.getName()); + } + + public void testCreateVirtualHostFromStoreConfigAtrributes() + { + StatisticsGatherer statisticsGatherer = mock(StatisticsGatherer.class); + SecurityManager securityManager = mock(SecurityManager.class); + ConfigurationEntry entry = mock(ConfigurationEntry.class); + Broker parent = mock(Broker.class); + when(parent.getSecurityManager()).thenReturn(securityManager); + + VirtualHostRecoverer recoverer = new VirtualHostRecoverer(statisticsGatherer); + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(VirtualHost.NAME, getName()); + attributes.put(VirtualHost.STORE_PATH, "/path/to/virtualhost/store"); + attributes.put(VirtualHost.STORE_TYPE, "DERBY"); + when(entry.getAttributes()).thenReturn(attributes); + + VirtualHost host = recoverer.create(null, entry, parent); + + assertNotNull("Null is returned", host); + assertEquals("Unexpected name", getName(), host.getName()); + } + + public void testCreateWithoutMandatoryAttributesResultsInException() + { + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(VirtualHost.NAME, getName()); + attributes.put(VirtualHost.CONFIG_PATH, "/path/to/virtualhost.xml"); + String[] mandatoryAttributes = {VirtualHost.NAME, VirtualHost.CONFIG_PATH}; + + checkMandatoryAttributesAreValidated(mandatoryAttributes, attributes); + + attributes = new HashMap<String, Object>(); + attributes.put(VirtualHost.NAME, getName()); + attributes.put(VirtualHost.STORE_PATH, "/path/to/store"); + attributes.put(VirtualHost.STORE_TYPE, "DERBY"); + mandatoryAttributes = new String[]{VirtualHost.NAME, VirtualHost.STORE_PATH, VirtualHost.STORE_TYPE}; + + checkMandatoryAttributesAreValidated(mandatoryAttributes, attributes); + } + + public void checkMandatoryAttributesAreValidated(String[] mandatoryAttributes, Map<String, Object> attributes) + { + StatisticsGatherer statisticsGatherer = mock(StatisticsGatherer.class); + SecurityManager securityManager = mock(SecurityManager.class); + ConfigurationEntry entry = mock(ConfigurationEntry.class); + Broker parent = mock(Broker.class); + when(parent.getSecurityManager()).thenReturn(securityManager); + VirtualHostRecoverer recoverer = new VirtualHostRecoverer(statisticsGatherer); + + for (String name : mandatoryAttributes) + { + Map<String, Object> copy = new HashMap<String, Object>(attributes); + copy.remove(name); + when(entry.getAttributes()).thenReturn(copy); + try + { + recoverer.create(null, entry, parent); + fail("Cannot create a virtual host without a manadatory attribute " + name); + } + catch(IllegalConfigurationException e) + { + // pass + } + } + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java new file mode 100644 index 0000000000..b357c0b8e9 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java @@ -0,0 +1,392 @@ +/* + * + * 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.configuration.store; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.model.KeyStore; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.Transport; +import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; +import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager; +import org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManager; +import org.apache.qpid.test.utils.QpidTestCase; + +public abstract class ConfigurationEntryStoreTestCase extends QpidTestCase +{ + private ConfigurationEntryStore _store; + + private UUID _brokerId; + private UUID _virtualHostId; + private UUID _authenticationProviderId; + + private Map<String, Object> _brokerAttributes; + private Map<String, Object> _virtualHostAttributes; + private Map<String, Object> _authenticationProviderAttributes; + + public void setUp() throws Exception + { + super.setUp(); + + _brokerId = UUID.randomUUID(); + _brokerAttributes = new HashMap<String, Object>(); + _brokerAttributes.put(Broker.DEFAULT_VIRTUAL_HOST, "test"); + _brokerAttributes.put(Broker.DEFAULT_AUTHENTICATION_PROVIDER, "authenticationProvider1"); + _brokerAttributes.put(Broker.ALERT_THRESHOLD_MESSAGE_AGE, 9); + _brokerAttributes.put(Broker.ALERT_THRESHOLD_MESSAGE_COUNT, 8); + _brokerAttributes.put(Broker.ALERT_THRESHOLD_QUEUE_DEPTH, 7); + _brokerAttributes.put(Broker.ALERT_THRESHOLD_MESSAGE_SIZE, 6); + _brokerAttributes.put(Broker.ALERT_REPEAT_GAP, 5); + _brokerAttributes.put(Broker.FLOW_CONTROL_SIZE_BYTES, 5); + _brokerAttributes.put(Broker.FLOW_CONTROL_RESUME_SIZE_BYTES, 3); + _brokerAttributes.put(Broker.MAXIMUM_DELIVERY_ATTEMPTS, 2); + _brokerAttributes.put(Broker.DEAD_LETTER_QUEUE_ENABLED, true); + _brokerAttributes.put(Broker.HOUSEKEEPING_CHECK_PERIOD, 1); + _brokerAttributes.put(Broker.ACL_FILE, "/path/to/acl"); + _brokerAttributes.put(Broker.SESSION_COUNT_LIMIT, 1000); + _brokerAttributes.put(Broker.HEART_BEAT_DELAY, 2000); + _brokerAttributes.put(Broker.STATISTICS_REPORTING_PERIOD, 4000); + _brokerAttributes.put(Broker.STATISTICS_REPORTING_RESET_ENABLED, true); + + _virtualHostId = UUID.randomUUID(); + _virtualHostAttributes = new HashMap<String, Object>(); + _virtualHostAttributes.put(VirtualHost.NAME, "test"); + _virtualHostAttributes.put(VirtualHost.CONFIG_PATH, "/path/to/phantom/test"); + + _authenticationProviderId = UUID.randomUUID(); + _authenticationProviderAttributes = new HashMap<String, Object>(); + _authenticationProviderAttributes.put(AuthenticationProvider.NAME, "authenticationProvider1"); + _authenticationProviderAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, AnonymousAuthenticationManager.class.getSimpleName()); + + _store = createStore(_brokerId, _brokerAttributes); + addConfiguration(_virtualHostId, VirtualHost.class.getSimpleName(), _virtualHostAttributes); + addConfiguration(_authenticationProviderId, AuthenticationProvider.class.getSimpleName(), _authenticationProviderAttributes); + } + + // ??? perhaps it should not be abstract + protected abstract ConfigurationEntryStore createStore(UUID brokerId, Map<String, Object> brokerAttributes) throws Exception; + + protected abstract void addConfiguration(UUID id, String type, Map<String, Object> attributes); + + protected ConfigurationEntryStore getStore() + { + return _store; + } + + public void testGetRootEntry() + { + ConfigurationEntry brokerConfigEntry = _store.getRootEntry(); + assertNotNull("Root entry does not exist", brokerConfigEntry); + assertEquals("Unexpected id", _brokerId, brokerConfigEntry.getId()); + assertEquals("Unexpected type ", Broker.class.getSimpleName(), brokerConfigEntry.getType()); + Map<String, Object> attributes = brokerConfigEntry.getAttributes(); + assertNotNull("Attributes cannot be null", attributes); + assertEquals("Unexpected attributes", _brokerAttributes, attributes); + } + + public void testGetEntry() + { + ConfigurationEntry authenticationProviderConfigEntry = _store.getEntry(_authenticationProviderId); + assertNotNull("Provider with id " + _authenticationProviderId + " should exist", authenticationProviderConfigEntry); + assertEquals("Unexpected id", _authenticationProviderId, authenticationProviderConfigEntry.getId()); + assertEquals("Unexpected type ", AuthenticationProvider.class.getSimpleName(), authenticationProviderConfigEntry.getType()); + Map<String, Object> attributes = authenticationProviderConfigEntry.getAttributes(); + assertNotNull("Attributes cannot be null", attributes); + assertEquals("Unexpected attributes", _authenticationProviderAttributes, attributes); + } + + public void testRemove() + { + Map<String, Object> virtualHostAttributes = new HashMap<String, Object>(); + virtualHostAttributes.put(VirtualHost.NAME, getName()); + virtualHostAttributes.put(VirtualHost.CONFIG_PATH, "/path/to/phantom/virtualhost/config"); + UUID virtualHostId = UUID.randomUUID(); + addConfiguration(virtualHostId, VirtualHost.class.getSimpleName(), virtualHostAttributes); + + assertNotNull("Virtual host with id " + virtualHostId + " should exist", _store.getEntry(virtualHostId)); + + _store.remove(virtualHostId); + assertNull("Authentication provider configuration should be removed", _store.getEntry(virtualHostId)); + } + + public void testRemoveMultipleEntries() + { + Map<String, Object> virtualHost1Attributes = new HashMap<String, Object>(); + virtualHost1Attributes.put(VirtualHost.NAME, "test1"); + virtualHost1Attributes.put(VirtualHost.CONFIG_PATH, "/path/to/phantom/virtualhost/config1"); + UUID virtualHost1Id = UUID.randomUUID(); + addConfiguration(virtualHost1Id, VirtualHost.class.getSimpleName(), virtualHost1Attributes); + + Map<String, Object> virtualHost2Attributes = new HashMap<String, Object>(); + virtualHost2Attributes.put(VirtualHost.NAME, "test1"); + virtualHost2Attributes.put(VirtualHost.CONFIG_PATH, "/path/to/phantom/virtualhost/config2"); + UUID virtualHost2Id = UUID.randomUUID(); + addConfiguration(virtualHost2Id, VirtualHost.class.getSimpleName(), virtualHost2Attributes); + + assertNotNull("Virtual host with id " + virtualHost1Id + " should exist", _store.getEntry(virtualHost1Id)); + assertNotNull("Virtual host with id " + virtualHost2Id + " should exist", _store.getEntry(virtualHost2Id)); + + UUID[] deletedIds = _store.remove(virtualHost1Id, virtualHost2Id); + assertNotNull("Unexpected deleted ids", deletedIds); + assertEquals("Unexpected id of first deleted virtual host", virtualHost1Id , deletedIds[0]); + assertEquals("Unexpected id of second deleted virtual host", virtualHost2Id , deletedIds[1]); + assertNull("First virtual host configuration should be removed", _store.getEntry(virtualHost1Id)); + assertNull("Second virtual host configuration should be removed", _store.getEntry(virtualHost2Id)); + } + + public void testSaveBroker() + { + ConfigurationEntry brokerConfigEntry = _store.getRootEntry(); + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(Broker.DEFAULT_VIRTUAL_HOST, "test"); + attributes.put(Broker.DEFAULT_AUTHENTICATION_PROVIDER, "authenticationProvider1"); + attributes.put(Broker.ALERT_THRESHOLD_MESSAGE_AGE, 19); + attributes.put(Broker.ALERT_THRESHOLD_MESSAGE_COUNT, 18); + attributes.put(Broker.ALERT_THRESHOLD_QUEUE_DEPTH, 17); + attributes.put(Broker.ALERT_THRESHOLD_MESSAGE_SIZE, 16); + attributes.put(Broker.ALERT_REPEAT_GAP, 15); + attributes.put(Broker.FLOW_CONTROL_SIZE_BYTES, 15); + attributes.put(Broker.FLOW_CONTROL_RESUME_SIZE_BYTES, 13); + attributes.put(Broker.MAXIMUM_DELIVERY_ATTEMPTS, 12); + attributes.put(Broker.DEAD_LETTER_QUEUE_ENABLED, false); + attributes.put(Broker.HOUSEKEEPING_CHECK_PERIOD, 11); + attributes.put(Broker.ACL_FILE, "/path/to/acl1"); + attributes.put(Broker.SESSION_COUNT_LIMIT, 11000); + attributes.put(Broker.HEART_BEAT_DELAY, 12000); + attributes.put(Broker.STATISTICS_REPORTING_PERIOD, 14000); + attributes.put(Broker.STATISTICS_REPORTING_RESET_ENABLED, false); + ConfigurationEntry updatedBrokerEntry = new ConfigurationEntry(_brokerId, Broker.class.getSimpleName(), attributes, + brokerConfigEntry.getChildrenIds(), _store); + + _store.save(updatedBrokerEntry); + + ConfigurationEntry newBrokerConfigEntry = _store.getRootEntry(); + assertNotNull("Root entry does not exist", newBrokerConfigEntry); + assertEquals("Unexpected id", _brokerId, newBrokerConfigEntry.getId()); + assertEquals("Unexpected type ", Broker.class.getSimpleName(), newBrokerConfigEntry.getType()); + Map<String, Object> newBrokerattributes = newBrokerConfigEntry.getAttributes(); + assertNotNull("Attributes cannot be null", newBrokerattributes); + assertEquals("Unexpected attributes", attributes, newBrokerattributes); + } + + public void testSaveNewVirtualHost() + { + Map<String, Object> virtualHostAttributes = new HashMap<String, Object>(); + virtualHostAttributes.put(VirtualHost.NAME, "test1"); + virtualHostAttributes.put(VirtualHost.CONFIG_PATH, "/path/to/phantom/virtualhost/config1"); + UUID virtualHostId = UUID.randomUUID(); + ConfigurationEntry hostEntry = new ConfigurationEntry(virtualHostId, VirtualHost.class.getSimpleName(), virtualHostAttributes, + Collections.<UUID> emptySet(), _store); + + _store.save(hostEntry); + + ConfigurationEntry configurationEntry = _store.getEntry(virtualHostId); + assertEquals("Unexpected virtual host configuration", hostEntry, configurationEntry); + assertEquals("Unexpected type", VirtualHost.class.getSimpleName(), configurationEntry.getType()); + assertEquals("Unexpected virtual host attributes", hostEntry.getAttributes(), configurationEntry.getAttributes()); + assertTrue("Unexpected virtual host children found", hostEntry.getChildrenIds().isEmpty()); + } + + public void testSaveExistingVirtualHost() + { + ConfigurationEntry hostEntry = _store.getEntry(_virtualHostId); + assertNotNull("Host configuration is not found", hostEntry); + + Map<String, Object> virtualHostAttributes = new HashMap<String, Object>(); + virtualHostAttributes.put(VirtualHost.NAME, "test"); + virtualHostAttributes.put(VirtualHost.CONFIG_PATH, "/path/to/new/phantom/test/configuration"); + + ConfigurationEntry updatedEntry = new ConfigurationEntry(_virtualHostId, VirtualHost.class.getSimpleName(), virtualHostAttributes, + hostEntry.getChildrenIds(), _store); + _store.save(updatedEntry); + + ConfigurationEntry newHostEntry = _store.getEntry(_virtualHostId); + assertEquals("Unexpected virtual host configuration", updatedEntry, newHostEntry); + assertEquals("Unexpected type", VirtualHost.class.getSimpleName(), newHostEntry.getType()); + assertEquals("Unexpected virtual host attributes", updatedEntry.getAttributes(), newHostEntry.getAttributes()); + assertEquals("Unexpected virtual host children found", updatedEntry.getChildrenIds(), newHostEntry.getChildrenIds()); + } + + public void testSaveNewAuthenticationProvider() + { + UUID authenticationProviderId = UUID.randomUUID(); + Map<String, Object> authenticationProviderAttributes = new HashMap<String, Object>(); + authenticationProviderAttributes.put(AuthenticationProvider.NAME, "authenticationProvider1"); + authenticationProviderAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, ExternalAuthenticationManager.class.getSimpleName()); + ConfigurationEntry providerEntry = new ConfigurationEntry(authenticationProviderId, AuthenticationProvider.class.getSimpleName(), + authenticationProviderAttributes, Collections.<UUID> emptySet(), _store); + + _store.save(providerEntry); + + ConfigurationEntry storeEntry = _store.getEntry(authenticationProviderId); + assertEquals("Unexpected provider configuration", providerEntry, storeEntry); + assertEquals("Unexpected type", AuthenticationProvider.class.getSimpleName(), storeEntry.getType()); + assertEquals("Unexpected provider attributes", providerEntry.getAttributes(), storeEntry.getAttributes()); + assertTrue("Unexpected provider children found", storeEntry.getChildrenIds().isEmpty()); + } + + public void testSaveExistingAuthenticationProvider() + { + ConfigurationEntry providerEntry = _store.getEntry(_authenticationProviderId); + assertNotNull("provider configuration is not found", providerEntry); + + Map<String, Object> authenticationProviderAttributes = new HashMap<String, Object>(); + authenticationProviderAttributes.put(AuthenticationProvider.NAME, "authenticationProvider1"); + authenticationProviderAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, ExternalAuthenticationManager.class.getSimpleName()); + ConfigurationEntry updatedEntry = new ConfigurationEntry(_authenticationProviderId, AuthenticationProvider.class.getSimpleName(), + authenticationProviderAttributes, Collections.<UUID> emptySet(), _store); + _store.save(updatedEntry); + + ConfigurationEntry storeEntry = _store.getEntry(_authenticationProviderId); + assertEquals("Unexpected provider configuration", updatedEntry, storeEntry); + assertEquals("Unexpected type", AuthenticationProvider.class.getSimpleName(), storeEntry.getType()); + assertEquals("Unexpected provider attributes", updatedEntry.getAttributes(), storeEntry.getAttributes()); + assertTrue("Unexpected provider children found", storeEntry.getChildrenIds().isEmpty()); + } + + public void testSaveTrustStore() + { + UUID trustStoreId = UUID.randomUUID(); + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(TrustStore.NAME, getName()); + attributes.put(TrustStore.PATH, "/path/to/truststore"); + attributes.put(TrustStore.PASSWORD, "my-secret-password"); + attributes.put(TrustStore.TYPE, "NON-JKS"); + attributes.put(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM, "NON-STANDARD"); + attributes.put(TrustStore.DESCRIPTION, "Description"); + + ConfigurationEntry trustStoreEntry = new ConfigurationEntry(trustStoreId, TrustStore.class.getSimpleName(), attributes, + Collections.<UUID> emptySet(), _store); + + _store.save(trustStoreEntry); + + ConfigurationEntry storeEntry = _store.getEntry(trustStoreId); + assertEquals("Unexpected trust store configuration", trustStoreEntry, storeEntry); + assertEquals("Unexpected type", TrustStore.class.getSimpleName(), storeEntry.getType()); + assertEquals("Unexpected provider attributes", trustStoreEntry.getAttributes(), storeEntry.getAttributes()); + assertTrue("Unexpected provider children found", storeEntry.getChildrenIds().isEmpty()); + } + + public void testSaveKeyStore() + { + UUID keyStoreId = UUID.randomUUID(); + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(KeyStore.NAME, getName()); + attributes.put(KeyStore.PATH, "/path/to/truststore"); + attributes.put(KeyStore.PASSWORD, "my-secret-password"); + attributes.put(KeyStore.TYPE, "NON-JKS"); + attributes.put(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM, "NON-STANDARD"); + attributes.put(KeyStore.DESCRIPTION, "Description"); + attributes.put(KeyStore.CERTIFICATE_ALIAS, "Alias"); + + ConfigurationEntry keyStoreEntry = new ConfigurationEntry(keyStoreId, KeyStore.class.getSimpleName(), attributes, Collections.<UUID> emptySet(), + _store); + + _store.save(keyStoreEntry); + + ConfigurationEntry storeEntry = _store.getEntry(keyStoreId); + assertEquals("Unexpected key store configuration", keyStoreEntry, storeEntry); + assertEquals("Unexpected type", KeyStore.class.getSimpleName(), storeEntry.getType()); + assertEquals("Unexpected provider attributes", keyStoreEntry.getAttributes(), storeEntry.getAttributes()); + assertTrue("Unexpected provider children found", storeEntry.getChildrenIds().isEmpty()); + } + + public void testSaveGroupProvider() + { + UUID groupProviderId = UUID.randomUUID(); + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(GroupProvider.NAME, getName()); + + ConfigurationEntry groupProviderEntry = new ConfigurationEntry(groupProviderId, GroupProvider.class.getSimpleName(), attributes, + Collections.<UUID> emptySet(), _store); + + _store.save(groupProviderEntry); + + ConfigurationEntry storeEntry = _store.getEntry(groupProviderId); + assertEquals("Unexpected group provider configuration", groupProviderEntry, storeEntry); + assertEquals("Unexpected type", GroupProvider.class.getSimpleName(), storeEntry.getType()); + assertEquals("Unexpected group provider attributes", groupProviderEntry.getAttributes(), storeEntry.getAttributes()); + assertTrue("Unexpected provider children found", storeEntry.getChildrenIds().isEmpty()); + } + + public void testSavePort() + { + UUID portId = UUID.randomUUID(); + Map<String, Object> attributes = new HashMap<String, Object>(); + Set<String> tcpTransportSet = Collections.singleton(Transport.TCP.name()); + attributes.put(Port.PORT, 9999); + attributes.put(Port.TRANSPORTS, tcpTransportSet); + attributes.put(Port.TCP_NO_DELAY, true); + attributes.put(Port.RECEIVE_BUFFER_SIZE, 1); + attributes.put(Port.SEND_BUFFER_SIZE, 2); + attributes.put(Port.NEED_CLIENT_AUTH, true); + attributes.put(Port.WANT_CLIENT_AUTH, true); + + ConfigurationEntry portEntry = new ConfigurationEntry(portId, Port.class.getSimpleName(), attributes, Collections.<UUID> emptySet(), _store); + + _store.save(portEntry); + + ConfigurationEntry storeEntry = _store.getEntry(portId); + assertEquals("Unexpected port configuration", portEntry, storeEntry); + assertEquals("Unexpected type", Port.class.getSimpleName(), storeEntry.getType()); + assertEquals("Unexpected port attributes", portEntry.getAttributes(), storeEntry.getAttributes()); + assertTrue("Unexpected port children found", storeEntry.getChildrenIds().isEmpty()); + } + + public void testMultipleSave() + { + UUID virtualHostId = UUID.randomUUID(); + Map<String, Object> virtualHostAttributes = new HashMap<String, Object>(); + virtualHostAttributes.put(VirtualHost.NAME, "test1"); + virtualHostAttributes.put(VirtualHost.CONFIG_PATH, "/path/to/phantom/virtualhost/config1"); + ConfigurationEntry hostEntry = new ConfigurationEntry(virtualHostId, VirtualHost.class.getSimpleName(), virtualHostAttributes, + Collections.<UUID> emptySet(), _store); + + UUID keyStoreId = UUID.randomUUID(); + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(KeyStore.NAME, getName()); + attributes.put(KeyStore.PATH, "/path/to/truststore"); + attributes.put(KeyStore.PASSWORD, "my-secret-password"); + attributes.put(KeyStore.TYPE, "NON-JKS"); + attributes.put(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM, "NON-STANDARD"); + attributes.put(KeyStore.DESCRIPTION, "Description"); + attributes.put(KeyStore.CERTIFICATE_ALIAS, "Alias"); + + ConfigurationEntry keyStoreEntry = new ConfigurationEntry(keyStoreId, KeyStore.class.getSimpleName(), attributes, Collections.<UUID> emptySet(), + _store); + + _store.save(hostEntry, keyStoreEntry); + + assertNotNull("Virtual host is not found", _store.getEntry(virtualHostId)); + assertNotNull("Key store is not found", _store.getEntry(keyStoreId)); + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java new file mode 100644 index 0000000000..7c9f4889f8 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java @@ -0,0 +1,216 @@ +package org.apache.qpid.server.configuration.store; + +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.test.utils.TestFileUtils; +import org.codehaus.jackson.JsonGenerationException; +import org.codehaus.jackson.map.JsonMappingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.SerializationConfig; + +public class JsonConfigurationEntryStoreTest extends ConfigurationEntryStoreTestCase +{ + private File _storeFile; + private ObjectMapper _objectMapper; + + @Override + public void setUp() throws Exception + { + _objectMapper = new ObjectMapper(); + _objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true); + super.setUp(); + } + + @Override + public void tearDown() throws Exception + { + _storeFile.delete(); + super.tearDown(); + } + + @Override + protected ConfigurationEntryStore createStore(UUID brokerId, Map<String, Object> brokerAttributes) throws Exception + { + _storeFile = createStoreFile(brokerId, brokerAttributes); + JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); + store.open(_storeFile.getAbsolutePath()); + return store; + } + + private File createStoreFile(UUID brokerId, Map<String, Object> brokerAttributes) throws IOException, + JsonGenerationException, JsonMappingException + { + Map<String, Object> brokerObjectMap = new HashMap<String, Object>(); + brokerObjectMap.put(Broker.ID, brokerId); + brokerObjectMap.put("@type", Broker.class.getSimpleName()); + brokerObjectMap.putAll(brokerAttributes); + + StringWriter sw = new StringWriter(); + _objectMapper.writeValue(sw, brokerObjectMap); + + String brokerJson = sw.toString(); + + return TestFileUtils.createTempFile(this, ".json", brokerJson); + } + + @Override + protected void addConfiguration(UUID id, String type, Map<String, Object> attributes) + { + ConfigurationEntryStore store = getStore(); + store.save(new ConfigurationEntry(id, type, attributes, Collections.<UUID> emptySet(), store)); + } + + public void testAttributeIsResolvedFromSystemProperties() + { + String aclLocation = "path/to/acl/" + getTestName(); + setTestSystemProperty("my.test.property", aclLocation); + + ConfigurationEntryStore store = getStore(); + ConfigurationEntry brokerConfigEntry = store.getRootEntry(); + Map<String, Object> attributes = new HashMap<String, Object>(brokerConfigEntry.getAttributes()); + attributes.put(Broker.ACL_FILE, "${my.test.property}"); + ConfigurationEntry updatedBrokerEntry = new ConfigurationEntry(brokerConfigEntry.getId(), Broker.class.getSimpleName(), + attributes, brokerConfigEntry.getChildrenIds(), store); + store.save(updatedBrokerEntry); + + JsonConfigurationEntryStore store2 = new JsonConfigurationEntryStore(); + store2.open(_storeFile.getAbsolutePath()); + + assertEquals("Unresolved ACL value", aclLocation, store2.getRootEntry().getAttributes().get(Broker.ACL_FILE)); + } + + public void testOpenEmpty() + { + File file = TestFileUtils.createTempFile(this, ".json"); + JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); + store.open(file.getAbsolutePath()); + ConfigurationEntry root = store.getRootEntry(); + assertNotNull("Root entry is not found", root); + store.copyTo(file.getAbsolutePath()); + + JsonConfigurationEntryStore store2 = new JsonConfigurationEntryStore(); + store2.open(file.getAbsolutePath()); + ConfigurationEntry root2 = store.getRootEntry(); + assertEquals("Unexpected root entry", root.getId(), root2.getId()); + } + + public void testOpenNotEmpty() throws Exception + { + UUID brokerId = UUID.randomUUID(); + Map<String, Object> brokerAttributes = new HashMap<String, Object>(); + brokerAttributes.put(Broker.NAME, getTestName()); + File file = createStoreFile(brokerId, brokerAttributes); + + JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); + store.open(file.getAbsolutePath()); + ConfigurationEntry root = store.getRootEntry(); + assertNotNull("Root entry is not found", root); + assertEquals("Unexpected root entry", brokerId, root.getId()); + Map<String, Object> attributes = root.getAttributes(); + assertNotNull("Attributes not found", attributes); + assertEquals("Unexpected number of attriburtes", 1, attributes.size()); + assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME)); + } + + public void testOpenInMemoryEmpty() + { + JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); + store.open(JsonConfigurationEntryStore.IN_MEMORY); + + ConfigurationEntry root = store.getRootEntry(); + assertNotNull("Root entry is not found", root); + } + + public void testOpenWithInitialStoreLocation() throws Exception + { + UUID brokerId = UUID.randomUUID(); + Map<String, Object> brokerAttributes = new HashMap<String, Object>(); + brokerAttributes.put(Broker.NAME, getTestName()); + File initialStoreFile = createStoreFile(brokerId, brokerAttributes); + + File storeFile = TestFileUtils.createTempFile(this, ".json"); + JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); + store.open(storeFile.getAbsolutePath(), initialStoreFile.getAbsolutePath()); + + ConfigurationEntry root = store.getRootEntry(); + assertNotNull("Root entry is not found", root); + assertEquals("Unexpected root entry", brokerId, root.getId()); + Map<String, Object> attributes = root.getAttributes(); + assertNotNull("Attributes not found", attributes); + assertEquals("Unexpected number of attriburtes", 1, attributes.size()); + assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME)); + } + + public void testOpenInMemoryWithInitialStoreLocation() throws Exception + { + UUID brokerId = UUID.randomUUID(); + Map<String, Object> brokerAttributes = new HashMap<String, Object>(); + brokerAttributes.put(Broker.NAME, getTestName()); + File initialStoreFile = createStoreFile(brokerId, brokerAttributes); + + JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); + store.open(JsonConfigurationEntryStore.IN_MEMORY, initialStoreFile.getAbsolutePath()); + + ConfigurationEntry root = store.getRootEntry(); + assertNotNull("Root entry is not found", root); + assertEquals("Unexpected root entry", brokerId, root.getId()); + Map<String, Object> attributes = root.getAttributes(); + assertNotNull("Attributes not found", attributes); + assertEquals("Unexpected number of attriburtes", 1, attributes.size()); + assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME)); + } + + public void testOpenWithInitialStore() throws Exception + { + UUID brokerId = UUID.randomUUID(); + Map<String, Object> brokerAttributes = new HashMap<String, Object>(); + brokerAttributes.put(Broker.NAME, getTestName()); + File initialStoreFile = createStoreFile(brokerId, brokerAttributes); + + JsonConfigurationEntryStore initialStore = new JsonConfigurationEntryStore(); + initialStore.open(initialStoreFile.getAbsolutePath()); + + File storeFile = TestFileUtils.createTempFile(this, ".json"); + JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); + store.open(storeFile.getAbsolutePath(), initialStore); + + ConfigurationEntry root = store.getRootEntry(); + assertNotNull("Root entry is not found", root); + assertEquals("Unexpected root entry", brokerId, root.getId()); + Map<String, Object> attributes = root.getAttributes(); + assertNotNull("Attributes not found", attributes); + assertEquals("Unexpected number of attriburtes", 1, attributes.size()); + assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME)); + } + + public void testOpenInMemoryWithInitialStore() throws Exception + { + UUID brokerId = UUID.randomUUID(); + Map<String, Object> brokerAttributes = new HashMap<String, Object>(); + brokerAttributes.put(Broker.NAME, getTestName()); + File initialStoreFile = createStoreFile(brokerId, brokerAttributes); + + JsonConfigurationEntryStore initialStore = new JsonConfigurationEntryStore(); + initialStore.open(initialStoreFile.getAbsolutePath()); + + JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); + store.open(JsonConfigurationEntryStore.IN_MEMORY, initialStore); + + ConfigurationEntry root = store.getRootEntry(); + assertNotNull("Root entry is not found", root); + assertEquals("Unexpected root entry", brokerId, root.getId()); + Map<String, Object> attributes = root.getAttributes(); + assertNotNull("Attributes not found", attributes); + assertEquals("Unexpected number of attriburtes", 1, attributes.size()); + assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME)); + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java new file mode 100644 index 0000000000..a67daac610 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java @@ -0,0 +1,341 @@ +package org.apache.qpid.server.configuration.store; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.any; + +import java.io.File; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.BrokerOptions; +import org.apache.qpid.server.configuration.BrokerConfigurationStoreCreator; +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.Protocol; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.test.utils.QpidTestCase; + +public class ManagementModeStoreHandlerTest extends QpidTestCase +{ + private ManagementModeStoreHandler _handler; + private BrokerOptions _options; + private ConfigurationEntryStore _store; + private ConfigurationEntry _root; + private ConfigurationEntry _portEntry; + private UUID _rootId, _portEntryId; + + protected void setUp() throws Exception + { + super.setUp(); + _rootId = UUID.randomUUID(); + _portEntryId = UUID.randomUUID(); + _store = mock(ConfigurationEntryStore.class); + _root = mock(ConfigurationEntry.class); + _portEntry = mock(ConfigurationEntry.class); + when(_store.getRootEntry()).thenReturn(_root); + when(_root.getId()).thenReturn(_rootId); + when(_portEntry.getId()).thenReturn(_portEntryId); + when(_store.getEntry(_portEntryId)).thenReturn(_portEntry); + when(_store.getEntry(_rootId)).thenReturn(_root); + when(_root.getChildrenIds()).thenReturn(Collections.singleton(_portEntryId)); + when(_portEntry.getType()).thenReturn(Port.class.getSimpleName()); + _options = new BrokerOptions(); + _handler = new ManagementModeStoreHandler(_store, _options); + } + + public void testOpenString() + { + try + { + _handler.open(TMP_FOLDER + File.separator + getTestName()); + fail("Exception should be thrown on attempt to call open method on a handler"); + } + catch (IllegalStateException e) + { + // pass + } + } + + public void testOpenStringString() + { + try + { + _handler.open(TMP_FOLDER + File.separator + getTestName(), + BrokerConfigurationStoreCreator.DEFAULT_INITIAL_STORE_LOCATION); + fail("Exception should be thrown on attempt to call open method on a handler"); + } + catch (IllegalStateException e) + { + // pass + } + } + + public void testOpenStringConfigurationEntryStore() + { + try + { + _handler.open(TMP_FOLDER + File.separator + getTestName(), _store); + fail("Exception should be thrown on attempt to call open method on a handler"); + } + catch (IllegalStateException e) + { + // pass + } + } + + public void testGetRootEntryWithEmptyOptions() + { + ConfigurationEntry root = _handler.getRootEntry(); + assertEquals("Unexpected root id", _rootId, root.getId()); + assertEquals("Unexpected children", Collections.singleton(_portEntryId), root.getChildrenIds()); + } + + public void testGetRootEntryWithHttpPortOverriden() + { + _options.setManagementModeHttpPort(9090); + _handler = new ManagementModeStoreHandler(_store, _options); + ConfigurationEntry root = _handler.getRootEntry(); + assertEquals("Unexpected root id", _rootId, root.getId()); + Collection<UUID> childrenIds = root.getChildrenIds(); + assertEquals("Unexpected children size", 2, childrenIds.size()); + assertTrue("Store port entry id is not found", childrenIds.contains(_portEntryId)); + } + + public void testGetRootEntryWithRmiPortOverriden() + { + _options.setManagementModeRmiPort(9090); + _handler = new ManagementModeStoreHandler(_store, _options); + ConfigurationEntry root = _handler.getRootEntry(); + assertEquals("Unexpected root id", _rootId, root.getId()); + Collection<UUID> childrenIds = root.getChildrenIds(); + assertEquals("Unexpected children size", 3, childrenIds.size()); + assertTrue("Store port entry id is not found", childrenIds.contains(_portEntryId)); + } + + public void testGetRootEntryWithConnectorPortOverriden() + { + _options.setManagementModeConnectorPort(9090); + _handler = new ManagementModeStoreHandler(_store, _options); + ConfigurationEntry root = _handler.getRootEntry(); + assertEquals("Unexpected root id", _rootId, root.getId()); + Collection<UUID> childrenIds = root.getChildrenIds(); + assertEquals("Unexpected children size", 2, childrenIds.size()); + assertTrue("Store port entry id is not found", childrenIds.contains(_portEntryId)); + } + + public void testGetRootEntryWithManagementPortsOverriden() + { + _options.setManagementModeHttpPort(1000); + _options.setManagementModeRmiPort(2000); + _options.setManagementModeConnectorPort(3000); + _handler = new ManagementModeStoreHandler(_store, _options); + ConfigurationEntry root = _handler.getRootEntry(); + assertEquals("Unexpected root id", _rootId, root.getId()); + Collection<UUID> childrenIds = root.getChildrenIds(); + assertEquals("Unexpected children size", 4, childrenIds.size()); + assertTrue("Store port entry id is not found", childrenIds.contains(_portEntryId)); + } + + public void testGetEntryByRootId() + { + ConfigurationEntry root = _handler.getEntry(_rootId); + assertEquals("Unexpected root id", _rootId, root.getId()); + assertEquals("Unexpected children", Collections.singleton(_portEntryId), root.getChildrenIds()); + } + + public void testGetEntryByPortId() + { + ConfigurationEntry portEntry = _handler.getEntry(_portEntryId); + assertEquals("Unexpected entry id", _portEntryId, portEntry.getId()); + assertTrue("Unexpected children", portEntry.getChildrenIds().isEmpty()); + assertEquals("Unexpected state", State.QUIESCED, portEntry.getAttributes().get(Port.STATE)); + } + + public void testGetEntryByCLIConnectorPortId() + { + _options.setManagementModeConnectorPort(9090); + _handler = new ManagementModeStoreHandler(_store, _options); + + UUID optionsPort = getOptionsPortId(); + ConfigurationEntry portEntry = _handler.getEntry(optionsPort); + assertCLIPortEntry(portEntry, optionsPort, Protocol.JMX_RMI); + } + + public void testGetEntryByCLIHttpPortId() + { + _options.setManagementModeHttpPort(9090); + _handler = new ManagementModeStoreHandler(_store, _options); + + UUID optionsPort = getOptionsPortId(); + ConfigurationEntry portEntry = _handler.getEntry(optionsPort); + assertCLIPortEntry(portEntry, optionsPort, Protocol.HTTP); + } + + public void testHttpPortEntryIsQuiesced() + { + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(Port.PROTOCOLS, Collections.singleton(Protocol.HTTP)); + when(_portEntry.getAttributes()).thenReturn(attributes); + _options.setManagementModeHttpPort(9090); + _handler = new ManagementModeStoreHandler(_store, _options); + + ConfigurationEntry portEntry = _handler.getEntry(_portEntryId); + assertEquals("Unexpected state", State.QUIESCED, portEntry.getAttributes().get(Port.STATE)); + } + + public void testRmiPortEntryIsQuiesced() + { + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(Port.PROTOCOLS, Collections.singleton(Protocol.RMI)); + when(_portEntry.getAttributes()).thenReturn(attributes); + _options.setManagementModeRmiPort(9090); + _handler = new ManagementModeStoreHandler(_store, _options); + + ConfigurationEntry portEntry = _handler.getEntry(_portEntryId); + assertEquals("Unexpected state", State.QUIESCED, portEntry.getAttributes().get(Port.STATE)); + } + + public void testConnectorPortEntryIsQuiesced() + { + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(Port.PROTOCOLS, Collections.singleton(Protocol.JMX_RMI)); + when(_portEntry.getAttributes()).thenReturn(attributes); + _options.setManagementModeRmiPort(9090); + _handler = new ManagementModeStoreHandler(_store, _options); + + ConfigurationEntry portEntry = _handler.getEntry(_portEntryId); + assertEquals("Unexpected state", State.QUIESCED, portEntry.getAttributes().get(Port.STATE)); + } + + public void testVirtualHostEntryIsQuiesced() + { + UUID virtualHostId = UUID.randomUUID(); + ConfigurationEntry virtualHost = mock(ConfigurationEntry.class); + when(virtualHost.getId()).thenReturn(virtualHostId); + when(virtualHost.getType()).thenReturn(VirtualHost.class.getSimpleName()); + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(VirtualHost.CONFIG_PATH, "/path/to/host.xml"); + when(virtualHost.getAttributes()).thenReturn(attributes); + when(_store.getEntry(virtualHostId)).thenReturn(virtualHost); + when(_root.getChildrenIds()).thenReturn(new HashSet<UUID>(Arrays.asList(_portEntryId, virtualHostId))); + + _handler = new ManagementModeStoreHandler(_store, _options); + + ConfigurationEntry hostEntry = _handler.getEntry(virtualHostId); + Map<String, Object> hostAttributes = hostEntry.getAttributes(); + assertEquals("Unexpected state", State.QUIESCED, hostAttributes.get(VirtualHost.STATE)); + hostAttributes.remove(VirtualHost.STATE); + assertEquals("Unexpected attributes", attributes, hostAttributes); + } + + @SuppressWarnings("unchecked") + private void assertCLIPortEntry(ConfigurationEntry portEntry, UUID optionsPort, Protocol protocol) + { + assertEquals("Unexpected entry id", optionsPort, portEntry.getId()); + assertTrue("Unexpected children", portEntry.getChildrenIds().isEmpty()); + Map<String, Object> attributes = portEntry.getAttributes(); + assertEquals("Unexpected name", "MANAGEMENT-MODE-PORT-" + protocol.name(), attributes.get(Port.NAME)); + assertEquals("Unexpected protocol", Collections.singleton(protocol), new HashSet<Protocol>( + (Collection<Protocol>) attributes.get(Port.PROTOCOLS))); + } + + public void testSavePort() + { + _options.setManagementModeHttpPort(1000); + _options.setManagementModeRmiPort(2000); + _options.setManagementModeConnectorPort(3000); + _handler = new ManagementModeStoreHandler(_store, _options); + + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(Port.NAME, "TEST"); + ConfigurationEntry configurationEntry = new ConfigurationEntry(_portEntryId, Port.class.getSimpleName(), attributes, + Collections.<UUID> emptySet(), null); + _handler.save(configurationEntry); + verify(_store).save(any(ConfigurationEntry.class)); + } + + public void testSaveRoot() + { + _options.setManagementModeHttpPort(1000); + _options.setManagementModeRmiPort(2000); + _options.setManagementModeConnectorPort(3000); + _handler = new ManagementModeStoreHandler(_store, _options); + + ConfigurationEntry root = _handler.getRootEntry(); + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(Broker.NAME, "TEST"); + ConfigurationEntry configurationEntry = new ConfigurationEntry(_rootId, Broker.class.getSimpleName(), attributes, + root.getChildrenIds(), null); + _handler.save(configurationEntry); + verify(_store).save(any(ConfigurationEntry.class)); + } + + public void testSaveCLIHttpPort() + { + _options.setManagementModeHttpPort(1000); + _handler = new ManagementModeStoreHandler(_store, _options); + + UUID portId = getOptionsPortId(); + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(Port.NAME, "TEST"); + ConfigurationEntry configurationEntry = new ConfigurationEntry(portId, Port.class.getSimpleName(), attributes, + Collections.<UUID> emptySet(), null); + try + { + _handler.save(configurationEntry); + fail("Exception should be thrown on trying to save CLI port"); + } + catch (IllegalConfigurationException e) + { + // pass + } + } + + public void testRemove() + { + _options.setManagementModeHttpPort(1000); + _handler = new ManagementModeStoreHandler(_store, _options); + + _handler.remove(_portEntryId); + verify(_store).remove(_portEntryId); + } + + public void testRemoveCLIPort() + { + _options.setManagementModeHttpPort(1000); + _handler = new ManagementModeStoreHandler(_store, _options); + UUID portId = getOptionsPortId(); + try + { + _handler.remove(portId); + fail("Exception should be thrown on trying to remove CLI port"); + } + catch (IllegalConfigurationException e) + { + // pass + } + } + + private UUID getOptionsPortId() + { + ConfigurationEntry root = _handler.getRootEntry(); + assertEquals("Unexpected root id", _rootId, root.getId()); + Collection<UUID> childrenIds = root.getChildrenIds(); + + childrenIds.remove(_portEntryId); + UUID optionsPort = childrenIds.iterator().next(); + return optionsPort; + } + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java new file mode 100644 index 0000000000..a77a0e9fcc --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java @@ -0,0 +1,83 @@ +package org.apache.qpid.server.configuration.store; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.when; + +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Queue; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.test.utils.QpidTestCase; + +public class StoreConfigurationChangeListenerTest extends QpidTestCase +{ + private ConfigurationEntryStore _store; + private StoreConfigurationChangeListener _listener; + + protected void setUp() throws Exception + { + super.setUp(); + _store = mock(ConfigurationEntryStore.class); + _listener = new StoreConfigurationChangeListener(_store); + } + + public void testStateChanged() + { + notifyBrokerStarted(); + UUID id = UUID.randomUUID(); + ConfiguredObject object = mock(VirtualHost.class); + when(object.getId()).thenReturn(id); + _listener.stateChanged(object, State.ACTIVE, State.DELETED); + verify(_store).remove(id); + } + + public void testChildAdded() + { + notifyBrokerStarted(); + Broker broker = mock(Broker.class); + VirtualHost child = mock(VirtualHost.class); + _listener.childAdded(broker, child); + verify(_store).save(any(ConfigurationEntry.class), any(ConfigurationEntry.class)); + } + + public void testChildRemoved() + { + notifyBrokerStarted(); + Broker broker = mock(Broker.class); + VirtualHost child = mock(VirtualHost.class); + _listener.childRemoved(broker, child); + verify(_store).save(any(ConfigurationEntry.class)); + } + + public void testAttributeSet() + { + notifyBrokerStarted(); + Broker broker = mock(Broker.class); + _listener.attributeSet(broker, Broker.FLOW_CONTROL_SIZE_BYTES, null, 1); + verify(_store).save(any(ConfigurationEntry.class)); + } + + public void testChildAddedForVirtualHost() + { + notifyBrokerStarted(); + + VirtualHost object = mock(VirtualHost.class); + Queue queue = mock(Queue.class); + _listener.childAdded(object, queue); + verifyNoMoreInteractions(_store); + } + + private void notifyBrokerStarted() + { + Broker broker = mock(Broker.class); + _listener.stateChanged(broker, State.INITIALISING, State.ACTIVE); + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/updater/TaskExecutorTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/updater/TaskExecutorTest.java new file mode 100644 index 0000000000..cd6302d55b --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/updater/TaskExecutorTest.java @@ -0,0 +1,296 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.updater; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CancellationException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import javax.security.auth.Subject; + +import junit.framework.TestCase; + +import org.apache.qpid.server.logging.LogActor; +import org.apache.qpid.server.logging.NullRootMessageLogger; +import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.logging.actors.TestLogActor; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.security.SecurityManager; + +public class TaskExecutorTest extends TestCase +{ + private TaskExecutor _executor; + + protected void setUp() throws Exception + { + super.setUp(); + _executor = new TaskExecutor(); + } + + protected void tearDown() throws Exception + { + try + { + _executor.stopImmediately(); + } + finally + { + super.tearDown(); + } + } + + public void testGetState() + { + assertEquals("Unxpected initial state", State.INITIALISING, _executor.getState()); + } + + public void testStart() + { + _executor.start(); + assertEquals("Unxpected started state", State.ACTIVE, _executor.getState()); + } + + public void testStopImmediately() throws Exception + { + _executor.start(); + final CountDownLatch submitLatch = new CountDownLatch(2); + final CountDownLatch waitForCallLatch = new CountDownLatch(1); + final BlockingQueue<Exception> submitExceptions = new LinkedBlockingQueue<Exception>(); + + Runnable runnable = new Runnable() + { + @Override + public void run() + { + try + { + Future<?> f = _executor.submit(new NeverEndingCallable(waitForCallLatch)); + submitLatch.countDown(); + f.get(); + } + catch (Exception e) + { + if (e instanceof ExecutionException) + { + e = (Exception) e.getCause(); + } + submitExceptions.add(e); + } + } + }; + new Thread(runnable).start(); + new Thread(runnable).start(); + assertTrue("Tasks have not been submitted", submitLatch.await(1000, TimeUnit.MILLISECONDS)); + assertTrue("The first task has not been triggered", waitForCallLatch.await(1000, TimeUnit.MILLISECONDS)); + + _executor.stopImmediately(); + assertEquals("Unxpected stopped state", State.STOPPED, _executor.getState()); + + Exception e = submitExceptions.poll(1000l, TimeUnit.MILLISECONDS); + assertNotNull("The task execution was not interrupted or cancelled", e); + Exception e2 = submitExceptions.poll(1000l, TimeUnit.MILLISECONDS); + assertNotNull("The task execution was not interrupted or cancelled", e2); + + assertTrue("One of the exceptions should be CancellationException:", e2 instanceof CancellationException + || e instanceof CancellationException); + assertTrue("One of the exceptions should be InterruptedException:", e2 instanceof InterruptedException + || e instanceof InterruptedException); + } + + public void testStop() + { + _executor.start(); + _executor.stop(); + assertEquals("Unxpected stopped state", State.STOPPED, _executor.getState()); + } + + public void testSubmitAndWait() throws Exception + { + _executor.start(); + Object result = _executor.submitAndWait(new Callable<String>() + { + @Override + public String call() throws Exception + { + return "DONE"; + } + }); + assertEquals("Unexpected task execution result", "DONE", result); + } + + public void testSubmitAndWaitInNotAuthorizedContext() + { + _executor.start(); + Object subject = _executor.submitAndWait(new SubjectRetriever()); + assertNull("Subject must be null", subject); + } + + public void testSubmitAndWaitInAuthorizedContext() + { + _executor.start(); + Subject subject = new Subject(); + Object result = Subject.doAs(subject, new PrivilegedAction<Object>() + { + @Override + public Object run() + { + return _executor.submitAndWait(new SubjectRetriever()); + } + }); + assertEquals("Unexpected subject", subject, result); + } + + public void testSubmitAndWaitInAuthorizedContextWithNullSubject() + { + _executor.start(); + Object result = Subject.doAs(null, new PrivilegedAction<Object>() + { + @Override + public Object run() + { + return _executor.submitAndWait(new SubjectRetriever()); + } + }); + assertEquals("Unexpected subject", null, result); + } + + public void testSubmitAndWaitReThrowsOriginalRuntimeException() + { + final RuntimeException exception = new RuntimeException(); + _executor.start(); + try + { + _executor.submitAndWait(new Callable<Void>() + { + + @Override + public Void call() throws Exception + { + throw exception; + } + }); + fail("Exception is expected"); + } + catch (Exception e) + { + assertEquals("Unexpected exception", exception, e); + } + } + + public void testSubmitAndWaitPassesOriginalCheckedException() + { + final Exception exception = new Exception(); + _executor.start(); + try + { + _executor.submitAndWait(new Callable<Void>() + { + + @Override + public Void call() throws Exception + { + throw exception; + } + }); + fail("Exception is expected"); + } + catch (Exception e) + { + assertEquals("Unexpected exception", exception, e.getCause()); + } + } + + public void testSubmitAndWaitCurrentActorAndSecurityManagerSubjectAreRespected() throws Exception + { + _executor.start(); + LogActor actor = new TestLogActor(new NullRootMessageLogger()); + Subject subject = new Subject(); + Subject currentSecurityManagerSubject = SecurityManager.getThreadSubject(); + final AtomicReference<LogActor> taskLogActor = new AtomicReference<LogActor>(); + final AtomicReference<Subject> taskSubject = new AtomicReference<Subject>(); + try + { + CurrentActor.set(actor); + SecurityManager.setThreadSubject(subject); + _executor.submitAndWait(new Callable<Void>() + { + @Override + public Void call() throws Exception + { + taskLogActor.set(CurrentActor.get()); + taskSubject.set(SecurityManager.getThreadSubject()); + return null; + } + }); + } + finally + { + SecurityManager.setThreadSubject(currentSecurityManagerSubject); + CurrentActor.remove(); + } + assertEquals("Unexpected task log actor", actor, taskLogActor.get()); + assertEquals("Unexpected security manager subject", subject, taskSubject.get()); + } + + private class SubjectRetriever implements Callable<Subject> + { + @Override + public Subject call() throws Exception + { + return Subject.getSubject(AccessController.getContext()); + } + } + + private class NeverEndingCallable implements Callable<Void> + { + private CountDownLatch _waitLatch; + + public NeverEndingCallable(CountDownLatch waitLatch) + { + super(); + _waitLatch = waitLatch; + } + + @Override + public Void call() throws Exception + { + if (_waitLatch != null) + { + _waitLatch.countDown(); + } + + // wait forever + synchronized (this) + { + this.wait(); + } + return null; + } + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java index 4befd26ece..0bb698a46c 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java +++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java @@ -29,7 +29,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.UUID; import java.util.concurrent.atomic.AtomicLong; import org.apache.log4j.Logger; @@ -54,25 +53,56 @@ import org.apache.qpid.server.queue.IncomingMessage; import org.apache.qpid.server.queue.MockStoredMessage; import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.queue.SimpleAMQQueue; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.store.StoredMessage; import org.apache.qpid.server.subscription.Subscription; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.server.util.BrokerTestHelper; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.test.utils.QpidTestCase; -public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase +public class AbstractHeadersExchangeTestBase extends QpidTestCase { private static final Logger _log = Logger.getLogger(AbstractHeadersExchangeTestBase.class); private final HeadersExchange exchange = new HeadersExchange(); - protected final Set<TestQueue> queues = new HashSet<TestQueue>(); - + private final Set<TestQueue> queues = new HashSet<TestQueue>(); + private VirtualHost _virtualHost; private int count; + @Override + public void setUp() throws Exception + { + super.setUp(); + BrokerTestHelper.setUp(); + _virtualHost = BrokerTestHelper.createVirtualHost(getClass().getName()); + } + + @Override + public void tearDown() throws Exception + { + try + { + if (_virtualHost != null) + { + _virtualHost.close(); + } + } + finally + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } + } + public void testDoNothing() { // this is here only to make junit under Eclipse happy } + public VirtualHost getVirtualHost() + { + return _virtualHost; + } + protected TestQueue bindDefault(String... bindings) throws AMQException { String queueName = "Queue" + (++count); @@ -83,7 +113,7 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase protected void unbind(TestQueue queue, String... bindings) throws AMQException { String queueName = queue.getName(); - exchange.onUnbind(new Binding(null, null, queueName, queue, exchange, getHeadersMap(bindings))); + exchange.onUnbind(new Binding(null, queueName, queue, exchange, getHeadersMap(bindings))); } protected int getCount() @@ -93,9 +123,9 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase private TestQueue bind(String key, String queueName, Map<String,Object> args) throws AMQException { - TestQueue queue = new TestQueue(new AMQShortString(queueName)); + TestQueue queue = new TestQueue(new AMQShortString(queueName), _virtualHost); queues.add(queue); - exchange.onBind(new Binding(null, null, key, queue, exchange, args)); + exchange.onBind(new Binding(null, key, queue, exchange, args)); return queue; } @@ -274,10 +304,10 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase return getNameShortString().toString(); } - public TestQueue(AMQShortString name) throws AMQException + public TestQueue(AMQShortString name, VirtualHost host) throws AMQException { - super(UUIDGenerator.generateRandomUUID(), name, false, new AMQShortString("test"), true, false,ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"), Collections.EMPTY_MAP); - ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test").getQueueRegistry().registerQueue(this); + super(UUIDGenerator.generateRandomUUID(), name, false, new AMQShortString("test"), true, false, host, Collections.EMPTY_MAP); + host.getQueueRegistry().registerQueue(this); } diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/DefaultExchangeFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/DefaultExchangeFactoryTest.java new file mode 100644 index 0000000000..341ab1b372 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/DefaultExchangeFactoryTest.java @@ -0,0 +1,226 @@ +/* + * + * 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.exchange; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.UUID; + +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.plugin.ExchangeType; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.test.utils.QpidTestCase; + +@SuppressWarnings("rawtypes") +public class DefaultExchangeFactoryTest extends QpidTestCase +{ + private DirectExchangeType _directExchangeType; + private TopicExchangeType _topicExchangeType; + private FanoutExchangeType _fanoutExchangeType; + private HeadersExchangeType _headersExchangeType; + + private List<ExchangeType> _stubbedExchangeTypes; + + protected void setUp() throws Exception + { + super.setUp(); + + _directExchangeType = new DirectExchangeType(); + _topicExchangeType = new TopicExchangeType(); + _fanoutExchangeType = new FanoutExchangeType(); + _headersExchangeType = new HeadersExchangeType(); + _stubbedExchangeTypes = new ArrayList<ExchangeType>(); + } + + public void testCreateDefaultExchangeFactory() + { + _stubbedExchangeTypes.add(_directExchangeType); + _stubbedExchangeTypes.add(_topicExchangeType); + _stubbedExchangeTypes.add(_fanoutExchangeType); + _stubbedExchangeTypes.add(_headersExchangeType); + + DefaultExchangeFactory factory = new TestExchangeFactory(); + + Collection<ExchangeType<? extends Exchange>> registeredTypes = factory.getRegisteredTypes(); + assertEquals("Unexpected number of exchange types", _stubbedExchangeTypes.size(), registeredTypes.size()); + assertTrue("Direct exchange type is not found", registeredTypes.contains(_directExchangeType)); + assertTrue("Fanout exchange type is not found", registeredTypes.contains(_fanoutExchangeType)); + assertTrue("Topic exchange type is not found", registeredTypes.contains(_topicExchangeType)); + assertTrue("Headers exchange type is not found", registeredTypes.contains(_headersExchangeType)); + } + + public void testCreateDefaultExchangeFactoryWithoutAllBaseExchangeTypes() + { + try + { + new TestExchangeFactory(); + fail("Cannot create factory without all base classes"); + } + catch (IllegalStateException e) + { + // pass + } + } + + public void testCreateDefaultExchangeFactoryWithoutDireactExchangeType() + { + _stubbedExchangeTypes.add(_topicExchangeType); + _stubbedExchangeTypes.add(_fanoutExchangeType); + _stubbedExchangeTypes.add(_headersExchangeType); + + try + { + new TestExchangeFactory(); + fail("Cannot create factory without all base classes"); + } + catch (IllegalStateException e) + { + assertEquals("Unexpected exception message", "Did not find expected exchange type: " + _directExchangeType.getName(), e.getMessage()); + } + } + + public void testCreateDefaultExchangeFactoryWithoutTopicExchangeType() + { + _stubbedExchangeTypes.add(_directExchangeType); + _stubbedExchangeTypes.add(_fanoutExchangeType); + _stubbedExchangeTypes.add(_headersExchangeType); + + try + { + new TestExchangeFactory(); + fail("Cannot create factory without all base classes"); + } + catch (IllegalStateException e) + { + assertEquals("Unexpected exception message", "Did not find expected exchange type: " + _topicExchangeType.getName(), e.getMessage()); + } + } + + public void testCreateDefaultExchangeFactoryWithoutFanoutExchangeType() + { + _stubbedExchangeTypes.add(_directExchangeType); + _stubbedExchangeTypes.add(_topicExchangeType); + _stubbedExchangeTypes.add(_headersExchangeType); + + try + { + new TestExchangeFactory(); + fail("Cannot create factory without all base classes"); + } + catch (IllegalStateException e) + { + assertEquals("Unexpected exception message", "Did not find expected exchange type: " + _fanoutExchangeType.getName(), e.getMessage()); + } + } + + public void testCreateDefaultExchangeFactoryWithoutHeadersExchangeType() + { + _stubbedExchangeTypes.add(_directExchangeType); + _stubbedExchangeTypes.add(_topicExchangeType); + _stubbedExchangeTypes.add(_fanoutExchangeType); + + try + { + new TestExchangeFactory(); + fail("Cannot create factory without all base classes"); + } + catch (IllegalStateException e) + { + assertEquals("Unexpected exception message", "Did not find expected exchange type: " + _headersExchangeType.getName(), e.getMessage()); + } + } + + public void testCreateDefaultExchangeFactoryWithDuplicateExchangeTypeName() + { + _stubbedExchangeTypes.add(_directExchangeType); + _stubbedExchangeTypes.add(_directExchangeType); + + try + { + new TestExchangeFactory(); + fail("Cannot create factory with duplicate exchange type names"); + } + catch (IllegalStateException e) + { + assertTrue( "Unexpected exception message", e.getMessage().contains("ExchangeType with type name '" + + _directExchangeType.getName() + "' is already registered using class '" + + DirectExchangeType.class.getName())); + } + } + + public void testCreateDefaultExchangeFactoryWithCustomExchangeType() + { + ExchangeType<?> customeExchangeType = new ExchangeType<Exchange>() + { + @Override + public AMQShortString getName() + { + return new AMQShortString("my-custom-exchange"); + } + + @Override + public Exchange newInstance(UUID id, VirtualHost host, AMQShortString name, boolean durable, int ticket, + boolean autoDelete) throws AMQException + { + return null; + } + + @Override + public AMQShortString getDefaultExchangeName() + { + return null; + } + }; + + _stubbedExchangeTypes.add(customeExchangeType); + _stubbedExchangeTypes.add(_directExchangeType); + _stubbedExchangeTypes.add(_topicExchangeType); + _stubbedExchangeTypes.add(_fanoutExchangeType); + _stubbedExchangeTypes.add(_headersExchangeType); + + DefaultExchangeFactory factory = new TestExchangeFactory(); + + Collection<ExchangeType<? extends Exchange>> registeredTypes = factory.getRegisteredTypes(); + assertEquals("Unexpected number of exchange types", _stubbedExchangeTypes.size(), registeredTypes.size()); + assertTrue("Direct exchange type is not found", registeredTypes.contains(_directExchangeType)); + assertTrue("Fanout exchange type is not found", registeredTypes.contains(_fanoutExchangeType)); + assertTrue("Topic exchange type is not found", registeredTypes.contains(_topicExchangeType)); + assertTrue("Headers exchange type is not found", registeredTypes.contains(_headersExchangeType)); + assertTrue("Custom exchange type is not found", registeredTypes.contains(customeExchangeType)); + } + + private final class TestExchangeFactory extends DefaultExchangeFactory + { + private TestExchangeFactory() + { + super(null); + } + + @Override + protected Iterable<ExchangeType> loadExchangeTypes() + { + return _stubbedExchangeTypes; + } + } + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java index 3988edcb3c..833df34fd8 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java @@ -160,7 +160,7 @@ public class HeadersBindingTest extends TestCase matchHeaders.setString("A", "Value of A"); - Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders); + Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders); assertTrue(new HeadersBinding(b).matches(matchHeaders)); } @@ -171,7 +171,7 @@ public class HeadersBindingTest extends TestCase matchHeaders.setString("A", "Value of A"); matchHeaders.setString("B", "Value of B"); - Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders); + Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders); assertTrue(new HeadersBinding(b).matches(matchHeaders)); } @@ -181,7 +181,7 @@ public class HeadersBindingTest extends TestCase matchHeaders.setString("A", "Altered value of A"); - Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders); + Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders); assertFalse(new HeadersBinding(b).matches(matchHeaders)); } @@ -192,7 +192,7 @@ public class HeadersBindingTest extends TestCase matchHeaders.setString("A", "Value of A"); - Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders); + Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders); assertTrue(new HeadersBinding(b).matches(matchHeaders)); } @@ -204,7 +204,7 @@ public class HeadersBindingTest extends TestCase matchHeaders.setString("A", "Value of A"); - Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders); + Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders); assertFalse(new HeadersBinding(b).matches(matchHeaders)); } @@ -217,7 +217,7 @@ public class HeadersBindingTest extends TestCase matchHeaders.setString("A", "Value of A"); matchHeaders.setString("B", "Value of B"); - Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders); + Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders); assertTrue(new HeadersBinding(b).matches(matchHeaders)); } @@ -231,7 +231,7 @@ public class HeadersBindingTest extends TestCase matchHeaders.setString("B", "Value of B"); matchHeaders.setString("C", "Value of C"); - Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders); + Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders); assertTrue(new HeadersBinding(b).matches(matchHeaders)); } @@ -245,7 +245,7 @@ public class HeadersBindingTest extends TestCase matchHeaders.setString("B", "Altered value of B"); matchHeaders.setString("C", "Value of C"); - Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders); + Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders); assertFalse(new HeadersBinding(b).matches(matchHeaders)); } @@ -256,7 +256,7 @@ public class HeadersBindingTest extends TestCase matchHeaders.setString("A", "Value of A"); - Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders); + Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders); assertTrue(new HeadersBinding(b).matches(matchHeaders)); } @@ -268,7 +268,7 @@ public class HeadersBindingTest extends TestCase matchHeaders.setString("A", "Value of A"); - Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders); + Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders); assertTrue(new HeadersBinding(b).matches(matchHeaders)); } @@ -281,7 +281,7 @@ public class HeadersBindingTest extends TestCase matchHeaders.setString("A", "Value of A"); matchHeaders.setString("B", "Value of B"); - Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders); + Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders); assertTrue(new HeadersBinding(b).matches(matchHeaders)); } @@ -295,7 +295,7 @@ public class HeadersBindingTest extends TestCase matchHeaders.setString("B", "Value of B"); matchHeaders.setString("C", "Value of C"); - Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders); + Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders); assertTrue(new HeadersBinding(b).matches(matchHeaders)); } @@ -309,7 +309,7 @@ public class HeadersBindingTest extends TestCase matchHeaders.setString("B", "Altered value of B"); matchHeaders.setString("C", "Value of C"); - Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders); + Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders); assertTrue(new HeadersBinding(b).matches(matchHeaders)); } @@ -323,7 +323,7 @@ public class HeadersBindingTest extends TestCase matchHeaders.setString("B", "Altered value of B"); matchHeaders.setString("C", "Value of C"); - Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders); + Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders); assertFalse(new HeadersBinding(b).matches(matchHeaders)); } diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersExchangeTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersExchangeTest.java index 326d36df05..bd6a02d69b 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersExchangeTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersExchangeTest.java @@ -23,8 +23,7 @@ package org.apache.qpid.server.exchange; import org.apache.qpid.AMQException; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.protocol.InternalTestProtocolSession; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.util.BrokerTestHelper; public class HeadersExchangeTest extends AbstractHeadersExchangeTestBase { @@ -34,10 +33,15 @@ public class HeadersExchangeTest extends AbstractHeadersExchangeTestBase public void setUp() throws Exception { super.setUp(); - // Just use the first vhost. - VirtualHost - virtualHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHosts().iterator().next(); - _protocolSession = new InternalTestProtocolSession(virtualHost); + BrokerTestHelper.setUp(); + _protocolSession = new InternalTestProtocolSession(getVirtualHost(), BrokerTestHelper.createBrokerMock()); + } + + @Override + public void tearDown() throws Exception + { + BrokerTestHelper.tearDown(); + super.tearDown(); } public void testSimple() throws AMQException diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java index 92274afece..f1bf632235 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java @@ -31,42 +31,55 @@ import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.message.AMQMessage; import org.apache.qpid.server.message.MessageMetaData; import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.protocol.InternalTestProtocolSession; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.IncomingMessage; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.store.MemoryMessageStore; import org.apache.qpid.server.store.MessageStore; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.test.utils.QpidTestCase; -public class TopicExchangeTest extends InternalBrokerBaseCase +public class TopicExchangeTest extends QpidTestCase { private TopicExchange _exchange; - private VirtualHost _vhost; private MessageStore _store; - private InternalTestProtocolSession _protocolSession; - @Override public void setUp() throws Exception { super.setUp(); + BrokerTestHelper.setUp(); _exchange = new TopicExchange(); - _vhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHosts().iterator().next(); + _vhost = BrokerTestHelper.createVirtualHost(getName()); _store = new MemoryMessageStore(); - _protocolSession = new InternalTestProtocolSession(_vhost); + } + + @Override + public void tearDown() throws Exception + { + try + { + if (_vhost != null) + { + _vhost.close(); + } + } + finally + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } } public void testNoRoute() throws AMQException { AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a*#b", false, null, false, false, _vhost, null); - _exchange.registerQueue(new Binding(null, null, "a.*.#.b",queue, _exchange, null)); + _exchange.registerQueue(new Binding(null, "a.*.#.b",queue, _exchange, null)); IncomingMessage message = createMessage("a.b"); @@ -78,7 +91,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase public void testDirectMatch() throws AMQException { AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "ab", false, null, false, false, _vhost, null); - _exchange.registerQueue(new Binding(null, null, "a.b",queue, _exchange, null)); + _exchange.registerQueue(new Binding(null, "a.b",queue, _exchange, null)); IncomingMessage message = createMessage("a.b"); @@ -105,7 +118,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase public void testStarMatch() throws AMQException { AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a*", false, null, false, false, _vhost, null); - _exchange.registerQueue(new Binding(null, null, "a.*",queue, _exchange, null)); + _exchange.registerQueue(new Binding(null, "a.*",queue, _exchange, null)); IncomingMessage message = createMessage("a.b"); @@ -144,7 +157,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase public void testHashMatch() throws AMQException { AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a#", false, null, false, false, _vhost, null); - _exchange.registerQueue(new Binding(null, null, "a.#",queue, _exchange, null)); + _exchange.registerQueue(new Binding(null, "a.#",queue, _exchange, null)); IncomingMessage message = createMessage("a.b.c"); @@ -207,7 +220,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase public void testMidHash() throws AMQException { AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a", false, null, false, false, _vhost, null); - _exchange.registerQueue(new Binding(null, null, "a.*.#.b",queue, _exchange, null)); + _exchange.registerQueue(new Binding(null, "a.*.#.b",queue, _exchange, null)); IncomingMessage message = createMessage("a.c.d.b"); @@ -237,7 +250,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase public void testMatchafterHash() throws AMQException { AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a#", false, null, false, false, _vhost, null); - _exchange.registerQueue(new Binding(null, null, "a.*.#.b.c",queue, _exchange, null)); + _exchange.registerQueue(new Binding(null, "a.*.#.b.c",queue, _exchange, null)); IncomingMessage message = createMessage("a.c.b.b"); @@ -283,7 +296,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase public void testHashAfterHash() throws AMQException { AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a#", false, null, false, false, _vhost, null); - _exchange.registerQueue(new Binding(null, null, "a.*.#.b.c.#.d",queue, _exchange, null)); + _exchange.registerQueue(new Binding(null, "a.*.#.b.c.#.d",queue, _exchange, null)); IncomingMessage message = createMessage("a.c.b.b.c"); @@ -310,7 +323,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase public void testHashHash() throws AMQException { AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a#", false, null, false, false, _vhost, null); - _exchange.registerQueue(new Binding(null, null, "a.#.*.#.d",queue, _exchange, null)); + _exchange.registerQueue(new Binding(null, "a.#.*.#.d",queue, _exchange, null)); IncomingMessage message = createMessage("a.c.b.b.c"); @@ -336,7 +349,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase public void testSubMatchFails() throws AMQException { AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a", false, null, false, false, _vhost, null); - _exchange.registerQueue(new Binding(null, null, "a.b.c.d",queue, _exchange, null)); + _exchange.registerQueue(new Binding(null, "a.b.c.d",queue, _exchange, null)); IncomingMessage message = createMessage("a.b.c"); @@ -366,7 +379,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase public void testMoreRouting() throws AMQException { AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a", false, null, false, false, _vhost, null); - _exchange.registerQueue(new Binding(null, null, "a.b",queue, _exchange, null)); + _exchange.registerQueue(new Binding(null, "a.b",queue, _exchange, null)); IncomingMessage message = createMessage("a.b.c"); @@ -381,7 +394,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase public void testMoreQueue() throws AMQException { AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a", false, null, false, false, _vhost, null); - _exchange.registerQueue(new Binding(null, null, "a.b",queue, _exchange, null)); + _exchange.registerQueue(new Binding(null, "a.b",queue, _exchange, null)); IncomingMessage message = createMessage("a"); diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java b/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java index fabbe8640e..be31f3d039 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java @@ -20,7 +20,6 @@ */ package org.apache.qpid.server.logging; -import org.apache.qpid.server.configuration.ServerConfiguration; import java.util.LinkedList; import java.util.List; @@ -34,9 +33,9 @@ public class UnitTestMessageLogger extends AbstractRootMessageLogger } - public UnitTestMessageLogger(ServerConfiguration config) + public UnitTestMessageLogger(boolean statusUpdatesEnabled) { - super(config); + super(statusUpdatesEnabled); } public void rawMessage(String message, String logHierarchy) diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPChannelActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPChannelActorTest.java index f739d3fcb9..e2472dbf01 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPChannelActorTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPChannelActorTest.java @@ -20,9 +20,8 @@ */ package org.apache.qpid.server.logging.actors; -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.AMQException; +import org.apache.qpid.server.AMQChannel; +import org.apache.qpid.server.util.BrokerTestHelper; import java.util.List; @@ -38,24 +37,17 @@ import java.util.List; public class AMQPChannelActorTest extends BaseConnectionActorTestCase { - @Override - public void configure() + public void setUp() { - // Prevent defaulting Logging to ON + // do nothing } - - @Override - public void createBroker() throws Exception + private void setUpNow() throws Exception { - //prevent auto-broker startup - } + super.setUp(); + AMQChannel channel = BrokerTestHelper.createChannel(1, getSession()); - private void startBrokerNow() throws Exception - { - super.createBroker(); - - _amqpActor = new AMQPChannelActor(getChannel(), _rootLogger); + setAmqpActor(new AMQPChannelActor(channel, getRootLogger())); } @@ -68,13 +60,11 @@ public class AMQPChannelActorTest extends BaseConnectionActorTestCase */ public void testChannel() throws Exception { - getConfigXml().setProperty("status-updates", "ON"); - - startBrokerNow(); + setUpNow(); - final String message = sendTestLogMessage(_amqpActor); + final String message = sendTestLogMessage(getAmqpActor()); - List<Object> logs = _rawLogger.getLogMessages(); + List<Object> logs = getRawLogger().getLogMessages(); assertEquals("Message log size not as expected.", 1, logs.size()); @@ -95,128 +85,22 @@ public class AMQPChannelActorTest extends BaseConnectionActorTestCase // Verify that the logged message contains the 'ch:1' marker assertTrue("Message was not logged as part of channel 1" + logs.get(0), logs.get(0).toString().contains("/ch:1")); - - } - - /** - * Test that if logging is configured to be off in the configuration that - * no logging is presented - * @throws ConfigurationException - * @throws AMQException - */ - public void testChannelLoggingOFF() throws Exception, AMQException - { - getConfigXml().setProperty("status-updates", "OFF"); - - // Start the broker now. - startBrokerNow(); - - sendTestLogMessage(_amqpActor); - - List<Object> logs = _rawLogger.getLogMessages(); - - assertEquals("Message log size not as expected.", 0, logs.size()); - - } - - /** - * Test that if logging is configured to be off in the configuration that - * no logging is presented - * @throws ConfigurationException - * @throws AMQException - */ - public void testChannelLoggingOfF() throws Exception, AMQException - { - getConfigXml().setProperty("status-updates", "OfF"); - - startBrokerNow(); - - sendTestLogMessage(_amqpActor); - - List<Object> logs = _rawLogger.getLogMessages(); - - assertEquals("Message log size not as expected.", 0, logs.size()); - - } - - /** - * Test that if logging is configured to be off in the configuration that - * no logging is presented - * @throws ConfigurationException - * @throws AMQException - */ - public void testChannelLoggingOff() throws Exception, AMQException - { - getConfigXml().setProperty("status-updates", "Off"); - - startBrokerNow(); - - sendTestLogMessage(_amqpActor); - - List<Object> logs = _rawLogger.getLogMessages(); - - assertEquals("Message log size not as expected.", 0, logs.size()); - } /** - * Test that if logging is configured to be off in the configuration that + * Test that if logging is configured to be off via system property that * no logging is presented - * @throws ConfigurationException - * @throws AMQException */ - public void testChannelLoggingofF() throws Exception, AMQException + public void testChannelLoggingOFF() throws Exception { - getConfigXml().setProperty("status-updates", "ofF"); + setStatusUpdatesEnabled(false); - startBrokerNow(); + setUpNow(); - sendTestLogMessage(_amqpActor); + sendTestLogMessage(getAmqpActor()); - List<Object> logs = _rawLogger.getLogMessages(); + List<Object> logs = getRawLogger().getLogMessages(); assertEquals("Message log size not as expected.", 0, logs.size()); - } - - /** - * Test that if logging is configured to be off in the configuration that - * no logging is presented - * @throws ConfigurationException - * @throws AMQException - */ - public void testChannelLoggingoff() throws Exception, AMQException - { - getConfigXml().setProperty("status-updates", "off"); - - startBrokerNow(); - - sendTestLogMessage(_amqpActor); - - List<Object> logs = _rawLogger.getLogMessages(); - - assertEquals("Message log size not as expected.", 0, logs.size()); - - } - - /** - * Test that if logging is configured to be off in the configuration that - * no logging is presented - * @throws ConfigurationException - * @throws AMQException - */ - public void testChannelLoggingoFf() throws Exception, AMQException - { - getConfigXml().setProperty("status-updates", "oFf"); - - startBrokerNow(); - - sendTestLogMessage(_amqpActor); - - List<Object> logs = _rawLogger.getLogMessages(); - - assertEquals("Message log size not as expected.", 0, logs.size()); - - } - } diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPConnectionActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPConnectionActorTest.java index 4eda9e9da1..d1cf256563 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPConnectionActorTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPConnectionActorTest.java @@ -38,16 +38,9 @@ import java.util.List; public class AMQPConnectionActorTest extends BaseConnectionActorTestCase { @Override - public void configure() + public void setUp() { - // Prevent defaulting Logging to ON - } - - - @Override - public void createBroker() - { - //Prevent auto-broker startup + //Prevent logger creation } /** @@ -60,13 +53,11 @@ public class AMQPConnectionActorTest extends BaseConnectionActorTestCase */ public void testConnection() throws Exception { - getConfigXml().setProperty("status-updates", "ON"); - - super.createBroker(); + super.setUp(); final String message = sendLogMessage(); - List<Object> logs = _rawLogger.getLogMessages(); + List<Object> logs = getRawLogger().getLogMessages(); assertEquals("Message log size not as expected.", 1, logs.size()); @@ -90,14 +81,13 @@ public class AMQPConnectionActorTest extends BaseConnectionActorTestCase public void testConnectionLoggingOff() throws Exception, AMQException { - getConfigXml().setProperty("status-updates", "OFF"); + setStatusUpdatesEnabled(false); - // Start the broker now. - super.createBroker(); + super.setUp(); sendLogMessage(); - List<Object> logs = _rawLogger.getLogMessages(); + List<Object> logs = getRawLogger().getLogMessages(); assertEquals("Message log size not as expected.", 0, logs.size()); @@ -107,7 +97,7 @@ public class AMQPConnectionActorTest extends BaseConnectionActorTestCase { final String message = "test logging"; - _amqpActor.message(new LogSubject() + getAmqpActor().message(new LogSubject() { public String toLogString() { diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AbstractManagementActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AbstractManagementActorTest.java new file mode 100644 index 0000000000..bf38bb64bf --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AbstractManagementActorTest.java @@ -0,0 +1,86 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.logging.actors; + +import java.security.Principal; +import java.security.PrivilegedAction; +import java.util.Collections; + +import javax.security.auth.Subject; + +import org.apache.qpid.server.logging.NullRootMessageLogger; +import org.apache.qpid.server.security.auth.TestPrincipalUtils; +import org.apache.qpid.test.utils.QpidTestCase; + +public class AbstractManagementActorTest extends QpidTestCase +{ + private AbstractManagementActor _logActor; + + @Override + public void setUp() + { + _logActor = new AbstractManagementActor(new NullRootMessageLogger(), AbstractManagementActor.UNKNOWN_PRINCIPAL) + { + @Override + public String getLogMessage() + { + return null; + } + }; + } + + public void testGetPrincipalName() + { + Subject subject = TestPrincipalUtils.createTestSubject("guest"); + + final String principalName = Subject.doAs(subject, + new PrivilegedAction<String>() + { + public String run() + { + return _logActor.getPrincipalName(); + } + }); + + assertEquals("guest", principalName); + } + + public void testGetPrincipalNameUsingSubjectWithoutAuthenticatedPrincipal() + { + Subject subject = new Subject(true, Collections.<Principal>emptySet(), Collections.emptySet(), Collections.emptySet()); + + final String principalName = Subject.doAs(subject, + new PrivilegedAction<String>() + { + public String run() + { + return _logActor.getPrincipalName(); + } + }); + + assertEquals(AbstractManagementActor.UNKNOWN_PRINCIPAL, principalName); + } + + public void testGetPrincipalWithoutSubject() + { + assertEquals(AbstractManagementActor.UNKNOWN_PRINCIPAL, _logActor.getPrincipalName()); + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseActorTestCase.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseActorTestCase.java index ec2cdd5585..30c3a51604 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseActorTestCase.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseActorTestCase.java @@ -20,39 +20,39 @@ */ package org.apache.qpid.server.logging.actors; -import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.LogMessage; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.RootMessageLogger; import org.apache.qpid.server.logging.UnitTestMessageLogger; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.test.utils.QpidTestCase; -public class BaseActorTestCase extends InternalBrokerBaseCase +public class BaseActorTestCase extends QpidTestCase { - protected LogActor _amqpActor; - protected UnitTestMessageLogger _rawLogger; - protected RootMessageLogger _rootLogger; + private boolean _statusUpdatesEnabled = true; + private LogActor _amqpActor; + private UnitTestMessageLogger _rawLogger; + private RootMessageLogger _rootLogger; @Override - public void configure() + public void setUp() throws Exception { - getConfiguration().getConfig().setProperty(ServerConfiguration.STATUS_UPDATES, "on"); - } - - @Override - public void createBroker() throws Exception - { - super.createBroker(); - - _rawLogger = new UnitTestMessageLogger(getConfiguration()); + super.setUp(); + CurrentActor.removeAll(); + CurrentActor.setDefault(null); + _rawLogger = new UnitTestMessageLogger(_statusUpdatesEnabled); _rootLogger = _rawLogger; } + @Override public void tearDown() throws Exception { - _rawLogger.clearLogMessages(); - + if(_rawLogger != null) + { + _rawLogger.clearLogMessages(); + } + CurrentActor.removeAll(); + CurrentActor.setDefault(null); super.tearDown(); } @@ -87,4 +87,34 @@ public class BaseActorTestCase extends InternalBrokerBaseCase }); } + public boolean isStatusUpdatesEnabled() + { + return _statusUpdatesEnabled; + } + + public void setStatusUpdatesEnabled(boolean statusUpdatesEnabled) + { + _statusUpdatesEnabled = statusUpdatesEnabled; + } + + public LogActor getAmqpActor() + { + return _amqpActor; + } + + public void setAmqpActor(LogActor amqpActor) + { + _amqpActor = amqpActor; + } + + public UnitTestMessageLogger getRawLogger() + { + return _rawLogger; + } + + public RootMessageLogger getRootLogger() + { + return _rootLogger; + } + } diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseConnectionActorTestCase.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseConnectionActorTestCase.java index 956d296dce..09dd48e4d3 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseConnectionActorTestCase.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseConnectionActorTestCase.java @@ -20,14 +20,43 @@ */ package org.apache.qpid.server.logging.actors; +import org.apache.qpid.server.protocol.AMQProtocolSession; +import org.apache.qpid.server.util.BrokerTestHelper; + public class BaseConnectionActorTestCase extends BaseActorTestCase { + private AMQProtocolSession _session; @Override - public void createBroker() throws Exception + public void setUp() throws Exception { - super.createBroker(); + super.setUp(); + BrokerTestHelper.setUp(); + _session = BrokerTestHelper.createSession(); + + setAmqpActor(new AMQPConnectionActor(_session, getRootLogger())); + } - _amqpActor = new AMQPConnectionActor(getSession(), _rootLogger); + @Override + public void tearDown() throws Exception + { + try + { + if (_session != null) + { + _session.getVirtualHost().close(); + } + } + finally + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } } + + public AMQProtocolSession getSession() + { + return _session; + } + } diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/CurrentActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/CurrentActorTest.java index f73765f5aa..8ea5510ce6 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/CurrentActorTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/CurrentActorTest.java @@ -70,12 +70,7 @@ public class CurrentActorTest extends BaseConnectionActorTestCase */ public void testLIFO() throws AMQException, ConfigurationException { - // This test only needs the local objects created, _session etc. - // So stopping the broker and making them useless will not affect the - // test, but the extra actors the test broker adds will so by stopping - // we remove the session actor and so all is good. - stopBroker(); - + assertTrue("Unexpected actor: " + CurrentActor.get(), CurrentActor.get() instanceof TestLogActor); AMQPConnectionActor connectionActor = new AMQPConnectionActor(getSession(), new NullRootMessageLogger()); diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/HttpManagementActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/HttpManagementActorTest.java new file mode 100644 index 0000000000..905de4b639 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/HttpManagementActorTest.java @@ -0,0 +1,94 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.logging.actors; + +import javax.security.auth.Subject; + +import org.apache.qpid.server.security.auth.TestPrincipalUtils; + +import java.security.PrivilegedAction; +import java.util.List; + +public class HttpManagementActorTest extends BaseActorTestCase +{ + private static final String IP = "127.0.0.1"; + private static final int PORT = 1; + private static final String SUFFIX = "(" + IP + ":" + PORT + ")] "; + + @Override + public void setUp() throws Exception + { + super.setUp(); + setAmqpActor(new HttpManagementActor(getRootLogger(), IP, PORT)); + } + + public void testSubjectPrincipalNameAppearance() + { + Subject subject = TestPrincipalUtils.createTestSubject("guest"); + + final String message = Subject.doAs(subject, new PrivilegedAction<String>() + { + public String run() + { + return sendTestLogMessage(getAmqpActor()); + } + }); + + assertNotNull("Test log message is not created!", message); + + List<Object> logs = getRawLogger().getLogMessages(); + assertEquals("Message log size not as expected.", 1, logs.size()); + + String logMessage = logs.get(0).toString(); + assertTrue("Message was not found in log message", logMessage.contains(message)); + assertTrue("Message does not contain expected value: " + logMessage, logMessage.contains("[mng:guest" + SUFFIX)); + } + + /** It's necessary to test successive calls because HttpManagementActor caches + * its log message based on principal name */ + public void testGetLogMessageCaching() + { + assertLogMessageWithoutPrincipal(); + assertLogMessageWithPrincipal("my_principal"); + assertLogMessageWithPrincipal("my_principal2"); + assertLogMessageWithoutPrincipal(); + } + + private void assertLogMessageWithoutPrincipal() + { + String message = getAmqpActor().getLogMessage(); + assertEquals("Unexpected log message", "[mng:" + AbstractManagementActor.UNKNOWN_PRINCIPAL + SUFFIX, message); + } + + private void assertLogMessageWithPrincipal(String principalName) + { + Subject subject = TestPrincipalUtils.createTestSubject(principalName); + final String message = Subject.doAs(subject, new PrivilegedAction<String>() + { + public String run() + { + return getAmqpActor().getLogMessage(); + } + }); + + assertEquals("Unexpected log message", "[mng:" + principalName + SUFFIX, message); + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java index cb866245f0..a0bfa592db 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java @@ -20,10 +20,11 @@ */ package org.apache.qpid.server.logging.actors; -import javax.management.remote.JMXPrincipal; import javax.security.auth.Subject; + +import org.apache.qpid.server.security.auth.TestPrincipalUtils; + import java.security.PrivilegedAction; -import java.util.Collections; import java.util.List; public class ManagementActorTest extends BaseActorTestCase @@ -34,10 +35,10 @@ public class ManagementActorTest extends BaseActorTestCase private String _threadName; @Override - public void createBroker() throws Exception + public void setUp() throws Exception { - super.createBroker(); - _amqpActor = new ManagementActor(_rootLogger); + super.setUp(); + setAmqpActor(new ManagementActor(getRootLogger())); // Set the thread name to be the same as a RMI JMX Connection would use _threadName = Thread.currentThread().getName(); @@ -56,14 +57,14 @@ public class ManagementActorTest extends BaseActorTestCase * * The test sends a message then verifies that it entered the logs. * - * The log message should be fully repalaced (no '{n}' values) and should + * The log message should be fully replaced (no '{n}' values) and should * not contain any channel identification. */ public void testConnection() { - final String message = sendTestLogMessage(_amqpActor); + final String message = sendTestLogMessage(getAmqpActor()); - List<Object> logs = _rawLogger.getLogMessages(); + List<Object> logs = getRawLogger().getLogMessages(); assertEquals("Message log size not as expected.", 1, logs.size()); @@ -94,21 +95,20 @@ public class ManagementActorTest extends BaseActorTestCase */ public void testSubjectPrincipalNameAppearance() { - Subject subject = new Subject(true, Collections.singleton(new JMXPrincipal("guest")), Collections.EMPTY_SET, - Collections.EMPTY_SET); + Subject subject = TestPrincipalUtils.createTestSubject("guest"); final String message = Subject.doAs(subject, new PrivilegedAction<String>() { public String run() { - return sendTestLogMessage(_amqpActor); + return sendTestLogMessage(getAmqpActor()); } }); // Verify that the log message was created assertNotNull("Test log message is not created!", message); - List<Object> logs = _rawLogger.getLogMessages(); + List<Object> logs = getRawLogger().getLogMessages(); // Verify that at least one log message was added to log assertEquals("Message log size not as expected.", 1, logs.size()); @@ -130,8 +130,8 @@ public class ManagementActorTest extends BaseActorTestCase public void testGetLogMessageWithoutSubjectButWithActorPrincipal() { String principalName = "my_principal"; - _amqpActor = new ManagementActor(_rootLogger, principalName); - String message = _amqpActor.getLogMessage(); + setAmqpActor(new ManagementActor(getRootLogger(), principalName)); + String message = getAmqpActor().getLogMessage(); assertEquals("Unexpected log message", "[mng:" + principalName + "(" + IP + ")] ", message); } @@ -149,7 +149,7 @@ public class ManagementActorTest extends BaseActorTestCase assertLogMessageInRMIThreadWithPrincipal("RMI TCP Connection(1)-" + IP, "my_principal"); Thread.currentThread().setName("RMI TCP Connection(2)-" + IP ); - String message = _amqpActor.getLogMessage(); + String message = getAmqpActor().getLogMessage(); assertEquals("Unexpected log message", "[mng:N/A(" + IP + ")] ", message); assertLogMessageWithoutPrincipal("TEST"); @@ -158,28 +158,26 @@ public class ManagementActorTest extends BaseActorTestCase private void assertLogMessageInRMIThreadWithoutPrincipal(String threadName) { Thread.currentThread().setName(threadName ); - String message = _amqpActor.getLogMessage(); + String message = getAmqpActor().getLogMessage(); assertEquals("Unexpected log message", "[mng:N/A(" + IP + ")] ", message); } private void assertLogMessageWithoutPrincipal(String threadName) { Thread.currentThread().setName(threadName ); - String message = _amqpActor.getLogMessage(); + String message = getAmqpActor().getLogMessage(); assertEquals("Unexpected log message", "[" + threadName +"] ", message); } private void assertLogMessageInRMIThreadWithPrincipal(String threadName, String principalName) { Thread.currentThread().setName(threadName); - Subject subject = new Subject(true, Collections.singleton(new JMXPrincipal(principalName)), Collections.EMPTY_SET, - Collections.EMPTY_SET); - + Subject subject = TestPrincipalUtils.createTestSubject(principalName); final String message = Subject.doAs(subject, new PrivilegedAction<String>() { public String run() { - return _amqpActor.getLogMessage(); + return getAmqpActor().getLogMessage(); } }); diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/QueueActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/QueueActorTest.java index 409f7c84b7..2dc44c58ce 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/QueueActorTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/QueueActorTest.java @@ -22,14 +22,16 @@ package org.apache.qpid.server.logging.actors; import java.util.List; +import org.apache.qpid.server.util.BrokerTestHelper; + public class QueueActorTest extends BaseConnectionActorTestCase { @Override - public void createBroker() throws Exception + public void setUp() throws Exception { - super.createBroker(); - _amqpActor = new QueueActor(getQueue(), _rootLogger); + super.setUp(); + setAmqpActor(new QueueActor(BrokerTestHelper.createQueue(getName(), getSession().getVirtualHost()), getRootLogger())); } /** @@ -42,9 +44,9 @@ public class QueueActorTest extends BaseConnectionActorTestCase */ public void testQueueActor() { - final String message = sendTestLogMessage(_amqpActor); + final String message = sendTestLogMessage(getAmqpActor()); - List<Object> logs = _rawLogger.getLogMessages(); + List<Object> logs = getRawLogger().getLogMessages(); assertEquals("Message log size not as expected.", 1, logs.size()); diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/SubscriptionActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/SubscriptionActorTest.java index 8eaa165853..58fca488c4 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/SubscriptionActorTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/SubscriptionActorTest.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.logging.actors; import org.apache.qpid.server.subscription.MockSubscription; +import org.apache.qpid.server.util.BrokerTestHelper; import java.util.List; @@ -37,15 +38,15 @@ public class SubscriptionActorTest extends BaseConnectionActorTestCase { @Override - public void createBroker() throws Exception + public void setUp() throws Exception { - super.createBroker(); + super.setUp(); MockSubscription mockSubscription = new MockSubscription(); - mockSubscription.setQueue(getQueue(), false); + mockSubscription.setQueue(BrokerTestHelper.createQueue(getName(), getSession().getVirtualHost()), false); - _amqpActor = new SubscriptionActor(_rootLogger, mockSubscription); + setAmqpActor(new SubscriptionActor(getRootLogger(), mockSubscription)); } /** @@ -58,9 +59,9 @@ public class SubscriptionActorTest extends BaseConnectionActorTestCase */ public void testSubscription() { - final String message = sendTestLogMessage(_amqpActor); + final String message = sendTestLogMessage(getAmqpActor()); - List<Object> logs = _rawLogger.getLogMessages(); + List<Object> logs = getRawLogger().getLogMessages(); assertEquals("Message log size not as expected.", 1, logs.size()); diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/log4j/LoggingFacadeTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/log4j/LoggingManagementFacadeTest.java index f871baffe6..72b34868ba 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/log4j/LoggingFacadeTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/log4j/LoggingManagementFacadeTest.java @@ -20,17 +20,19 @@ package org.apache.qpid.server.logging.log4j; import java.io.File; +import java.io.InputStream; import java.util.List; import java.util.Map; import org.apache.log4j.Level; +import org.apache.qpid.test.utils.TestFileUtils; import org.apache.qpid.util.FileUtils; import junit.framework.TestCase; -public class LoggingFacadeTest extends TestCase +public class LoggingManagementFacadeTest extends TestCase { - private LoggingFacade _loggingFacade; + private LoggingManagementFacade _loggingFacade; private String _log4jXmlFile; @Override @@ -38,7 +40,7 @@ public class LoggingFacadeTest extends TestCase { super.setUp(); _log4jXmlFile = createTestLog4jXml(); - _loggingFacade = LoggingFacade.configure(_log4jXmlFile); + _loggingFacade = LoggingManagementFacade.configure(_log4jXmlFile); } public void testGetAvailableLoggerLevels() throws Exception @@ -236,10 +238,6 @@ public class LoggingFacadeTest extends TestCase private String createTestLog4jXml() throws Exception { - File dst = File.createTempFile("log4j." + getName(), "xml"); - File filename = new File(getClass().getResource("LoggingFacadeTest.log4j.xml").toURI()); - FileUtils.copy(filename, dst); - dst.deleteOnExit(); - return dst.getAbsolutePath(); + return TestFileUtils.createTempFileFromResource(this, "LoggingFacadeTest.log4j.xml").getAbsolutePath(); } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java index 24e7225d82..229d75c69f 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java @@ -29,11 +29,12 @@ import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.UnitTestMessageLogger; import org.apache.qpid.server.logging.actors.TestLogActor; import org.apache.qpid.server.logging.subjects.TestBlankSubject; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.server.util.BrokerTestHelper; +import org.apache.qpid.test.utils.QpidTestCase; import java.util.List; -public abstract class AbstractTestMessages extends InternalBrokerBaseCase +public abstract class AbstractTestMessages extends QpidTestCase { protected Configuration _config = new PropertiesConfiguration(); protected LogMessage _logMessage = null; @@ -49,6 +50,14 @@ public abstract class AbstractTestMessages extends InternalBrokerBaseCase _logger = new UnitTestMessageLogger(); _actor = new TestLogActor(_logger); + BrokerTestHelper.setUp(); + } + + @Override + public void tearDown() throws Exception + { + BrokerTestHelper.tearDown(); + super.tearDown(); } protected List<Object> performLog() diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java index 4364376000..1cb4da55c3 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java @@ -21,7 +21,7 @@ package org.apache.qpid.server.logging.messages; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.util.BrokerTestHelper; import java.util.List; @@ -30,12 +30,9 @@ import java.util.List; */ public class ExchangeMessagesTest extends AbstractTestMessages { - public void testExchangeCreated_Transient() + public void testExchangeCreated_Transient() throws Exception { - // Get the Default Exchange on the Test Vhost for testing - Exchange exchange = ApplicationRegistry.getInstance(). - getVirtualHostRegistry().getVirtualHost("test"). - getExchangeRegistry().getDefaultExchange(); + Exchange exchange = BrokerTestHelper.createExchange("test"); String type = exchange.getTypeShortString().toString(); String name = exchange.getNameShortString().toString(); @@ -48,12 +45,9 @@ public class ExchangeMessagesTest extends AbstractTestMessages validateLogMessage(log, "EXH-1001", expected); } - public void testExchangeCreated_Persistent() + public void testExchangeCreated_Persistent() throws Exception { - // Get the Default Exchange on the Test Vhost for testing - Exchange exchange = ApplicationRegistry.getInstance(). - getVirtualHostRegistry().getVirtualHost("test"). - getExchangeRegistry().getDefaultExchange(); + Exchange exchange = BrokerTestHelper.createExchange("test"); String type = exchange.getTypeShortString().toString(); String name = exchange.getNameShortString().toString(); @@ -76,12 +70,9 @@ public class ExchangeMessagesTest extends AbstractTestMessages validateLogMessage(log, "EXH-1002", expected); } - public void testExchangeDiscardedMessage() + public void testExchangeDiscardedMessage() throws Exception { - // Get the Default Exchange on the Test Vhost for testing - final Exchange exchange = ApplicationRegistry.getInstance(). - getVirtualHostRegistry().getVirtualHost("test"). - getExchangeRegistry().getDefaultExchange(); + Exchange exchange = BrokerTestHelper.createExchange("test"); final String name = exchange.getNameShortString().toString(); final String routingKey = "routingKey"; diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessagesTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessagesTest.java index 4bfbae44ac..dfc9357402 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessagesTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessagesTest.java @@ -29,10 +29,10 @@ public class ManagementConsoleMessagesTest extends AbstractTestMessages { public void testManagementStartup() { - _logMessage = ManagementConsoleMessages.STARTUP(); + _logMessage = ManagementConsoleMessages.STARTUP("My"); List<Object> log = performLog(); - String[] expected = {"Startup"}; + String[] expected = {"My Management Startup"}; validateLogMessage(log, "MNG-1001", expected); } @@ -65,29 +65,20 @@ public class ManagementConsoleMessagesTest extends AbstractTestMessages public void testManagementReady() { - _logMessage = ManagementConsoleMessages.READY(false); + _logMessage = ManagementConsoleMessages.READY("My"); List<Object> log = performLog(); - String[] expected = {"Ready"}; - - validateLogMessage(log, "MNG-1004", expected); - - _logger.clearLogMessages(); - - _logMessage = ManagementConsoleMessages.READY(true); - log = performLog(); - - expected = new String[]{"Ready : Using the platform JMX Agent"}; + String[] expected = {"My Management Ready"}; validateLogMessage(log, "MNG-1004", expected); } public void testManagementStopped() { - _logMessage = ManagementConsoleMessages.STOPPED(); + _logMessage = ManagementConsoleMessages.STOPPED("My"); List<Object> log = performLog(); - String[] expected = {"Stopped"}; + String[] expected = {"My Management Stopped"}; validateLogMessage(log, "MNG-1005", expected); } diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java index c2558d2d1b..193e8a490d 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java @@ -20,21 +20,19 @@ */ package org.apache.qpid.server.logging.subjects; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.LogMessage; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.UnitTestMessageLogger; +import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.actors.TestLogActor; import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.test.utils.QpidTestCase; import java.util.List; @@ -49,29 +47,39 @@ import java.util.List; * The resulting log file is then validated. * */ -public abstract class AbstractTestLogSubject extends InternalBrokerBaseCase +public abstract class AbstractTestLogSubject extends QpidTestCase { - protected Configuration _config = new PropertiesConfiguration(); protected LogSubject _subject = null; @Override public void setUp() throws Exception { super.setUp(); - - _config.setProperty(ServerConfiguration.STATUS_UPDATES, "ON"); + BrokerTestHelper.setUp(); } + @Override + public void tearDown() throws Exception + { + BrokerTestHelper.tearDown(); + try + { + CurrentActor.removeAll(); + } + finally + { + super.tearDown(); + } + } - protected List<Object> performLog() throws ConfigurationException + protected List<Object> performLog(boolean statusUpdatesEnabled) { if (_subject == null) { throw new NullPointerException("LogSubject has not been set"); } - ServerConfiguration serverConfig = new ServerConfiguration(_config); - UnitTestMessageLogger logger = new UnitTestMessageLogger(serverConfig); + UnitTestMessageLogger logger = new UnitTestMessageLogger(statusUpdatesEnabled); LogActor actor = new TestLogActor(logger); @@ -247,11 +255,10 @@ public abstract class AbstractTestLogSubject extends InternalBrokerBaseCase /** * Test that when Logging occurs a single log statement is provided * - * @throws ConfigurationException */ - public void testEnabled() throws ConfigurationException + public void testEnabled() { - List<Object> logs = performLog(); + List<Object> logs = performLog(true); assertEquals("Log has incorrect message count", 1, logs.size()); @@ -267,15 +274,11 @@ public abstract class AbstractTestLogSubject extends InternalBrokerBaseCase protected abstract void validateLogStatement(String message); /** - * Ensure that when status-updates are off this does not perform logging - * - * @throws ConfigurationException + * Ensure that when status updates are off this does not perform logging */ - public void testDisabled() throws ConfigurationException + public void testDisabled() { - _config.setProperty(ServerConfiguration.STATUS_UPDATES, "OFF"); - - List<Object> logs = performLog(); + List<Object> logs = performLog(false); assertEquals("Log has incorrect message count", 0, logs.size()); } diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java index e80c4c4679..dd8d28e836 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java @@ -24,7 +24,7 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.MockAMQQueue; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; /** @@ -38,13 +38,12 @@ public class BindingLogSubjectTest extends AbstractTestLogSubject private Exchange _exchange; private VirtualHost _testVhost; + @Override public void setUp() throws Exception { super.setUp(); - _testVhost = ApplicationRegistry.getInstance().getVirtualHostRegistry(). - getVirtualHost("test"); - // Configure items for subjectCreation + _testVhost = BrokerTestHelper.createVirtualHost("test"); _routingKey = new AMQShortString("RoutingKey"); _exchange = _testVhost.getExchangeRegistry().getDefaultExchange(); _queue = new MockAMQQueue("BindingLogSubjectTest"); @@ -53,6 +52,16 @@ public class BindingLogSubjectTest extends AbstractTestLogSubject _subject = new BindingLogSubject(String.valueOf(_routingKey), _exchange, _queue); } + @Override + public void tearDown() throws Exception + { + if (_testVhost != null) + { + _testVhost.close(); + } + super.tearDown(); + } + /** * Validate that the logged Subject message is as expected: * MESSAGE [Blank][vh(/test)/ex(direct/<<default>>)/qu(BindingLogSubjectTest)/rk(RoutingKey)] <Log Message> diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ChannelLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ChannelLogSubjectTest.java index 6bc5effa05..d75e033739 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ChannelLogSubjectTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ChannelLogSubjectTest.java @@ -34,6 +34,7 @@ public class ChannelLogSubjectTest extends ConnectionLogSubjectTest { super.setUp(); + AMQChannel channel = new AMQChannel(getSession(), _channelID, getSession().getVirtualHost().getMessageStore()); _subject = new ChannelLogSubject(channel); diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubjectTest.java index c246fff2a8..7dc4c443ba 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubjectTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubjectTest.java @@ -20,17 +20,34 @@ */ package org.apache.qpid.server.logging.subjects; +import org.apache.qpid.server.protocol.InternalTestProtocolSession; +import org.apache.qpid.server.util.BrokerTestHelper; + /** * Validate ConnectionLogSubjects are logged as expected */ public class ConnectionLogSubjectTest extends AbstractTestLogSubject { + private InternalTestProtocolSession _session; + + @Override public void setUp() throws Exception { super.setUp(); - _subject = new ConnectionLogSubject(getSession()); + _session = BrokerTestHelper.createSession("test"); + _subject = new ConnectionLogSubject(_session); + } + + @Override + public void tearDown() throws Exception + { + if (_session != null) + { + _session.getVirtualHost().close(); + } + super.tearDown(); } /** @@ -40,7 +57,12 @@ public class ConnectionLogSubjectTest extends AbstractTestLogSubject */ protected void validateLogStatement(String message) { - verifyConnection(getSession().getSessionID(), "InternalTestProtocolSession", "127.0.0.1:1", "test", message); + verifyConnection(_session.getSessionID(), "InternalTestProtocolSession", "127.0.0.1:1", "test", message); + } + + public InternalTestProtocolSession getSession() + { + return _session; } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubjectTest.java index cc06b05bf6..8d1b89bf3c 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubjectTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubjectTest.java @@ -21,7 +21,7 @@ package org.apache.qpid.server.logging.subjects; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; @@ -33,17 +33,27 @@ public class ExchangeLogSubjectTest extends AbstractTestLogSubject private Exchange _exchange; private VirtualHost _testVhost; + @Override public void setUp() throws Exception { super.setUp(); - _testVhost = ApplicationRegistry.getInstance().getVirtualHostRegistry(). - getVirtualHost("test"); + _testVhost = BrokerTestHelper.createVirtualHost("test"); _exchange = _testVhost.getExchangeRegistry().getDefaultExchange(); _subject = new ExchangeLogSubject(_exchange,_testVhost); } + @Override + public void tearDown() throws Exception + { + if (_testVhost != null) + { + _testVhost.close(); + } + super.tearDown(); + } + /** * Validate that the logged Subject message is as expected: * MESSAGE [Blank][vh(/test)/ex(direct/<<default>>)] <Log Message> diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubjectTest.java index c62b24c3b9..65fd249d03 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubjectTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubjectTest.java @@ -20,7 +20,7 @@ */ package org.apache.qpid.server.logging.subjects; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; /** @@ -30,16 +30,26 @@ public class MessageStoreLogSubjectTest extends AbstractTestLogSubject { private VirtualHost _testVhost; + @Override public void setUp() throws Exception { super.setUp(); - _testVhost = ApplicationRegistry.getInstance().getVirtualHostRegistry(). - getVirtualHost("test"); + _testVhost = BrokerTestHelper.createVirtualHost("test"); _subject = new MessageStoreLogSubject(_testVhost, _testVhost.getMessageStore().getClass().getSimpleName()); } + @Override + public void tearDown() throws Exception + { + if (_testVhost != null) + { + _testVhost.close(); + } + super.tearDown(); + } + /** * Validate that the logged Subject message is as expected: * MESSAGE [Blank][vh(/test)/ms(MemoryMessageStore)] <Log Message> diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/QueueLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/QueueLogSubjectTest.java index 1f432be57a..e2765f338b 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/QueueLogSubjectTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/QueueLogSubjectTest.java @@ -22,7 +22,7 @@ package org.apache.qpid.server.logging.subjects; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.MockAMQQueue; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; /** @@ -39,8 +39,7 @@ public class QueueLogSubjectTest extends AbstractTestLogSubject { super.setUp(); - _testVhost = ApplicationRegistry.getInstance().getVirtualHostRegistry(). - getVirtualHost("test"); + _testVhost = BrokerTestHelper.createVirtualHost("test"); _queue = new MockAMQQueue("QueueLogSubjectTest"); ((MockAMQQueue) _queue).setVirtualHost(_testVhost); @@ -48,6 +47,16 @@ public class QueueLogSubjectTest extends AbstractTestLogSubject _subject = new QueueLogSubject(_queue); } + @Override + public void tearDown() throws Exception + { + if (_testVhost != null) + { + _testVhost.close(); + } + super.tearDown(); + } + /** * Validate that the logged Subject message is as expected: * MESSAGE [Blank][vh(/test)/qu(QueueLogSubjectTest)] <Log Message> diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubjectTest.java index 0c356e1838..153d01f355 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubjectTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubjectTest.java @@ -23,12 +23,13 @@ package org.apache.qpid.server.logging.subjects; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.flow.LimitlessCreditManager; +import org.apache.qpid.server.protocol.InternalTestProtocolSession; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.MockAMQQueue; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.subscription.SubscriptionFactory; import org.apache.qpid.server.subscription.SubscriptionFactoryImpl; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; /** @@ -42,23 +43,24 @@ public class SubscriptionLogSubjectTest extends AbstractTestLogSubject private int _channelID = 1; private Subscription _subscription; + @Override public void setUp() throws Exception { super.setUp(); - _testVhost = ApplicationRegistry.getInstance().getVirtualHostRegistry(). - getVirtualHost("test"); + InternalTestProtocolSession session = BrokerTestHelper.createSession(); + _testVhost = session.getVirtualHost(); _queue = new MockAMQQueue("SubscriptionLogSubjectTest"); ((MockAMQQueue) _queue).setVirtualHost(_testVhost); - AMQChannel channel = new AMQChannel(getSession(), _channelID, getSession().getVirtualHost().getMessageStore()); + AMQChannel channel = new AMQChannel(session, _channelID, _testVhost.getMessageStore()); - getSession().addChannel(channel); + session.addChannel(channel); SubscriptionFactory factory = new SubscriptionFactoryImpl(); - _subscription = factory.createSubscription(_channelID, getSession(), new AMQShortString("cTag"), + _subscription = factory.createSubscription(_channelID, session, new AMQShortString("cTag"), false, null, false, new LimitlessCreditManager()); @@ -67,6 +69,16 @@ public class SubscriptionLogSubjectTest extends AbstractTestLogSubject _subject = new SubscriptionLogSubject(_subscription); } + @Override + public void tearDown() throws Exception + { + if (_testVhost != null) + { + _testVhost.close(); + } + super.tearDown(); + } + /** * Validate that the logged Subject message is as expected: * MESSAGE [Blank][sub:0(vh(/test)/qu(SubscriptionLogSubjectTest))] <Log Message> diff --git a/java/broker/src/test/java/org/apache/qpid/server/model/BrokerShutdownTest.java b/java/broker/src/test/java/org/apache/qpid/server/model/BrokerShutdownTest.java new file mode 100644 index 0000000000..7c1db6348b --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/model/BrokerShutdownTest.java @@ -0,0 +1,189 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.configuration.startup.DefaultRecovererProvider; +import org.apache.qpid.server.logging.LogRecorder; +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; +import org.apache.qpid.server.security.auth.manager.PlainPasswordFileAuthenticationManagerFactory; +import org.apache.qpid.server.stats.StatisticsGatherer; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; +import org.apache.qpid.test.utils.QpidTestCase; +import org.apache.qpid.test.utils.TestFileUtils; + +import java.io.File; +import java.security.Provider; +import java.security.Security; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** + * QPID-1390 : Test to validate that the AuthenticationManger can successfully unregister any new SASL providers when + * the broker is stopped. + */ +public class BrokerShutdownTest extends QpidTestCase +{ + private Provider[] _defaultProviders; + private Broker _broker; + private TaskExecutor _taskExecutor; + + @Override + public void setUp() throws Exception + { + // Get default providers + _defaultProviders = Security.getProviders(); + + super.setUp(); + + _taskExecutor = new TaskExecutor(); + _taskExecutor.start(); + + // Startup the new broker and register the new providers + _broker = startBroker(); + } + + @Override + public void tearDown() throws Exception + { + try + { + super.tearDown(); + } + finally + { + if (_taskExecutor != null) + { + _taskExecutor.stopImmediately(); + } + } + + } + + private Broker startBroker() throws Exception + { + ConfigurationEntryStore store = mock(ConfigurationEntryStore.class); + UUID brokerId = UUID.randomUUID(); + UUID authenticationProviderId = UUID.randomUUID(); + + ConfigurationEntry root = new ConfigurationEntry(brokerId, Broker.class.getSimpleName(), Collections.<String, Object> emptyMap(), + Collections.singleton(authenticationProviderId), store); + + File file = TestFileUtils.createTempFile(BrokerShutdownTest.this, ".db.users"); + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE); + attributes.put(PlainPasswordFileAuthenticationManagerFactory.ATTRIBUTE_PATH, file.getAbsolutePath()); + ConfigurationEntry authenticationProviderEntry = new ConfigurationEntry(authenticationProviderId, AuthenticationProvider.class.getSimpleName(), attributes, + Collections.<UUID> emptySet(), store); + + when(store.getRootEntry()).thenReturn(root); + when(store.getEntry(brokerId)).thenReturn(root); + when(store.getEntry(authenticationProviderId)).thenReturn(authenticationProviderEntry); + + // mocking the required object + StatisticsGatherer statisticsGatherer = mock(StatisticsGatherer.class); + VirtualHostRegistry virtualHostRegistry = mock(VirtualHostRegistry.class); + LogRecorder logRecorder = mock(LogRecorder.class); + RootMessageLogger rootMessageLogger = mock(RootMessageLogger.class); + + // recover the broker from the store + RecovererProvider provider = new DefaultRecovererProvider(statisticsGatherer, virtualHostRegistry, logRecorder, rootMessageLogger, _taskExecutor); + ConfiguredObjectRecoverer<? extends ConfiguredObject> brokerRecoverer = provider.getRecoverer(Broker.class.getSimpleName()); + + Broker broker = (Broker) brokerRecoverer.create(provider, store.getRootEntry()); + + // start broker + broker.setDesiredState(State.INITIALISING, State.ACTIVE); + return broker; + } + + private void stopBroker() + { + _broker.setDesiredState(State.ACTIVE, State.STOPPED); + } + + /** + * QPID-1399 : Ensure that the Authentication manager unregisters any SASL providers created during + * broker start-up. + * + */ + public void testAuthenticationMangerCleansUp() throws Exception + { + + // Get the providers after initialisation + Provider[] providersAfterInitialisation = Security.getProviders(); + + // Find the additions + List<Provider> additions = new LinkedList<Provider>(); + for (Provider afterInit : providersAfterInitialisation) + { + boolean found = false; + for (Provider defaultProvider : _defaultProviders) + { + if (defaultProvider == afterInit) + { + found = true; + break; + } + } + + // Record added registies + if (!found) + { + additions.add(afterInit); + } + } + + assertFalse("No new SASL mechanisms added by initialisation.", additions.isEmpty()); + + // Close the registry which will perform the close the + // AuthenticationManager + stopBroker(); + + // Validate that the SASL plugins have been removed. + Provider[] providersAfterClose = Security.getProviders(); + + assertTrue("No providers unregistered", providersAfterInitialisation.length > providersAfterClose.length); + + // Ensure that the additions are not still present after close(). + for (Provider afterClose : providersAfterClose) + { + assertFalse("Added provider not unregistered", additions.contains(afterClose)); + } + } + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/model/UUIDGeneratorTest.java b/java/broker/src/test/java/org/apache/qpid/server/model/UUIDGeneratorTest.java index 643132d371..c686a24e99 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/model/UUIDGeneratorTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/model/UUIDGeneratorTest.java @@ -70,8 +70,12 @@ public class UUIDGeneratorTest extends QpidTestCase idSet.add(id6); UUID id7 = UUIDGenerator.generateVhostAliasUUID(value, value); idSet.add(id7); + UUID id8 = UUIDGenerator.generateGroupUUID(value, value); + idSet.add(id8); + UUID id9 = UUIDGenerator.generateGroupMemberUUID(value, value, value); + idSet.add(id9); - assertEquals("The produced UUIDs were not all unique", 7, idSet.size()); + assertEquals("The produced UUIDs were not all unique", 9, idSet.size()); } public void testQueueIdGeneration() throws Exception diff --git a/java/broker/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java new file mode 100644 index 0000000000..585fecae83 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java @@ -0,0 +1,85 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model.adapter; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import junit.framework.TestCase; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.PasswordCredentialManagingAuthenticationProvider; +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager; + +public class AuthenticationProviderFactoryTest extends TestCase +{ + + public void testCreatePasswordCredentialManagingAuthenticationProvider() + { + AuthenticationProvider provider = testForFactory(mock(PrincipalDatabaseAuthenticationManager.class)); + assertTrue("The created provider should match the factory's AuthenticationManager type", + provider instanceof PasswordCredentialManagingAuthenticationProvider); + } + + public void testCreateNonPasswordCredentialManagingAuthenticationProvider() + { + AuthenticationProvider provider = testForFactory(mock(AuthenticationManager.class)); + assertFalse("The created provider should match the factory's AuthenticationManager type", + provider instanceof PasswordCredentialManagingAuthenticationProvider); + } + + @SuppressWarnings("unchecked") + private AuthenticationProvider testForFactory(AuthenticationManager authenticationManager) + { + UUID id = UUID.randomUUID(); + Map<String, Object> attributes = new HashMap<String, Object>(); + + QpidServiceLoader<AuthenticationManagerFactory> authManagerFactoryServiceLoader = mock(QpidServiceLoader.class); + AuthenticationManagerFactory authenticationManagerFactory = mock(AuthenticationManagerFactory.class); + ConfigurationEntry configurationEntry = mock(ConfigurationEntry.class); + + when(configurationEntry.getId()).thenReturn(id); + Broker broker = mock(Broker.class); + + when(authManagerFactoryServiceLoader.atLeastOneInstanceOf(AuthenticationManagerFactory.class)).thenReturn( + Collections.singleton(authenticationManagerFactory)); + when(authenticationManagerFactory.createInstance(attributes)).thenReturn(authenticationManager); + + AuthenticationProviderFactory providerFactory = new AuthenticationProviderFactory(authManagerFactoryServiceLoader); + AuthenticationProvider provider = providerFactory.create(id, broker, attributes, null); + + assertNotNull("Provider is not created", provider); + assertEquals("Unexpected ID", id, provider.getId()); + + return provider; + } + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java new file mode 100644 index 0000000000..14c5c265c9 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java @@ -0,0 +1,212 @@ +/* + * + * 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.model.adapter; + +import static org.mockito.Mockito.mock; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.Protocol; +import org.apache.qpid.server.model.Transport; +import org.apache.qpid.test.utils.QpidTestCase; + +public class PortFactoryTest extends QpidTestCase +{ + private UUID _portId = UUID.randomUUID(); + private int _portNumber = 123; + private Set<String> _tcpStringSet = Collections.singleton(Transport.SSL.name()); + private Set<Transport> _tcpTransportSet = Collections.singleton(Transport.SSL); + + private Map<String, Object> _attributes = new HashMap<String, Object>(); + + private Broker _broker = mock(Broker.class); + private PortFactory _portFactory; + + @Override + protected void setUp() throws Exception + { + setTestSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES, null); + setTestSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES, null); + _portFactory = new PortFactory(); + + _attributes.put(Port.PORT, _portNumber); + _attributes.put(Port.TRANSPORTS, _tcpStringSet); + + _attributes.put(Port.TCP_NO_DELAY, "true"); + _attributes.put(Port.RECEIVE_BUFFER_SIZE, "1"); + _attributes.put(Port.SEND_BUFFER_SIZE, "2"); + _attributes.put(Port.NEED_CLIENT_AUTH, "true"); + _attributes.put(Port.WANT_CLIENT_AUTH, "true"); + _attributes.put(Port.BINDING_ADDRESS, "127.0.0.1"); + } + + public void testDefaultProtocols() + { + Collection<Protocol> protocols = _portFactory.getDefaultProtocols(); + EnumSet<Protocol> expected = EnumSet.of(Protocol.AMQP_0_8, Protocol.AMQP_0_9, Protocol.AMQP_0_9_1, Protocol.AMQP_0_10, + Protocol.AMQP_1_0); + assertEquals("Unexpected protocols", new HashSet<Protocol>(expected), new HashSet<Protocol>(protocols)); + } + + public void testDefaultProtocolsWhenProtocolExcludeSystemPropertyIsSet() + { + setTestSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES, Protocol.AMQP_1_0.name() + "," + + Protocol.AMQP_0_10.name()); + _portFactory = new PortFactory(); + Collection<Protocol> protocols = _portFactory.getDefaultProtocols(); + EnumSet<Protocol> expected = EnumSet.of(Protocol.AMQP_0_8, Protocol.AMQP_0_9, Protocol.AMQP_0_9_1); + assertEquals("Unexpected protocols", new HashSet<Protocol>(expected), new HashSet<Protocol>(protocols)); + } + + public void testDefaultProtocolsWhenProtocolIncludeSystemPropertyIsSet() + { + setTestSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES, Protocol.AMQP_1_0.name() + "," + + Protocol.AMQP_0_10.name() + "," + Protocol.AMQP_0_9_1.name()); + setTestSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES, Protocol.AMQP_0_10.name() + "," + + Protocol.AMQP_0_9_1.name()); + _portFactory = new PortFactory(); + Collection<Protocol> protocols = _portFactory.getDefaultProtocols(); + EnumSet<Protocol> expected = EnumSet.of(Protocol.AMQP_0_8, Protocol.AMQP_0_9, Protocol.AMQP_0_9_1, Protocol.AMQP_0_10); + assertEquals("Unexpected protocols", new HashSet<Protocol>(expected), new HashSet<Protocol>(protocols)); + } + + public void testCreatePortWithMinimumAttributes() + { + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(Port.PORT, 1); + Port port = _portFactory.createPort(_portId, _broker, attributes); + + assertNotNull(port); + assertTrue(port instanceof AmqpPortAdapter); + assertEquals("Unexpected port", 1, port.getPort()); + assertEquals("Unexpected transports", Collections.singleton(PortFactory.DEFAULT_TRANSPORT), port.getTransports()); + assertEquals("Unexpected protocols", _portFactory.getDefaultProtocols(), port.getProtocols()); + assertEquals("Unexpected send buffer size", PortFactory.DEFAULT_AMQP_SEND_BUFFER_SIZE, + port.getAttribute(Port.SEND_BUFFER_SIZE)); + assertEquals("Unexpected receive buffer size", PortFactory.DEFAULT_AMQP_RECEIVE_BUFFER_SIZE, + port.getAttribute(Port.RECEIVE_BUFFER_SIZE)); + assertEquals("Unexpected need client auth", PortFactory.DEFAULT_AMQP_NEED_CLIENT_AUTH, + port.getAttribute(Port.NEED_CLIENT_AUTH)); + assertEquals("Unexpected want client auth", PortFactory.DEFAULT_AMQP_WANT_CLIENT_AUTH, + port.getAttribute(Port.WANT_CLIENT_AUTH)); + assertEquals("Unexpected tcp no delay", PortFactory.DEFAULT_AMQP_TCP_NO_DELAY, port.getAttribute(Port.TCP_NO_DELAY)); + assertEquals("Unexpected binding", PortFactory.DEFAULT_AMQP_BINDING, port.getAttribute(Port.BINDING_ADDRESS)); + } + + public void testCreateAmqpPort() + { + Set<Protocol> amqp010ProtocolSet = Collections.singleton(Protocol.AMQP_0_10); + Set<String> amqp010StringSet = Collections.singleton(Protocol.AMQP_0_10.name()); + _attributes.put(Port.PROTOCOLS, amqp010StringSet); + + Port port = _portFactory.createPort(_portId, _broker, _attributes); + + assertNotNull(port); + assertTrue(port instanceof AmqpPortAdapter); + assertEquals(_portId, port.getId()); + assertEquals(_portNumber, port.getPort()); + assertEquals(_tcpTransportSet, port.getTransports()); + assertEquals(amqp010ProtocolSet, port.getProtocols()); + assertEquals("Unexpected send buffer size", 2, port.getAttribute(Port.SEND_BUFFER_SIZE)); + assertEquals("Unexpected receive buffer size", 1, port.getAttribute(Port.RECEIVE_BUFFER_SIZE)); + assertEquals("Unexpected need client auth", true, port.getAttribute(Port.NEED_CLIENT_AUTH)); + assertEquals("Unexpected want client auth", true, port.getAttribute(Port.WANT_CLIENT_AUTH)); + assertEquals("Unexpected tcp no delay", true, port.getAttribute(Port.TCP_NO_DELAY)); + assertEquals("Unexpected binding", "127.0.0.1", port.getAttribute(Port.BINDING_ADDRESS)); + } + + public void testCreateNonAmqpPort() + { + Set<Protocol> nonAmqpProtocolSet = Collections.singleton(Protocol.JMX_RMI); + Set<String> nonAmqpStringSet = Collections.singleton(Protocol.JMX_RMI.name()); + _attributes = new HashMap<String, Object>(); + _attributes.put(Port.PROTOCOLS, nonAmqpStringSet); + _attributes.put(Port.PORT, _portNumber); + _attributes.put(Port.TRANSPORTS, _tcpStringSet); + + Port port = _portFactory.createPort(_portId, _broker, _attributes); + + assertNotNull(port); + assertFalse("Port should be a PortAdapter, not its AMQP-specific subclass", port instanceof AmqpPortAdapter); + assertEquals(_portId, port.getId()); + assertEquals(_portNumber, port.getPort()); + assertEquals(_tcpTransportSet, port.getTransports()); + assertEquals(nonAmqpProtocolSet, port.getProtocols()); + assertNull("Unexpected send buffer size", port.getAttribute(Port.SEND_BUFFER_SIZE)); + assertNull("Unexpected receive buffer size", port.getAttribute(Port.RECEIVE_BUFFER_SIZE)); + assertNull("Unexpected need client auth", port.getAttribute(Port.NEED_CLIENT_AUTH)); + assertNull("Unexpected want client auth", port.getAttribute(Port.WANT_CLIENT_AUTH)); + assertNull("Unexpected tcp no delay", port.getAttribute(Port.TCP_NO_DELAY)); + assertNull("Unexpected binding", port.getAttribute(Port.BINDING_ADDRESS)); + } + + public void testCreateNonAmqpPortWithPartiallySetAttributes() + { + Set<Protocol> nonAmqpProtocolSet = Collections.singleton(Protocol.JMX_RMI); + Set<String> nonAmqpStringSet = Collections.singleton(Protocol.JMX_RMI.name()); + _attributes = new HashMap<String, Object>(); + _attributes.put(Port.PROTOCOLS, nonAmqpStringSet); + _attributes.put(Port.PORT, _portNumber); + + Port port = _portFactory.createPort(_portId, _broker, _attributes); + + assertNotNull(port); + assertFalse("Port should be a PortAdapter, not its AMQP-specific subclass", port instanceof AmqpPortAdapter); + assertEquals(_portId, port.getId()); + assertEquals(_portNumber, port.getPort()); + assertEquals(Collections.singleton(PortFactory.DEFAULT_TRANSPORT), port.getTransports()); + assertEquals(nonAmqpProtocolSet, port.getProtocols()); + assertNull("Unexpected send buffer size", port.getAttribute(Port.SEND_BUFFER_SIZE)); + assertNull("Unexpected receive buffer size", port.getAttribute(Port.RECEIVE_BUFFER_SIZE)); + assertNull("Unexpected need client auth", port.getAttribute(Port.NEED_CLIENT_AUTH)); + assertNull("Unexpected want client auth", port.getAttribute(Port.WANT_CLIENT_AUTH)); + assertNull("Unexpected tcp no delay", port.getAttribute(Port.TCP_NO_DELAY)); + assertNull("Unexpected binding", port.getAttribute(Port.BINDING_ADDRESS)); + } + + public void testCreateMixedAmqpAndNonAmqpThrowsException() + { + Set<String> mixedProtocolSet = new HashSet<String>(Arrays.asList(Protocol.AMQP_0_10.name(), Protocol.JMX_RMI.name())); + _attributes.put(Port.PROTOCOLS, mixedProtocolSet); + + try + { + _portFactory.createPort(_portId, _broker, _attributes); + fail("Exception not thrown"); + } + catch (IllegalConfigurationException e) + { + // pass + } + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/model/configuration/ConfigurationEntryTest.java b/java/broker/src/test/java/org/apache/qpid/server/model/configuration/ConfigurationEntryTest.java new file mode 100644 index 0000000000..dd48d7b56d --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/model/configuration/ConfigurationEntryTest.java @@ -0,0 +1,129 @@ +/* + * + * 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.model.configuration; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import junit.framework.TestCase; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.VirtualHost; + +public class ConfigurationEntryTest extends TestCase +{ + public void testGetChildren() + { + ConfigurationEntryStore store = mock(ConfigurationEntryStore.class); + + ConfigurationEntry virtualHostEntry1 = new ConfigurationEntry(UUID.randomUUID(), VirtualHost.class.getSimpleName(), + Collections.<String, Object> emptyMap(), Collections.<UUID> emptySet(), store); + ConfigurationEntry virtualHostEntry2 = new ConfigurationEntry(UUID.randomUUID(), VirtualHost.class.getSimpleName(), + Collections.<String, Object> emptyMap(), Collections.<UUID> emptySet(), store); + ConfigurationEntry portEntry = new ConfigurationEntry(UUID.randomUUID(), Port.class.getSimpleName(), + Collections.<String, Object> emptyMap(), Collections.<UUID> emptySet(), store); + + when(store.getEntry(virtualHostEntry1.getId())).thenReturn(virtualHostEntry1); + when(store.getEntry(virtualHostEntry2.getId())).thenReturn(virtualHostEntry2); + when(store.getEntry(portEntry.getId())).thenReturn(portEntry); + + Set<UUID> childrenIds = new HashSet<UUID>(); + childrenIds.add(virtualHostEntry1.getId()); + childrenIds.add(virtualHostEntry2.getId()); + childrenIds.add(portEntry.getId()); + ConfigurationEntry parentEntry = new ConfigurationEntry(UUID.randomUUID(), Broker.class.getSimpleName(), + Collections.<String, Object> emptyMap(), childrenIds, store); + + Map<String, Collection<ConfigurationEntry>> children = parentEntry.getChildren(); + assertNotNull("Null is returned for children", children); + assertEquals("Unexpected size", 2, children.size()); + Collection<ConfigurationEntry> virtualHosts = children.get(VirtualHost.class.getSimpleName()); + Collection<ConfigurationEntry> ports = children.get(Port.class.getSimpleName()); + assertEquals("Unexpected virtual hosts", + new HashSet<ConfigurationEntry>(Arrays.asList(virtualHostEntry1, virtualHostEntry2)), + new HashSet<ConfigurationEntry>(virtualHosts)); + assertEquals("Unexpected ports", new HashSet<ConfigurationEntry>(Arrays.asList(portEntry)), + new HashSet<ConfigurationEntry>(ports)); + } + + public void testHashCode() + { + ConfigurationEntryStore store = mock(ConfigurationEntryStore.class); + + UUID id = UUID.randomUUID(); + ConfigurationEntry entry1 = new ConfigurationEntry(id, VirtualHost.class.getSimpleName(), + Collections.<String, Object> emptyMap(), Collections.singleton(UUID.randomUUID()), store); + ConfigurationEntry entry2 = new ConfigurationEntry(id, VirtualHost.class.getSimpleName(), + Collections.<String, Object> emptyMap(), Collections.singleton(UUID.randomUUID()), store); + ConfigurationEntry entryWithDifferentId = new ConfigurationEntry(UUID.randomUUID(), + VirtualHost.class.getSimpleName(), Collections.<String, Object> emptyMap(), Collections.singleton(UUID.randomUUID()), store); + + assertTrue(entry1.hashCode() == entry2.hashCode()); + assertFalse(entry1.hashCode() == entryWithDifferentId.hashCode()); + } + + public void testEqualsObject() + { + ConfigurationEntryStore store = mock(ConfigurationEntryStore.class); + + UUID id = UUID.randomUUID(); + Map<String, Object> attributes1 = new HashMap<String, Object>(); + attributes1.put(VirtualHost.NAME, "name1"); + Set<UUID> childrenIds = Collections.singleton(UUID.randomUUID()); + ConfigurationEntry entry1 = new ConfigurationEntry(id, VirtualHost.class.getSimpleName(), attributes1, + childrenIds, store); + + Map<String, Object> attributes2 = new HashMap<String, Object>(); + attributes2.put(VirtualHost.NAME, "name2"); + + ConfigurationEntry entry2 = new ConfigurationEntry(id, VirtualHost.class.getSimpleName(), attributes1, + childrenIds, store); + ConfigurationEntry entryWithDifferentId = new ConfigurationEntry(UUID.randomUUID(), + VirtualHost.class.getSimpleName(), attributes1, childrenIds, store); + + assertTrue(entry1.equals(entry2)); + assertFalse("Entries should be diferrent because of diferrent IDs", entry1.equals(entryWithDifferentId)); + + ConfigurationEntry entryWithDifferentChildId = new ConfigurationEntry(id, + VirtualHost.class.getSimpleName(), attributes1, Collections.singleton(UUID.randomUUID()), store); + assertFalse("Entries should be diferrent because of diferrent children", entry1.equals(entryWithDifferentChildId)); + + ConfigurationEntry entryWithDifferentName = new ConfigurationEntry(id, + VirtualHost.class.getSimpleName(), attributes2, childrenIds, store); + assertFalse("Entries should be diferrent because of diferrent attributes", entry1.equals(entryWithDifferentName)); + + ConfigurationEntry entryWithDifferentType = new ConfigurationEntry(id, + Broker.class.getSimpleName(), attributes1, childrenIds, store); + assertFalse("Entries should be diferrent because of diferrent types", entry1.equals(entryWithDifferentType)); + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtilTest.java b/java/broker/src/test/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtilTest.java deleted file mode 100644 index 20abdd48cd..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtilTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * - * 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.plugins; - -import org.osgi.framework.Version; - -import org.apache.qpid.test.utils.QpidTestCase; - -import java.util.Map; -import java.util.TreeMap; - -/** - * - */ -public class OsgiSystemPackageUtilTest extends QpidTestCase -{ - private OsgiSystemPackageUtil _util = null; // Object under test - - private Map<String, String> _map = new TreeMap<String, String>(); // Use a TreeMap for unit test in order for determinstic results. - - public void testWithOnePackage() throws Exception - { - _map.put("org.xyz", "1.0.0"); - - _util = new OsgiSystemPackageUtil(null, _map); - - final String systemPackageString = _util.getFormattedSystemPackageString(); - - assertEquals("org.xyz; version=1.0.0", systemPackageString); - } - - public void testWithTwoPackages() throws Exception - { - _map.put("org.xyz", "1.0.0"); - _map.put("org.abc", "1.2.3"); - - _util = new OsgiSystemPackageUtil(null, _map); - - final String systemPackageString = _util.getFormattedSystemPackageString(); - - assertEquals("org.abc; version=1.2.3, org.xyz; version=1.0.0", systemPackageString); - } - - public void testWithNoPackages() throws Exception - { - _util = new OsgiSystemPackageUtil(null, _map); - - final String systemPackageString = _util.getFormattedSystemPackageString(); - - assertNull(systemPackageString); - } - - public void testWithQpidPackageWithQpidReleaseNumberSet() throws Exception - { - _map.put("org.apache.qpid.xyz", "1.0.0"); - _map.put("org.abc", "1.2.3"); - - _util = new OsgiSystemPackageUtil(new Version("0.19"), _map); - - final String systemPackageString = _util.getFormattedSystemPackageString(); - - assertEquals("org.abc; version=1.2.3, org.apache.qpid.xyz; version=0.19.0", systemPackageString); - } - - public void testWithQpidPackageWithoutQpidReleaseNumberSet() throws Exception - { - _map.put("org.apache.qpid.xyz", "1.0.0"); - _map.put("org.abc", "1.2.3"); - - _util = new OsgiSystemPackageUtil(null, _map); - - final String systemPackageString = _util.getFormattedSystemPackageString(); - - assertEquals("org.abc; version=1.2.3, org.apache.qpid.xyz; version=1.0.0", systemPackageString); - } -} diff --git a/java/broker/src/test/java/org/apache/qpid/server/plugins/PluginTest.java b/java/broker/src/test/java/org/apache/qpid/server/plugins/PluginTest.java deleted file mode 100644 index b4bda9a032..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/plugins/PluginTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.plugins; - -import org.apache.qpid.server.exchange.ExchangeType; -import org.apache.qpid.server.util.InternalBrokerBaseCase; - -import java.util.Map; - -public class PluginTest extends InternalBrokerBaseCase -{ - private static final String TEST_EXCHANGE_CLASS = "org.apache.qpid.extras.exchanges.example.TestExchangeType"; - - private static final String PLUGIN_DIRECTORY = System.getProperty("example.plugin.target"); - private static final String CACHE_DIRECTORY = System.getProperty("example.cache.target"); - - @Override - public void configure() - { - getConfiguration().getConfig().addProperty("plugin-directory", PLUGIN_DIRECTORY); - getConfiguration().getConfig().addProperty("cache-directory", CACHE_DIRECTORY); - } - - public void disabled_testLoadExchanges() throws Exception - { - PluginManager manager = getRegistry().getPluginManager(); - Map<String, ExchangeType<?>> exchanges = manager.getExchanges(); - assertNotNull("No exchanges found in " + PLUGIN_DIRECTORY, exchanges); - assertEquals("Wrong number of exchanges found in " + PLUGIN_DIRECTORY, 2, exchanges.size()); - assertNotNull("Wrong exchange found in " + PLUGIN_DIRECTORY, exchanges.get(TEST_EXCHANGE_CLASS)); - } - - public void testNoExchanges() throws Exception - { - PluginManager manager = new PluginManager("/path/to/nowhere", "/tmp", null); - Map<String, ExchangeType<?>> exchanges = manager.getExchanges(); - assertTrue("Exchanges found", exchanges.isEmpty()); - } -} diff --git a/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java b/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java index 96c67941f9..3216f8886a 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java +++ b/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java @@ -28,10 +28,11 @@ import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.message.AMQMessage; import org.apache.qpid.server.message.MessageContentSource; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.output.ProtocolOutputConverter; import org.apache.qpid.server.queue.QueueEntry; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.subscription.ClientDeliveryMethod; import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.subscription.SubscriptionImpl; @@ -39,6 +40,8 @@ import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.TestNetworkConnection; import javax.security.auth.Subject; + +import java.security.Principal; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -55,19 +58,28 @@ public class InternalTestProtocolSession extends AMQProtocolEngine implements Pr private AtomicInteger _deliveryCount = new AtomicInteger(0); private static final AtomicLong ID_GENERATOR = new AtomicLong(0); - public InternalTestProtocolSession(VirtualHost virtualHost) throws AMQException + public InternalTestProtocolSession(VirtualHost virtualHost, Broker broker) throws AMQException { - super(ApplicationRegistry.getInstance().getVirtualHostRegistry(), new TestNetworkConnection(), ID_GENERATOR.getAndIncrement()); + super(broker, new TestNetworkConnection(), ID_GENERATOR.getAndIncrement()); _channelDelivers = new HashMap<Integer, Map<AMQShortString, LinkedList<DeliveryPair>>>(); - // Need to authenticate session for it to be representative testing. - setAuthorizedSubject(new Subject(true, Collections.singleton(new UsernamePrincipal("InternalTestProtocolSession")), - Collections.EMPTY_SET, Collections.EMPTY_SET)); - + setTestAuthorizedSubject(); setVirtualHost(virtualHost); } + private void setTestAuthorizedSubject() + { + Principal principal = new AuthenticatedPrincipal(new UsernamePrincipal("InternalTestProtocolSession")); + Subject authorizedSubject = new Subject( + true, + Collections.singleton(principal), + Collections.emptySet(), + Collections.emptySet()); + + setAuthorizedSubject(authorizedSubject); + } + public ProtocolOutputConverter getProtocolOutputConverter() { return this; diff --git a/java/broker/src/test/java/org/apache/qpid/server/protocol/MaxChannelsTest.java b/java/broker/src/test/java/org/apache/qpid/server/protocol/MaxChannelsTest.java index e8ee2c4d0b..99dd42e179 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/protocol/MaxChannelsTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/protocol/MaxChannelsTest.java @@ -23,20 +23,24 @@ package org.apache.qpid.server.protocol; import org.apache.qpid.AMQException; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.util.InternalBrokerBaseCase; -import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.util.BrokerTestHelper; +import org.apache.qpid.test.utils.QpidTestCase; /** Test class to test MBean operations for AMQMinaProtocolSession. */ -public class MaxChannelsTest extends InternalBrokerBaseCase +public class MaxChannelsTest extends QpidTestCase { - private AMQProtocolEngine _session; + private AMQProtocolEngine _session; - public void testChannels() throws Exception + @Override + public void setUp() throws Exception { - VirtualHost vhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"); - _session = new InternalTestProtocolSession(vhost); + super.setUp(); + BrokerTestHelper.setUp(); + _session = BrokerTestHelper.createSession(); + } + public void testChannels() throws Exception + { // check the channel count is correct int channelCount = _session.getChannels().size(); assertEquals("Initial channel count wrong", 0, channelCount); @@ -45,13 +49,15 @@ public class MaxChannelsTest extends InternalBrokerBaseCase _session.setMaximumNumberOfChannels(maxChannels); assertEquals("Number of channels not correctly set.", new Long(maxChannels), _session.getMaximumNumberOfChannels()); + for (long currentChannel = 0L; currentChannel < maxChannels; currentChannel++) + { + _session.addChannel(new AMQChannel(_session, (int) currentChannel, null)); + } try { - for (long currentChannel = 0L; currentChannel < maxChannels; currentChannel++) - { - _session.addChannel(new AMQChannel(_session, (int) currentChannel, null)); - } + _session.addChannel(new AMQChannel(_session, (int) maxChannels, null)); + fail("Cannot create more channels then maximum"); } catch (AMQException e) { @@ -63,14 +69,14 @@ public class MaxChannelsTest extends InternalBrokerBaseCase @Override public void tearDown() throws Exception { - try { - _session.closeSession(); - } catch (AMQException e) { - // Yikes - fail(e.getMessage()); - } + try + { + _session.getVirtualHost().close(); + _session.closeSession(); + } finally { + BrokerTestHelper.tearDown(); super.tearDown(); } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java index 6081be8efd..02b8c74feb 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java @@ -20,36 +20,52 @@ */ package org.apache.qpid.server.protocol; -import org.apache.commons.configuration.XMLConfiguration; - -import org.apache.qpid.protocol.ServerProtocolEngine; -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.util.TestApplicationRegistry; -import org.apache.qpid.test.utils.QpidTestCase; -import org.apache.qpid.transport.TestNetworkConnection; +import static org.mockito.Mockito.when; import java.nio.ByteBuffer; import java.util.EnumSet; import java.util.Set; +import org.apache.qpid.protocol.ServerProtocolEngine; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.util.BrokerTestHelper; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; +import org.apache.qpid.test.utils.QpidTestCase; +import org.apache.qpid.transport.TestNetworkConnection; + public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase { + private VirtualHost _virtualHost; + private Broker _broker; + @Override protected void setUp() throws Exception { super.setUp(); + BrokerTestHelper.setUp(); + _broker = BrokerTestHelper.createBrokerMock(); + VirtualHostRegistry virtualHostRegistry = _broker.getVirtualHostRegistry(); + when(_broker.getAttribute(Broker.DEFAULT_VIRTUAL_HOST)).thenReturn("default"); - //the factory needs a registry instance - ApplicationRegistry.initialise(new TestApplicationRegistry(new ServerConfiguration(new XMLConfiguration()))); + // AMQP 1-0 connection needs default vhost to be present + _virtualHost = BrokerTestHelper.createVirtualHost("default", virtualHostRegistry); } - protected void tearDown() + @Override + protected void tearDown() throws Exception { - //the factory opens a registry instance - ApplicationRegistry.remove(); + try + { + _virtualHost.close(); + } + finally + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } } - + private static final byte[] AMQP_0_8_HEADER = new byte[] { (byte) 'A', (byte) 'M', @@ -108,6 +124,7 @@ public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase (byte) 0 }; + private byte[] getAmqpHeader(final AmqpProtocolVersion version) { switch(version) @@ -137,7 +154,7 @@ public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase Set<AmqpProtocolVersion> versions = EnumSet.allOf(AmqpProtocolVersion.class); MultiVersionProtocolEngineFactory factory = - new MultiVersionProtocolEngineFactory(versions, null); + new MultiVersionProtocolEngineFactory(_broker, versions, null); //create a dummy to retrieve the 'current' ID number long previousId = factory.newProtocolEngine().getConnectionId(); @@ -160,6 +177,7 @@ public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase assertEquals("ID was not as expected following receipt of the AMQP version header", expectedID, engine.getConnectionId()); previousId = expectedID; + engine.closed(); } } @@ -174,7 +192,7 @@ public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase try { - new MultiVersionProtocolEngineFactory(versions, AmqpProtocolVersion.v0_9); + new MultiVersionProtocolEngineFactory(_broker, versions, AmqpProtocolVersion.v0_9); fail("should not have been allowed to create the factory"); } catch(IllegalArgumentException iae) diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java index c3d58f3bdc..81ad57c040 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java @@ -36,8 +36,9 @@ public class AMQPriorityQueueTest extends SimpleAMQQueueTest @Override public void setUp() throws Exception { - _arguments = new FieldTable(); - _arguments.put(new AMQShortString(AMQQueueFactory.X_QPID_PRIORITIES), 3); + FieldTable arguments = new FieldTable(); + arguments.put(new AMQShortString(AMQQueueFactory.X_QPID_PRIORITIES), 3); + setArguments(arguments); super.setUp(); } @@ -45,25 +46,26 @@ public class AMQPriorityQueueTest extends SimpleAMQQueueTest { // Enqueue messages in order - _queue.enqueue(createMessage(1L, (byte) 10)); - _queue.enqueue(createMessage(2L, (byte) 4)); - _queue.enqueue(createMessage(3L, (byte) 0)); + SimpleAMQQueue queue = getQueue(); + queue.enqueue(createMessage(1L, (byte) 10)); + queue.enqueue(createMessage(2L, (byte) 4)); + queue.enqueue(createMessage(3L, (byte) 0)); // Enqueue messages in reverse order - _queue.enqueue(createMessage(4L, (byte) 0)); - _queue.enqueue(createMessage(5L, (byte) 4)); - _queue.enqueue(createMessage(6L, (byte) 10)); + queue.enqueue(createMessage(4L, (byte) 0)); + queue.enqueue(createMessage(5L, (byte) 4)); + queue.enqueue(createMessage(6L, (byte) 10)); // Enqueue messages out of order - _queue.enqueue(createMessage(7L, (byte) 4)); - _queue.enqueue(createMessage(8L, (byte) 10)); - _queue.enqueue(createMessage(9L, (byte) 0)); + queue.enqueue(createMessage(7L, (byte) 4)); + queue.enqueue(createMessage(8L, (byte) 10)); + queue.enqueue(createMessage(9L, (byte) 0)); // Register subscriber - _queue.registerSubscription(_subscription, false); + queue.registerSubscription(getSubscription(), false); Thread.sleep(150); - ArrayList<QueueEntry> msgs = _subscription.getMessages(); + ArrayList<QueueEntry> msgs = getSubscription().getMessages(); try { assertEquals(1L, msgs.get(0).getMessage().getMessageNumber()); diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java index 186be4dff7..0f82345271 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java @@ -20,23 +20,23 @@ */ package org.apache.qpid.server.queue; +import static org.mockito.Mockito.when; + import org.apache.commons.configuration.XMLConfiguration; import org.apache.qpid.AMQException; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.server.configuration.ServerConfiguration; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.DefaultExchangeFactory; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.logging.SystemOutMessageLogger; -import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.logging.actors.TestLogActor; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.store.TestableMemoryMessageStore; -import org.apache.qpid.server.util.TestApplicationRegistry; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.test.utils.QpidTestCase; @@ -50,19 +50,19 @@ public class AMQQueueFactoryTest extends QpidTestCase { super.setUp(); - CurrentActor.set(new TestLogActor(new SystemOutMessageLogger())); - + BrokerTestHelper.setUp(); XMLConfiguration configXml = new XMLConfiguration(); - configXml.addProperty("virtualhosts.virtualhost(-1).name", getName()); - configXml.addProperty("virtualhosts.virtualhost(-1)."+getName()+".store.class", TestableMemoryMessageStore.class.getName()); + configXml.addProperty("store.class", TestableMemoryMessageStore.class.getName()); - ServerConfiguration configuration = new ServerConfiguration(configXml); - ApplicationRegistry registry = new TestApplicationRegistry(configuration); - ApplicationRegistry.initialise(registry); - registry.getVirtualHostRegistry().setDefaultVirtualHostName(getName()); + Broker broker = BrokerTestHelper.createBrokerMock(); + if (getName().equals("testDeadLetterQueueDoesNotInheritDLQorMDCSettings")) + { + when(broker.getAttribute(Broker.MAXIMUM_DELIVERY_ATTEMPTS)).thenReturn(5); + when(broker.getAttribute(Broker.DEAD_LETTER_QUEUE_ENABLED)).thenReturn(true); + } - _virtualHost = registry.getVirtualHostRegistry().getVirtualHost(getName()); + _virtualHost = BrokerTestHelper.createVirtualHost(new VirtualHostConfiguration(getName(), configXml, broker)); _queueRegistry = _virtualHost.getQueueRegistry(); @@ -73,11 +73,12 @@ public class AMQQueueFactoryTest extends QpidTestCase { try { - super.tearDown(); + _virtualHost.close(); } finally { - ApplicationRegistry.remove(); + BrokerTestHelper.tearDown(); + super.tearDown(); } } @@ -172,11 +173,8 @@ public class AMQQueueFactoryTest extends QpidTestCase * are not applied to the DLQ itself. * @throws AMQException */ - public void testDeadLetterQueueDoesNotInheritDLQorMDCSettings() throws AMQException + public void testDeadLetterQueueDoesNotInheritDLQorMDCSettings() throws Exception { - ApplicationRegistry.getInstance().getConfiguration().getConfig().addProperty("deadLetterQueues","true"); - ApplicationRegistry.getInstance().getConfiguration().getConfig().addProperty("maximumDeliveryCount","5"); - String queueName = "testDeadLetterQueueEnabled"; AMQShortString dlExchangeName = new AMQShortString(queueName + DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX); AMQShortString dlQueueName = new AMQShortString(queueName + AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX); @@ -336,11 +334,8 @@ public class AMQQueueFactoryTest extends QpidTestCase try { // change DLQ name to make its length bigger than exchange name - ApplicationRegistry.getInstance().getConfiguration().getConfig() - .addProperty("deadLetterExchangeSuffix", "_DLE"); - ApplicationRegistry.getInstance().getConfiguration().getConfig() - .addProperty("deadLetterQueueSuffix", "_DLQUEUE"); - + setTestSystemProperty(BrokerProperties.PROPERTY_DEAD_LETTER_EXCHANGE_SUFFIX, "_DLE"); + setTestSystemProperty(BrokerProperties.PROPERTY_DEAD_LETTER_QUEUE_SUFFIX, "_DLQUEUE"); FieldTable fieldTable = new FieldTable(); fieldTable.setBoolean(AMQQueueFactory.X_QPID_DLQ_ENABLED, true); AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), queueName, false, "owner", @@ -353,13 +348,6 @@ public class AMQQueueFactoryTest extends QpidTestCase assertTrue("Unexpected exception message!", e.getMessage().contains("DLQ queue name") && e.getMessage().contains("length exceeds limit of 255")); } - finally - { - ApplicationRegistry.getInstance().getConfiguration().getConfig() - .addProperty("deadLetterExchangeSuffix", DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX); - ApplicationRegistry.getInstance().getConfiguration().getConfig() - .addProperty("deadLetterQueueSuffix", AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX); - } } /** @@ -372,11 +360,8 @@ public class AMQQueueFactoryTest extends QpidTestCase try { // change DLQ name to make its length bigger than exchange name - ApplicationRegistry.getInstance().getConfiguration().getConfig() - .addProperty("deadLetterExchangeSuffix", "_DLEXCHANGE"); - ApplicationRegistry.getInstance().getConfiguration().getConfig() - .addProperty("deadLetterQueueSuffix", "_DLQ"); - + setTestSystemProperty(BrokerProperties.PROPERTY_DEAD_LETTER_EXCHANGE_SUFFIX, "_DLEXCHANGE"); + setTestSystemProperty(BrokerProperties.PROPERTY_DEAD_LETTER_QUEUE_SUFFIX, "_DLQ"); FieldTable fieldTable = new FieldTable(); fieldTable.setBoolean(AMQQueueFactory.X_QPID_DLQ_ENABLED, true); AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), queueName, false, "owner", @@ -389,13 +374,6 @@ public class AMQQueueFactoryTest extends QpidTestCase assertTrue("Unexpected exception message!", e.getMessage().contains("DL exchange name") && e.getMessage().contains("length exceeds limit of 255")); } - finally - { - ApplicationRegistry.getInstance().getConfiguration().getConfig() - .addProperty("deadLetterExchangeSuffix", DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX); - ApplicationRegistry.getInstance().getConfiguration().getConfig() - .addProperty("deadLetterQueueSuffix", AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX); - } } private String generateStringWithLength(char ch, int length) diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java index 190d5c777b..cbbf183232 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java @@ -32,18 +32,16 @@ import org.apache.qpid.server.flow.LimitlessCreditManager; import org.apache.qpid.server.flow.Pre0_10CreditManager; import org.apache.qpid.server.message.AMQMessage; import org.apache.qpid.server.message.MessageMetaData; -import org.apache.qpid.server.model.UUIDGenerator; import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.protocol.InternalTestProtocolSession; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.store.StoredMessage; import org.apache.qpid.server.store.TestableMemoryMessageStore; import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.subscription.SubscriptionFactoryImpl; import org.apache.qpid.server.txn.AutoCommitTransaction; import org.apache.qpid.server.txn.ServerTransaction; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.test.utils.QpidTestCase; import java.util.ArrayList; import java.util.Set; @@ -51,7 +49,7 @@ import java.util.Set; /** * Tests that acknowledgements are handled correctly. */ -public class AckTest extends InternalBrokerBaseCase +public class AckTest extends QpidTestCase { private Subscription _subscription; @@ -70,15 +68,19 @@ public class AckTest extends InternalBrokerBaseCase public void setUp() throws Exception { super.setUp(); - _virtualHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"); - _messageStore = new TestableMemoryMessageStore(); - _protocolSession = new InternalTestProtocolSession(_virtualHost); - _channel = new AMQChannel(_protocolSession,5, _messageStore /*dont need exchange registry*/); - - _protocolSession.addChannel(_channel); + BrokerTestHelper.setUp(); + _channel = BrokerTestHelper.createChannel(5); + _protocolSession = _channel.getProtocolSession(); + _virtualHost = _protocolSession.getVirtualHost(); + _queue = BrokerTestHelper.createQueue(getTestName(), _virtualHost); + _messageStore = (TestableMemoryMessageStore)_virtualHost.getMessageStore(); + } - _queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "myQ", false, "guest", true, false, - _virtualHost, null); + @Override + protected void tearDown() throws Exception + { + BrokerTestHelper.tearDown(); + super.tearDown(); } private void publishMessages(int count) throws AMQException diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/InboundMessageAdapterTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/InboundMessageAdapterTest.java new file mode 100644 index 0000000000..2f160678ba --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/queue/InboundMessageAdapterTest.java @@ -0,0 +1,97 @@ +/* + * + * 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.queue; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.message.AMQMessageHeader; +import org.apache.qpid.server.message.ServerMessage; +import org.apache.qpid.test.utils.QpidTestCase; + +public class InboundMessageAdapterTest extends QpidTestCase +{ + private ServerMessage<?> _mockMessage; + private QueueEntry _mockQueueEntry; + private InboundMessageAdapter _inboundMessageAdapter; + + @Override + protected void setUp() throws Exception + { + super.setUp(); + _mockMessage = mock(ServerMessage.class); + _mockQueueEntry = mock(QueueEntry.class); + when(_mockQueueEntry.getMessage()).thenReturn(_mockMessage); + + _inboundMessageAdapter = new InboundMessageAdapter(_mockQueueEntry); + } + + public void testGetRoutingKey() throws Exception + { + String routingKey = getTestName(); + when(_mockMessage.getRoutingKey()).thenReturn(routingKey); + + assertEquals("Unexpected value for routing key", routingKey, _inboundMessageAdapter.getRoutingKey()); + } + + public void testGetRoutingKeyShortString() throws Exception + { + String routingKey = getTestName(); + when(_mockMessage.getRoutingKey()).thenReturn(routingKey); + + AMQShortString routingKeyShortString = AMQShortString.valueOf(routingKey); + assertEquals("Unexpected value for routing key short string", routingKeyShortString, _inboundMessageAdapter.getRoutingKeyShortString()); + } + + public void testGetMessageHeader() throws Exception + { + AMQMessageHeader mockMessageHeader = mock(AMQMessageHeader.class); + when(_mockQueueEntry.getMessageHeader()).thenReturn(mockMessageHeader); + + assertSame("unexpected message header", mockMessageHeader, _inboundMessageAdapter.getMessageHeader()); + } + + public void testIsRedelivered() throws Exception + { + when(_mockQueueEntry.isRedelivered()).thenReturn(true); + assertTrue("unexpected isRedelivered value", _inboundMessageAdapter.isRedelivered()); + + when(_mockQueueEntry.isRedelivered()).thenReturn(false); + assertFalse("unexpected isRedelivered value", _inboundMessageAdapter.isRedelivered()); + } + + public void testIsPersistent() throws Exception + { + when(_mockQueueEntry.isPersistent()).thenReturn(true); + assertTrue("unexpected isPersistent value", _inboundMessageAdapter.isPersistent()); + + when(_mockQueueEntry.isPersistent()).thenReturn(false); + assertFalse("unexpected isPersistent value", _inboundMessageAdapter.isPersistent()); + } + + public void testGetSize() throws Exception + { + long size = 32526215; + when(_mockQueueEntry.getSize()).thenReturn(size); + assertEquals("unexpected getSize value", size, _inboundMessageAdapter.getSize()); + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java b/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java index bcb8d54636..358246330a 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java +++ b/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java @@ -23,10 +23,8 @@ package org.apache.qpid.server.queue; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.QueueConfigType; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; +import org.apache.qpid.server.configuration.QueueConfiguration; +import org.apache.qpid.server.configuration.plugins.AbstractConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.message.ServerMessage; @@ -106,11 +104,6 @@ public class MockAMQQueue implements AMQQueue return 0; } - public ConfigStore getConfigStore() - { - return getVirtualHost().getConfigStore(); - } - public long getMessageDequeueCount() { return 0; @@ -186,22 +179,6 @@ public class MockAMQQueue implements AMQQueue return null; } - @Override - public UUID getQMFId() - { - return null; - } - - public QueueConfigType getConfigType() - { - return null; - } - - public ConfiguredObject getParent() - { - return null; - } - public boolean isDurable() { return false; @@ -532,16 +509,11 @@ public class MockAMQQueue implements AMQQueue } - public void configure(ConfigurationPlugin config) + public void configure(QueueConfiguration config) { } - public ConfigurationPlugin getConfiguration() - { - return null; - } - public AuthorizationHolder getAuthorizationHolder() { return _authorizationHolder; diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java index 2cd423d4c9..ece42f7de3 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java @@ -28,8 +28,6 @@ import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Matchers.contains; import static org.mockito.Matchers.eq; -import org.apache.commons.configuration.PropertiesConfiguration; - import org.apache.qpid.AMQException; import org.apache.qpid.AMQInternalException; import org.apache.qpid.AMQSecurityException; @@ -39,7 +37,6 @@ import org.apache.qpid.framing.BasicContentHeaderProperties; import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.abstraction.MessagePublishInfo; -import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.DirectExchange; import org.apache.qpid.server.message.AMQMessage; import org.apache.qpid.server.message.MessageMetaData; @@ -47,16 +44,15 @@ import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.server.model.UUIDGenerator; import org.apache.qpid.server.queue.BaseQueue.PostEnqueueAction; import org.apache.qpid.server.queue.SimpleAMQQueue.QueueEntryFilter; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.store.StoredMessage; import org.apache.qpid.server.store.TestableMemoryMessageStore; import org.apache.qpid.server.subscription.MockSubscription; import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.txn.AutoCommitTransaction; import org.apache.qpid.server.txn.ServerTransaction; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.virtualhost.VirtualHostImpl; +import org.apache.qpid.test.utils.QpidTestCase; import java.util.ArrayList; import java.util.Collections; @@ -64,17 +60,17 @@ import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -public class SimpleAMQQueueTest extends InternalBrokerBaseCase +public class SimpleAMQQueueTest extends QpidTestCase { - protected SimpleAMQQueue _queue; - protected VirtualHost _virtualHost; - protected AMQShortString _qname = new AMQShortString("qname"); - protected AMQShortString _owner = new AMQShortString("owner"); - protected AMQShortString _routingKey = new AMQShortString("routing key"); - protected DirectExchange _exchange; - protected MockSubscription _subscription = new MockSubscription(); - protected FieldTable _arguments = null; + private SimpleAMQQueue _queue; + private VirtualHost _virtualHost; + private AMQShortString _qname = new AMQShortString("qname"); + private AMQShortString _owner = new AMQShortString("owner"); + private AMQShortString _routingKey = new AMQShortString("routing key"); + private DirectExchange _exchange; + private MockSubscription _subscription = new MockSubscription(); + private FieldTable _arguments = null; private MessagePublishInfo info = new MessagePublishInfo() { @@ -108,25 +104,29 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase public void setUp() throws Exception { super.setUp(); - //Create Application Registry for test - ApplicationRegistry applicationRegistry = (ApplicationRegistry)ApplicationRegistry.getInstance(); + BrokerTestHelper.setUp(); - PropertiesConfiguration env = new PropertiesConfiguration(); - final VirtualHostConfiguration vhostConfig = new VirtualHostConfiguration(getClass().getName(), env); - vhostConfig.setMessageStoreClass(TestableMemoryMessageStore.class.getName()); - _virtualHost = new VirtualHostImpl(ApplicationRegistry.getInstance(), vhostConfig); - applicationRegistry.getVirtualHostRegistry().registerVirtualHost(_virtualHost); + _virtualHost = BrokerTestHelper.createVirtualHost(getClass().getName()); - _queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), _qname.asString(), false, _owner.asString(), false, false, _virtualHost, FieldTable.convertToMap(_arguments)); + _queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), _qname.asString(), false, _owner.asString(), + false, false, _virtualHost, FieldTable.convertToMap(_arguments)); - _exchange = (DirectExchange)_virtualHost.getExchangeRegistry().getExchange(ExchangeDefaults.DIRECT_EXCHANGE_NAME); + _exchange = (DirectExchange) _virtualHost.getExchangeRegistry().getExchange(ExchangeDefaults.DIRECT_EXCHANGE_NAME); } @Override public void tearDown() throws Exception { - _queue.stop(); - super.tearDown(); + try + { + _queue.stop(); + _virtualHost.close(); + } + finally + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } } public void testCreateQueue() throws AMQException @@ -659,7 +659,7 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase public void onRollback() { } - }, 0L); + }); // Check that it is enqueued AMQQueue data = store.getMessages().get(1L); @@ -1269,6 +1269,26 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase } } + public SimpleAMQQueue getQueue() + { + return _queue; + } + + public MockSubscription getSubscription() + { + return _subscription; + } + + public FieldTable getArguments() + { + return _arguments; + } + + public void setArguments(FieldTable arguments) + { + _arguments = arguments; + } + public class TestMessage extends AMQMessage { private final long _tag; diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java index 6b82cd361a..4abb7233dc 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java @@ -20,20 +20,33 @@ */ package org.apache.qpid.server.queue; -import org.apache.qpid.AMQException; import org.apache.qpid.pool.ReferenceCountingExecutorService; import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.test.utils.QpidTestCase; -public class SimpleAMQQueueThreadPoolTest extends InternalBrokerBaseCase +public class SimpleAMQQueueThreadPoolTest extends QpidTestCase { - public void test() throws AMQException + @Override + public void setUp() throws Exception + { + super.setUp(); + BrokerTestHelper.setUp(); + } + + @Override + public void tearDown() throws Exception + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } + + public void test() throws Exception { int initialCount = ReferenceCountingExecutorService.getInstance().getReferenceCount(); - VirtualHost test = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"); + VirtualHost test = BrokerTestHelper.createVirtualHost("test"); try { @@ -50,7 +63,7 @@ public class SimpleAMQQueueThreadPoolTest extends InternalBrokerBaseCase } finally { - ApplicationRegistry.remove(); + test.close(); } } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java b/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java deleted file mode 100644 index 9af950d385..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * - * 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.registry; - -import org.apache.qpid.server.util.InternalBrokerBaseCase; - -import java.security.Provider; -import java.security.Security; -import java.util.LinkedList; -import java.util.List; - -/** - * QPID-1390 : Test to validate that the AuthenticationManger can successfully unregister any new SASL providers when - * The ApplicationRegistry is closed. - * - * This should be expanded as QPID-1399 is implemented. - */ -public class ApplicationRegistryShutdownTest extends InternalBrokerBaseCase -{ - - private Provider[] _defaultProviders; - @Override - public void setUp() throws Exception - { - // Get default providers - _defaultProviders = Security.getProviders(); - - //Startup the new broker and register the new providers - super.setUp(); - } - - - /** - * QPID-1399 : Ensure that the Authentication manager unregisters any SASL providers created during - * ApplicationRegistry initialisation. - * - */ - public void testAuthenticationMangerCleansUp() throws Exception - { - - // Get the providers after initialisation - Provider[] providersAfterInitialisation = Security.getProviders(); - - // Find the additions - List additions = new LinkedList(); - for (Provider afterInit : providersAfterInitialisation) - { - boolean found = false; - for (Provider defaultProvider : _defaultProviders) - { - if (defaultProvider == afterInit) - { - found=true; - break; - } - } - - // Record added registies - if (!found) - { - additions.add(afterInit); - } - } - - assertFalse("No new SASL mechanisms added by initialisation.", additions.isEmpty()); - - //Close the registry which will perform the close the AuthenticationManager - stopBroker(); - - //Validate that the SASL plugFins have been removed. - Provider[] providersAfterClose = Security.getProviders(); - - assertTrue("No providers unregistered", providersAfterInitialisation.length > providersAfterClose.length); - - //Ensure that the additions are not still present after close(). - for (Provider afterClose : providersAfterClose) - { - assertFalse("Added provider not unregistered", additions.contains(afterClose)); - } - } - - - - - -} diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java new file mode 100644 index 0000000000..b1bc9bea68 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java @@ -0,0 +1,138 @@ +/* + * 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.security; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.security.Principal; +import java.util.Arrays; +import java.util.HashSet; + +import javax.security.auth.Subject; +import javax.security.sasl.SaslServer; + +import junit.framework.TestCase; + +import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; +import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; +import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.group.GroupPrincipalAccessor; + +public class SubjectCreatorTest extends TestCase +{ + private static final String USERNAME = "username"; + private static final String PASSWORD = "password"; + + private AuthenticationManager _authenticationManager = mock(AuthenticationManager.class); + private GroupPrincipalAccessor _groupPrincipalAccessor = mock(GroupPrincipalAccessor.class); + private SubjectCreator _subjectCreator = new SubjectCreator(_authenticationManager, _groupPrincipalAccessor); + + private Principal _userPrincipal = mock(Principal.class); + private Principal _group1 = mock(Principal.class); + private Principal _group2 = mock(Principal.class); + + private AuthenticationResult _authenticationResult; + private SaslServer _testSaslServer = mock(SaslServer.class); + private byte[] _saslResponseBytes = PASSWORD.getBytes(); + + @Override + public void setUp() + { + _authenticationResult = new AuthenticationResult(_userPrincipal); + when(_authenticationManager.authenticate(USERNAME, PASSWORD)).thenReturn(_authenticationResult); + + when(_groupPrincipalAccessor.getGroupPrincipals(USERNAME)) + .thenReturn(new HashSet<Principal>(Arrays.asList(_group1, _group2))); + } + + public void testAuthenticateUsernameAndPasswordReturnsSubjectWithUserAndGroupPrincipals() + { + final SubjectAuthenticationResult actualResult = _subjectCreator.authenticate(USERNAME, PASSWORD); + + assertEquals(AuthenticationStatus.SUCCESS, actualResult.getStatus()); + + final Subject actualSubject = actualResult.getSubject(); + + assertEquals("Should contain one user principal and two groups ", 3, actualSubject.getPrincipals().size()); + + assertTrue(actualSubject.getPrincipals().contains(new AuthenticatedPrincipal(_userPrincipal))); + assertTrue(actualSubject.getPrincipals().contains(_group1)); + assertTrue(actualSubject.getPrincipals().contains(_group2)); + + assertTrue(actualSubject.isReadOnly()); + } + + public void testSaslAuthenticationSuccessReturnsSubjectWithUserAndGroupPrincipals() throws Exception + { + when(_authenticationManager.authenticate(_testSaslServer, _saslResponseBytes)).thenReturn(_authenticationResult); + when(_testSaslServer.isComplete()).thenReturn(true); + when(_testSaslServer.getAuthorizationID()).thenReturn(USERNAME); + + SubjectAuthenticationResult result = _subjectCreator.authenticate(_testSaslServer, _saslResponseBytes); + + final Subject actualSubject = result.getSubject(); + assertEquals("Should contain one user principal and two groups ", 3, actualSubject.getPrincipals().size()); + + assertTrue(actualSubject.getPrincipals().contains(new AuthenticatedPrincipal(_userPrincipal))); + assertTrue(actualSubject.getPrincipals().contains(_group1)); + assertTrue(actualSubject.getPrincipals().contains(_group2)); + + assertTrue(actualSubject.isReadOnly()); + } + + public void testAuthenticateUnsuccessfulWithUsernameReturnsNullSubjectAndCorrectStatus() + { + testUnsuccessfulAuthentication(AuthenticationResult.AuthenticationStatus.CONTINUE); + testUnsuccessfulAuthentication(AuthenticationResult.AuthenticationStatus.ERROR); + } + + private void testUnsuccessfulAuthentication(AuthenticationStatus expectedStatus) + { + AuthenticationResult failedAuthenticationResult = new AuthenticationResult(expectedStatus); + + when(_authenticationManager.authenticate(USERNAME, PASSWORD)).thenReturn(failedAuthenticationResult); + + SubjectAuthenticationResult subjectAuthenticationResult = _subjectCreator.authenticate(USERNAME, PASSWORD); + + assertSame(expectedStatus, subjectAuthenticationResult.getStatus()); + assertNull(subjectAuthenticationResult.getSubject()); + } + + public void testAuthenticateUnsuccessfulWithSaslServerReturnsNullSubjectAndCorrectStatus() + { + testUnsuccessfulAuthenticationWithSaslServer(AuthenticationResult.AuthenticationStatus.CONTINUE); + testUnsuccessfulAuthenticationWithSaslServer(AuthenticationResult.AuthenticationStatus.ERROR); + } + + private void testUnsuccessfulAuthenticationWithSaslServer(AuthenticationStatus expectedStatus) + { + AuthenticationResult failedAuthenticationResult = new AuthenticationResult(expectedStatus); + + when(_authenticationManager.authenticate(_testSaslServer, _saslResponseBytes)).thenReturn(failedAuthenticationResult); + when(_testSaslServer.isComplete()).thenReturn(false); + + SubjectAuthenticationResult subjectAuthenticationResult = _subjectCreator.authenticate(_testSaslServer, _saslResponseBytes); + + assertSame(expectedStatus, subjectAuthenticationResult.getStatus()); + assertNull(subjectAuthenticationResult.getSubject()); + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTest.java new file mode 100644 index 0000000000..cd5791952f --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTest.java @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.security.auth; + +import java.security.Principal; + +import javax.security.auth.Subject; + +import org.apache.qpid.server.security.auth.UsernamePrincipal; + +import junit.framework.TestCase; + +public class AuthenticatedPrincipalTest extends TestCase +{ + + private AuthenticatedPrincipal _authenticatedPrincipal = new AuthenticatedPrincipal(new UsernamePrincipal("name")); + + public void testGetAuthenticatedPrincipalFromSubject() + { + final Subject subject = createSubjectContainingAuthenticatedPrincipal(); + final AuthenticatedPrincipal actual = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject); + assertSame(_authenticatedPrincipal, actual); + } + + public void testAuthenticatedPrincipalNotInSubject() + { + try + { + AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(new Subject()); + fail("Exception not thrown"); + } + catch (IllegalArgumentException iae) + { + // PASS + } + } + + public void testGetOptionalAuthenticatedPrincipalFromSubject() + { + final Subject subject = createSubjectContainingAuthenticatedPrincipal(); + final AuthenticatedPrincipal actual = AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(subject); + assertSame(_authenticatedPrincipal, actual); + } + + public void testGetOptionalAuthenticatedPrincipalFromSubjectReturnsNullIfMissing() + { + Subject subjectWithNoPrincipals = new Subject(); + assertNull(AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(subjectWithNoPrincipals)); + + Subject subjectWithoutAuthenticatedPrincipal = new Subject(); + subjectWithoutAuthenticatedPrincipal.getPrincipals().add(new UsernamePrincipal("name1")); + assertNull("Should return null for a subject containing a principal that isn't an AuthenticatedPrincipal", + AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(subjectWithoutAuthenticatedPrincipal)); + } + + public void testTooManyAuthenticatedPrincipalsInSubject() + { + final Subject subject = new Subject(); + subject.getPrincipals().add(new AuthenticatedPrincipal(new UsernamePrincipal("name1"))); + subject.getPrincipals().add(new AuthenticatedPrincipal(new UsernamePrincipal("name2"))); + + try + { + AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject); + fail("Exception not thrown"); + } + catch (IllegalArgumentException iae) + { + // PASS + } + } + + private Subject createSubjectContainingAuthenticatedPrincipal() + { + final Principal other = new Principal() + { + public String getName() + { + return "otherprincipal"; + } + }; + + final Subject subject = new Subject(); + subject.getPrincipals().add(_authenticatedPrincipal); + subject.getPrincipals().add(other); + return subject; + } + + public void testEqualsAndHashcode() + { + AuthenticatedPrincipal user1principal1 = new AuthenticatedPrincipal(new UsernamePrincipal("user1")); + AuthenticatedPrincipal user1principal2 = new AuthenticatedPrincipal(new UsernamePrincipal("user1")); + + assertTrue(user1principal1.equals(user1principal1)); + assertTrue(user1principal1.equals(user1principal2)); + assertTrue(user1principal2.equals(user1principal1)); + + assertEquals(user1principal1.hashCode(), user1principal2.hashCode()); + } + + public void testEqualsAndHashcodeWithSameWrappedObject() + { + UsernamePrincipal wrappedPrincipal = new UsernamePrincipal("user1"); + AuthenticatedPrincipal user1principal1 = new AuthenticatedPrincipal(wrappedPrincipal); + AuthenticatedPrincipal user1principal2 = new AuthenticatedPrincipal(wrappedPrincipal); + + assertTrue(user1principal1.equals(user1principal1)); + assertTrue(user1principal1.equals(user1principal2)); + assertTrue(user1principal2.equals(user1principal1)); + + assertEquals(user1principal1.hashCode(), user1principal2.hashCode()); + } + + public void testEqualsWithDifferentUsernames() + { + AuthenticatedPrincipal user1principal1 = new AuthenticatedPrincipal(new UsernamePrincipal("user1")); + AuthenticatedPrincipal user1principal2 = new AuthenticatedPrincipal(new UsernamePrincipal("user2")); + + assertFalse(user1principal1.equals(user1principal2)); + assertFalse(user1principal2.equals(user1principal1)); + } + + public void testEqualsWithDisimilarObjects() + { + UsernamePrincipal wrappedPrincipal = new UsernamePrincipal("user1"); + AuthenticatedPrincipal authenticatedPrincipal = new AuthenticatedPrincipal(wrappedPrincipal); + + assertFalse(authenticatedPrincipal.equals(wrappedPrincipal)); + assertFalse(wrappedPrincipal.equals(authenticatedPrincipal)); + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTestHelper.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTestHelper.java new file mode 100644 index 0000000000..e9d8d16fce --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTestHelper.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.security.auth; + +import java.security.Principal; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import junit.framework.Assert; + +/** + * Helper class for testing that sets of principals contain {@link AuthenticatedPrincipal}'s that wrap + * expected {@link Principal}'s. + */ +public class AuthenticatedPrincipalTestHelper +{ + public static void assertOnlyContainsWrapped(Principal wrappedPrincipal, Set<Principal> principals) + { + assertOnlyContainsWrappedAndSecondaryPrincipals(wrappedPrincipal, Collections.<Principal>emptySet(), principals); + } + + + public static void assertOnlyContainsWrappedAndSecondaryPrincipals( + Principal expectedWrappedPrincipal, + Set<Principal> expectedSecondaryPrincipals, + Set<Principal> actualPrincipals) + { + Assert.assertEquals("Principal set should contain one principal " + "but the principal set is: " + actualPrincipals, + 1 + expectedSecondaryPrincipals.size(), + actualPrincipals.size()); + + Set<Principal> expectedSet = new HashSet<Principal>(expectedSecondaryPrincipals); + expectedSet.add(new AuthenticatedPrincipal(expectedWrappedPrincipal)); + + Assert.assertEquals(expectedSet, actualPrincipals); + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java new file mode 100644 index 0000000000..a023cbdbb2 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.security.auth; + +import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrapped; +import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrappedAndSecondaryPrincipals; +import static org.mockito.Mockito.mock; + +import java.security.Principal; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import junit.framework.TestCase; + +public class AuthenticationResultTest extends TestCase +{ + public void testConstructWithAuthenticationStatusContinue() + { + AuthenticationResult authenticationResult = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.CONTINUE); + assertSame(AuthenticationResult.AuthenticationStatus.CONTINUE, authenticationResult.getStatus()); + assertTrue(authenticationResult.getPrincipals().isEmpty()); + } + + public void testConstructWithAuthenticationStatusError() + { + AuthenticationResult authenticationResult = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR); + assertSame(AuthenticationResult.AuthenticationStatus.ERROR, authenticationResult.getStatus()); + assertTrue(authenticationResult.getPrincipals().isEmpty()); + } + + public void testConstructWithAuthenticationStatusSuccessThrowsException() + { + try + { + new AuthenticationResult(AuthenticationResult.AuthenticationStatus.SUCCESS); + fail("Exception not thrown"); + } + catch(IllegalArgumentException e) + { + // PASS + } + } + + public void testConstructWithPrincipal() + { + Principal mainPrincipal = mock(Principal.class); + AuthenticationResult authenticationResult = new AuthenticationResult(mainPrincipal); + + assertOnlyContainsWrapped(mainPrincipal, authenticationResult.getPrincipals()); + assertSame(AuthenticationResult.AuthenticationStatus.SUCCESS, authenticationResult.getStatus()); + } + + public void testConstructWithNullPrincipalThrowsException() + { + try + { + new AuthenticationResult((Principal)null); + fail("Exception not thrown"); + } + catch(IllegalArgumentException e) + { + // pass + } + } + + public void testConstructWithSetOfPrincipals() + { + Principal mainPrincipal = mock(Principal.class); + Principal secondaryPrincipal = mock(Principal.class); + Set<Principal> secondaryPrincipals = Collections.singleton(secondaryPrincipal); + + AuthenticationResult authenticationResult = new AuthenticationResult(mainPrincipal, secondaryPrincipals); + + assertOnlyContainsWrappedAndSecondaryPrincipals(mainPrincipal, secondaryPrincipals, authenticationResult.getPrincipals()); + assertSame(AuthenticationResult.AuthenticationStatus.SUCCESS, authenticationResult.getStatus()); + } + + public void testConstructWithSetOfPrincipalsDeDuplicatesMainPrincipal() + { + Principal mainPrincipal = mock(Principal.class); + Principal secondaryPrincipal = mock(Principal.class); + + Set<Principal> secondaryPrincipalsContainingDuplicateOfMainPrincipal = new HashSet<Principal>( + Arrays.asList(secondaryPrincipal, mainPrincipal)); + Set<Principal> deDuplicatedSecondaryPrincipals = Collections.singleton(secondaryPrincipal); + + AuthenticationResult authenticationResult = new AuthenticationResult( + mainPrincipal, secondaryPrincipalsContainingDuplicateOfMainPrincipal); + + assertOnlyContainsWrappedAndSecondaryPrincipals(mainPrincipal, deDuplicatedSecondaryPrincipals, authenticationResult.getPrincipals()); + + assertSame(AuthenticationResult.AuthenticationStatus.SUCCESS, authenticationResult.getStatus()); + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/TestPrincipalUtils.java index 7ce03eaa79..ea6b40e3de 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/TestPrincipalUtils.java @@ -18,9 +18,12 @@ * under the License. * */ -package org.apache.qpid.server.security.auth.sasl; +package org.apache.qpid.server.security.auth; import javax.security.auth.Subject; + +import org.apache.qpid.server.security.group.GroupPrincipal; + import java.security.Principal; import java.util.Collections; import java.util.HashSet; @@ -28,21 +31,19 @@ import java.util.Set; public class TestPrincipalUtils { - /** - * Creates a test subject, with exactly one UsernamePrincipal and zero or more GroupPrincipals. + * Creates a test subject, with exactly one {@link AuthenticatedPrincipal} and zero or more GroupPrincipals. */ public static Subject createTestSubject(final String username, final String... groups) { final Set<Principal> principals = new HashSet<Principal>(1 + groups.length); - principals.add(new UsernamePrincipal(username)); + principals.add(new AuthenticatedPrincipal(username)); for (String group : groups) { principals.add(new GroupPrincipal(group)); } - - final Subject subject = new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET); - return subject; + + return new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET); } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/UsernamePrincipalTest.java index 75bc76c688..5e025d3ca8 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/UsernamePrincipalTest.java @@ -18,13 +18,10 @@ * under the License. * */ -package org.apache.qpid.server.security.auth.sasl; +package org.apache.qpid.server.security.auth; import junit.framework.TestCase; -import javax.security.auth.Subject; -import java.security.Principal; - /** * Tests the UsernamePrincipal. * @@ -70,54 +67,4 @@ public class UsernamePrincipalTest extends TestCase UsernamePrincipal principal = new UsernamePrincipal("string"); assertFalse(principal.equals(null)); } - - public void testGetUsernamePrincipalFromSubject() - { - final UsernamePrincipal expected = new UsernamePrincipal("name"); - final Principal other = new Principal() - { - public String getName() - { - return "otherprincipal"; - } - }; - - final Subject subject = new Subject(); - subject.getPrincipals().add(expected); - subject.getPrincipals().add(other); - - final UsernamePrincipal actual = UsernamePrincipal.getUsernamePrincipalFromSubject(subject); - assertSame(expected, actual); - } - - public void testUsernamePrincipalNotInSubject() - { - try - { - UsernamePrincipal.getUsernamePrincipalFromSubject(new Subject()); - fail("Exception not thrown"); - } - catch (IllegalArgumentException iae) - { - // PASS - } - } - - public void testTooManyUsernamePrincipalInSubject() - { - final Subject subject = new Subject(); - subject.getPrincipals().add(new UsernamePrincipal("name1")); - subject.getPrincipals().add(new UsernamePrincipal("name2")); - try - { - - UsernamePrincipal.getUsernamePrincipalFromSubject(subject); - fail("Exception not thrown"); - } - catch (IllegalArgumentException iae) - { - // PASS - } - } - } diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java index 33740af1e7..7b244e219e 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java @@ -23,7 +23,7 @@ package org.apache.qpid.server.security.auth.database; import junit.framework.TestCase; import org.apache.commons.codec.binary.Base64; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.login.AccountNotFoundException; diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java index b8601f0e5c..8e62324f7d 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java @@ -22,7 +22,7 @@ package org.apache.qpid.server.security.auth.database; import junit.framework.TestCase; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import javax.security.auth.login.AccountNotFoundException; import java.io.BufferedReader; diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java index 4203cb0e07..f670d80ae8 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java @@ -21,14 +21,13 @@ package org.apache.qpid.server.security.auth.database; import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser; import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.login.AccountNotFoundException; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.security.Principal; import java.util.HashMap; import java.util.LinkedList; @@ -123,22 +122,6 @@ public class PropertiesPrincipalDatabase implements PrincipalDatabase return equal; } - private char[] convertPassword(String password) throws UnsupportedEncodingException - { - byte[] passwdBytes = password.getBytes("utf-8"); - - char[] passwd = new char[passwdBytes.length]; - - int index = 0; - - for (byte b : passwdBytes) - { - passwd[index++] = (char) b; - } - - return passwd; - } - public Map<String, AuthenticationProviderInitialiser> getMechanisms() { @@ -166,4 +149,10 @@ public class PropertiesPrincipalDatabase implements PrincipalDatabase { //No file to update from, so do nothing. } + + @Override + public void setPasswordFile(String passwordFile) + { + throw new UnsupportedOperationException(); + } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java index 9dcd22c088..cfeb7c525b 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java @@ -20,26 +20,17 @@ */ package org.apache.qpid.server.security.auth.manager; +import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrapped; + import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.XMLConfiguration; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; + import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.test.utils.QpidTestCase; -public class AnonymousAuthenticationManagerTest extends InternalBrokerBaseCase +public class AnonymousAuthenticationManagerTest extends QpidTestCase { - - private AuthenticationManager _manager = null; - - public void setUp() throws Exception - { - _manager = AnonymousAuthenticationManager.INSTANCE; - } - + private AuthenticationManager _manager = new AnonymousAuthenticationManager(); public void tearDown() throws Exception { @@ -49,29 +40,6 @@ public class AnonymousAuthenticationManagerTest extends InternalBrokerBaseCase } } - private ConfigurationPlugin getPlainDatabaseConfig() throws ConfigurationException - { - final ConfigurationPlugin config = new PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - xmlconfig.addProperty("pd-auth-manager.principal-database.class", PlainPasswordFilePrincipalDatabase.class.getName()); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - config.setConfiguration("security", xmlconfig); - return config; - } - - - public void testConfiguration() throws Exception - { - AuthenticationManager authenticationManager = - AnonymousAuthenticationManager.FACTORY.newInstance(getPlainDatabaseConfig()); - - assertNull("AnonymousAuthenticationManager unexpectedly created when not in config", authenticationManager); - } - public void testGetMechanisms() throws Exception { assertEquals("ANONYMOUS", _manager.getMechanisms()); @@ -102,7 +70,8 @@ public class AnonymousAuthenticationManagerTest extends InternalBrokerBaseCase assertEquals("Expected authentication to be successful", AuthenticationResult.AuthenticationStatus.SUCCESS, result.getStatus()); - assertNotNull("Subject should not be null", result.getSubject()); + + assertOnlyContainsWrapped(AnonymousAuthenticationManager.ANONYMOUS_PRINCIPAL, result.getPrincipals()); } diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistryTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistryTest.java deleted file mode 100644 index efb8df3a38..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistryTest.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * 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.security.auth.manager; - -import static org.mockito.Mockito.*; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.commons.configuration.ConfigurationException; -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.plugins.Plugin; -import org.apache.qpid.server.plugins.PluginManager; -import org.apache.qpid.server.security.SecurityManager.SecurityConfiguration; -import org.mockito.Mockito; - -import junit.framework.TestCase; - -public class AuthenticationManagerRegistryTest extends TestCase -{ - private static final Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> EMPTY_PLUGINMAP = Collections.emptyMap(); - - private PluginManager _pluginManager = Mockito.mock(PluginManager.class); - private ServerConfiguration _serverConfiguration = Mockito.mock(ServerConfiguration.class); - private SecurityConfiguration _securityConfiguration = Mockito.mock(SecurityConfiguration.class); - - private List<AuthenticationManager> _allCreatedAuthManagers = new ArrayList<AuthenticationManager>(); - - @Override - protected void setUp() throws Exception - { - super.setUp(); - - // Setup server configuration to return mock security config. - when(_serverConfiguration.getConfiguration(SecurityConfiguration.class.getName())).thenReturn(_securityConfiguration); - } - - @Override - protected void tearDown() throws Exception - { - try - { - verifyAllCreatedAuthManagersClosed(); - } - finally - { - super.tearDown(); - } - } - - public void testNoAuthenticationManagerFactoryPluginsFound() throws Exception - { - when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(EMPTY_PLUGINMAP); - try - { - new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager); - fail("Exception not thrown"); - } - catch (ConfigurationException ce) - { - // PASS - assertEquals("No authentication manager factory plugins found. Check the desired authentication manager plugin has been placed in the plugins directory.", - ce.getMessage()); - } - } - - public void testSameAuthenticationManagerSpecifiedTwice() throws Exception - { - AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class); - - Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory, myAuthManagerFactory); - - when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap); - - try - { - new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager); - fail("Exception not thrown"); - } - catch (ConfigurationException ce) - { - // PASS - assertEquals("Cannot configure more than one authentication manager of type " + myAuthManagerFactory.getPluginClass().getSimpleName() + ". Remove configuration for one of the authentication managers.", - ce.getMessage()); - } - } - - public void testMultipleAuthenticationManagersSpecifiedButNoDefaultSpecified() throws Exception - { - AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory1 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class); - AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory2 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager2.class); - - Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory1, myAuthManagerFactory2); - - when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap); - when(_serverConfiguration.getDefaultAuthenticationManager()).thenReturn(null); - - try - { - new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager); - fail("Exception not thrown"); - } - catch (ConfigurationException ce) - { - // PASS - assertEquals("If more than one authentication manager is configured a default MUST be specified.", - ce.getMessage()); - } - } - - public void testDefaultAuthenticationManagerNotKnown() throws Exception - { - String myDefaultAuthManagerSimpleClassName = "UnknownAuthenticationManager"; - - AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory1 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class); - AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory2 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager2.class); - - Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory1, myAuthManagerFactory2); - - when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap); - when(_serverConfiguration.getDefaultAuthenticationManager()).thenReturn(myDefaultAuthManagerSimpleClassName); - - try - { - new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager); - fail("Exception not thrown"); - } - catch (ConfigurationException ce) - { - // PASS - assertTrue("Unexpected message " + ce.getMessage(), - ce.getMessage().startsWith("No authentication managers configured of type " + myDefaultAuthManagerSimpleClassName + " which is specified as the default")); - } - } - - public void testPortMappedToUnknownAuthenticationManager() throws Exception - { - String myDefaultAuthManagerSimpleClassName = "UnknownAuthenticationManager"; - int portNumber = 1234; - - AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory1 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class); - - Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory1); - - when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap); - when(_serverConfiguration.getPortAuthenticationMappings()).thenReturn(Collections.singletonMap(portNumber, myDefaultAuthManagerSimpleClassName)); - - try - { - new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager); - fail("Exception not thrown"); - } - catch (ConfigurationException ce) - { - // PASS - assertEquals("Unknown authentication manager class " + myDefaultAuthManagerSimpleClassName + " configured for port " + portNumber, ce.getMessage()); - } - } - - public void testGetAuthenticationManagerForInetSocketAddress() throws Exception - { - AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory1 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class); - Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory1); - - when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap); - - AuthenticationManagerRegistry registry = new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager); - - AuthenticationManager authenticationManager = registry.getAuthenticationManager(new InetSocketAddress(1234)); - assertEquals("TestAuthenticationManager1", authenticationManager.getMechanisms()); - - registry.close(); - } - - public void testGetAuthenticationManagerForNonInetSocketAddress() throws Exception - { - AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory1 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class); - Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory1); - - when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap); - - AuthenticationManagerRegistry registry = new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager); - - AuthenticationManager authenticationManager = registry.getAuthenticationManager(mock(SocketAddress.class)); - assertEquals("TestAuthenticationManager1", authenticationManager.getMechanisms()); - - registry.close(); - } - - public void testGetAuthenticationManagerWithMultipleAuthenticationManager() throws Exception - { - AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory1 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class); - AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory2 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager2.class); - Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory1, myAuthManagerFactory2); - - String defaultAuthManger = myAuthManagerFactory1.getPluginName(); - int unmappedPortNumber = 1234; - int mappedPortNumber = 1235; - String mappedAuthManager = myAuthManagerFactory2.getPluginName(); - - when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap); - when(_serverConfiguration.getDefaultAuthenticationManager()).thenReturn(defaultAuthManger); - when(_serverConfiguration.getPortAuthenticationMappings()).thenReturn(Collections.singletonMap(mappedPortNumber, mappedAuthManager)); - - AuthenticationManagerRegistry registry = new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager); - - AuthenticationManager authenticationManager1 = registry.getAuthenticationManager(new InetSocketAddress(unmappedPortNumber)); - assertEquals("TestAuthenticationManager1", authenticationManager1.getMechanisms()); - - AuthenticationManager authenticationManager2 = registry.getAuthenticationManager(new InetSocketAddress(mappedPortNumber)); - assertEquals("TestAuthenticationManager2", authenticationManager2.getMechanisms()); - - registry.close(); - } - - public void testAuthenticationManagersAreClosed() throws Exception - { - AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory1 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class); - AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory2 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager2.class); - Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory1, myAuthManagerFactory2); - - String defaultAuthManger = myAuthManagerFactory1.getPluginName(); - when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap); - when(_serverConfiguration.getDefaultAuthenticationManager()).thenReturn(defaultAuthManger); - - AuthenticationManagerRegistry registry = new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager); - - registry.close(); - } - - private AuthenticationManagerPluginFactory<? extends Plugin> newMockFactoryProducingMockAuthManagerImplementing(Class<? extends AuthenticationManager> authManagerClazz) - throws ConfigurationException - { - AuthenticationManager myAuthManager = mock(authManagerClazz); - when(myAuthManager.getMechanisms()).thenReturn(authManagerClazz.getSimpleName()); // used to verify the getAuthenticationManagerFor returns expected impl. - - AuthenticationManagerPluginFactory myAuthManagerFactory = mock(AuthenticationManagerPluginFactory.class); - when(myAuthManagerFactory.getPluginClass()).thenReturn(myAuthManager.getClass()); - when(myAuthManagerFactory.getPluginName()).thenReturn(myAuthManager.getClass().getSimpleName()); - when(myAuthManagerFactory.newInstance(_securityConfiguration)).thenReturn(myAuthManager); - - _allCreatedAuthManagers.add(myAuthManager); - return myAuthManagerFactory; - } - - private Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> createPluginMap( - AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory) - { - return createPluginMap(myAuthManagerFactory, null); - } - - private Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> createPluginMap( - AuthenticationManagerPluginFactory<? extends Plugin> authManagerFactory1, - AuthenticationManagerPluginFactory<? extends Plugin> authManagerFactory2) - { - Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = new HashMap<String, AuthenticationManagerPluginFactory<? extends Plugin>>(); - pluginMap.put("config.path.unused1", authManagerFactory1); - if (authManagerFactory2 != null) - { - pluginMap.put("config.path.unused2", authManagerFactory2); - } - return pluginMap; - } - - private void verifyAllCreatedAuthManagersClosed() - { - for (Iterator<AuthenticationManager> iterator = _allCreatedAuthManagers.iterator(); iterator.hasNext();) - { - AuthenticationManager authenticationManager = (AuthenticationManager) iterator.next(); - verify(authenticationManager).close(); - } - } - - private interface TestAuthenticationManager1 extends AuthenticationManager - { - } - - private interface TestAuthenticationManager2 extends AuthenticationManager - { - } -} diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactoryTest.java new file mode 100644 index 0000000000..04e09e073f --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactoryTest.java @@ -0,0 +1,111 @@ +/* + * 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.security.auth.manager; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; +import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase; + +public class Base64MD5PasswordFileAuthenticationManagerFactoryTest extends TestCase +{ + AuthenticationManagerFactory _factory = new Base64MD5PasswordFileAuthenticationManagerFactory(); + private Map<String, Object> _configuration = new HashMap<String, Object>(); + private File _emptyPasswordFile; + + @Override + protected void setUp() throws Exception + { + super.setUp(); + _emptyPasswordFile = File.createTempFile(getName(), "passwd"); + _emptyPasswordFile.deleteOnExit(); + } + + public void testBase64MD5InstanceCreated() throws Exception + { + _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, Base64MD5PasswordFileAuthenticationManagerFactory.PROVIDER_TYPE); + _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _emptyPasswordFile.getAbsolutePath()); + + AuthenticationManager manager = _factory.createInstance(_configuration); + assertNotNull(manager); + assertTrue(manager instanceof PrincipalDatabaseAuthenticationManager); + assertTrue(((PrincipalDatabaseAuthenticationManager)manager).getPrincipalDatabase() instanceof Base64MD5PasswordFilePrincipalDatabase); + } + + public void testPasswordFileNotFound() throws Exception + { + //delete the file + _emptyPasswordFile.delete(); + + _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, Base64MD5PasswordFileAuthenticationManagerFactory.PROVIDER_TYPE); + _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _emptyPasswordFile.getAbsolutePath()); + + try + { + _factory.createInstance(_configuration); + } + catch (RuntimeException re) + { + assertTrue(re.getCause() instanceof FileNotFoundException); + } + } + + public void testReturnsNullWhenNoConfig() throws Exception + { + AuthenticationManager manager = _factory.createInstance(_configuration); + assertNull(manager); + } + + public void testReturnsNullWhenConfigForOtherAuthManagerType() throws Exception + { + _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, "other-auth-manager"); + AuthenticationManager manager = _factory.createInstance(_configuration); + assertNull(manager); + } + + public void testReturnsNullWhenConfigForPlainPDImplementationNoPasswordFileValueSpecified() throws Exception + { + _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, Base64MD5PasswordFileAuthenticationManagerFactory.PROVIDER_TYPE); + + AuthenticationManager manager = _factory.createInstance(_configuration); + assertNull(manager); + } + + @Override + protected void tearDown() throws Exception + { + try + { + if (_emptyPasswordFile == null && _emptyPasswordFile.exists()) + { + _emptyPasswordFile.delete(); + } + } + finally + { + super.tearDown(); + } + } +}
\ No newline at end of file diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java index c1a55ef2ad..a66d73c47d 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java @@ -18,58 +18,18 @@ */ package org.apache.qpid.server.security.auth.manager; +import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrapped; + import javax.security.auth.x500.X500Principal; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.XMLConfiguration; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; + import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.test.utils.QpidTestCase; -public class ExternalAuthenticationManagerTest extends InternalBrokerBaseCase +public class ExternalAuthenticationManagerTest extends QpidTestCase { - - private AuthenticationManager _manager = null; - - public void setUp() throws Exception - { - _manager = ExternalAuthenticationManager.INSTANCE; - } - - - public void tearDown() throws Exception - { - if(_manager != null) - { - _manager = null; - } - } - - private ConfigurationPlugin getPlainDatabaseConfig() throws ConfigurationException - { - final ConfigurationPlugin config = new PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - xmlconfig.addProperty("pd-auth-manager.principal-database.class", PlainPasswordFilePrincipalDatabase.class.getName()); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - config.setConfiguration("security", xmlconfig); - return config; - } - - - public void testConfiguration() throws Exception - { - AuthenticationManager authenticationManager = - ExternalAuthenticationManager.FACTORY.newInstance(getPlainDatabaseConfig()); - - assertNull("ExternalAuthenticationManager unexpectedly created when not in config", authenticationManager); - } + private AuthenticationManager _manager = new ExternalAuthenticationManager(); public void testGetMechanisms() throws Exception { @@ -103,12 +63,12 @@ public class ExternalAuthenticationManagerTest extends InternalBrokerBaseCase assertEquals("Expected authentication to be successful", AuthenticationResult.AuthenticationStatus.SUCCESS, result.getStatus()); - assertEquals("Expected principal to be unchanged", - principal, - result.getSubject().getPrincipals().iterator().next()); + + assertOnlyContainsWrapped(principal, result.getPrincipals()); saslServer = _manager.createSaslServer("EXTERNAL", "example.example.com", null); result = _manager.authenticate(saslServer, new byte[0]); + assertNotNull(result); assertEquals("Expected authentication to be unsuccessful", AuthenticationResult.AuthenticationStatus.ERROR, diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactoryTest.java new file mode 100644 index 0000000000..d428f8b211 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactoryTest.java @@ -0,0 +1,111 @@ +/* + * 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.security.auth.manager; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; +import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase; + +public class PlainPasswordFileAuthenticationManagerFactoryTest extends TestCase +{ + AuthenticationManagerFactory _factory = new PlainPasswordFileAuthenticationManagerFactory(); + private Map<String, Object> _configuration = new HashMap<String, Object>(); + private File _emptyPasswordFile; + + @Override + protected void setUp() throws Exception + { + super.setUp(); + _emptyPasswordFile = File.createTempFile(getName(), "passwd"); + _emptyPasswordFile.deleteOnExit(); + } + + public void testPlainInstanceCreated() throws Exception + { + _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE); + _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _emptyPasswordFile.getAbsolutePath()); + + AuthenticationManager manager = _factory.createInstance(_configuration); + assertNotNull(manager); + assertTrue(manager instanceof PrincipalDatabaseAuthenticationManager); + assertTrue(((PrincipalDatabaseAuthenticationManager)manager).getPrincipalDatabase() instanceof PlainPasswordFilePrincipalDatabase); + } + + public void testPasswordFileNotFound() throws Exception + { + //delete the file + _emptyPasswordFile.delete(); + + _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE); + _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _emptyPasswordFile.getAbsolutePath()); + + try + { + _factory.createInstance(_configuration); + } + catch (RuntimeException re) + { + assertTrue(re.getCause() instanceof FileNotFoundException); + } + } + + public void testReturnsNullWhenNoConfig() throws Exception + { + AuthenticationManager manager = _factory.createInstance(_configuration); + assertNull(manager); + } + + public void testReturnsNullWhenConfigForOtherAuthManagerType() throws Exception + { + _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, "other-auth-manager"); + AuthenticationManager manager = _factory.createInstance(_configuration); + assertNull(manager); + } + + public void testReturnsNullWhenConfigForPlainPDImplementationNoPasswordFileValueSpecified() throws Exception + { + _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE); + + AuthenticationManager manager = _factory.createInstance(_configuration); + assertNull(manager); + } + + @Override + protected void tearDown() throws Exception + { + try + { + if (_emptyPasswordFile == null && _emptyPasswordFile.exists()) + { + _emptyPasswordFile.delete(); + } + } + finally + { + super.tearDown(); + } + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java index 47c189e4fa..1ae667804a 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java @@ -20,132 +20,92 @@ */ package org.apache.qpid.server.security.auth.manager; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.XMLConfiguration; +import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrapped; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; -import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import java.security.Provider; +import java.security.Security; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; -import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileWriter; -import java.security.Provider; -import java.security.Security; +import javax.security.sasl.SaslServerFactory; + +import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; +import org.apache.qpid.server.security.auth.UsernamePrincipal; +import org.apache.qpid.server.security.auth.database.PrincipalDatabase; +import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser; +import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser; +import org.apache.qpid.test.utils.QpidTestCase; /** - * * Tests the public methods of PrincipalDatabaseAuthenticationManager. * */ -public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBaseCase +public class PrincipalDatabaseAuthenticationManagerTest extends QpidTestCase { + private static final String MOCK_MECH_NAME = "MOCK-MECH-NAME"; + private static final UsernamePrincipal PRINCIPAL = new UsernamePrincipal("guest"); + private AuthenticationManager _manager = null; // Class under test - private String TEST_USERNAME = "guest"; - private String TEST_PASSWORD = "guest"; + private PrincipalDatabase _principalDatabase; - /** - * @see org.apache.qpid.server.util.InternalBrokerBaseCase#tearDown() - */ @Override public void tearDown() throws Exception { - super.tearDown(); if (_manager != null) { _manager.close(); } + super.tearDown(); } - /** - * @see org.apache.qpid.server.util.InternalBrokerBaseCase#setUp() - */ - @Override - public void setUp() throws Exception + private void setupMocks() throws Exception { - super.setUp(); - - final String passwdFilename = createPasswordFile().getCanonicalPath(); - final ConfigurationPlugin config = getConfig(PlainPasswordFilePrincipalDatabase.class.getName(), - "passwordFile", passwdFilename); + _principalDatabase = mock(PrincipalDatabase.class); - _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(config); - } + AuthenticationProviderInitialiser _mockMechInitialiser = mock(AuthenticationProviderInitialiser.class); + Map<String, AuthenticationProviderInitialiser> _initialisers = Collections.singletonMap(MOCK_MECH_NAME, _mockMechInitialiser); - /** - * Tests where the case where the config specifies a PD implementation - * that is not found. - */ - public void testPrincipalDatabaseImplementationNotFound() throws Exception - { - try - { - _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(getConfig("not.Found", null, null)); - fail("Exception not thrown"); - } - catch (ConfigurationException ce) - { - // PASS - } - } + when(_principalDatabase.getMechanisms()).thenReturn(_initialisers); - /** - * Tests where the case where the config specifies a PD implementation - * of the wrong type. - */ - public void testPrincipalDatabaseImplementationWrongType() throws Exception - { - try - { - _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(getConfig(String.class.getName(), null, null)); // Not a PrincipalDatabase implementation - fail("Exception not thrown"); - } - catch (ConfigurationException ce) - { - // PASS - } + _manager = new PrincipalDatabaseAuthenticationManager(_principalDatabase); + _manager.initialise(); } - /** - * Tests the case where a setter with the desired name cannot be found. - */ - public void testPrincipalDatabaseSetterNotFound() throws Exception + private void setupMocksWithInitialiser() throws Exception { - try - { - _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(getConfig(PlainPasswordFilePrincipalDatabase.class.getName(), "noMethod", "test")); - fail("Exception not thrown"); - } - catch (ConfigurationException ce) - { - // PASS - } - } + _principalDatabase = mock(PrincipalDatabase.class); - /** - * QPID-1347. Make sure the exception message and stack trace is reasonable for an absent password file. - */ - public void testPrincipalDatabaseThrowsSetterFileNotFound() throws Exception - { - try - { - _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(getConfig(PlainPasswordFilePrincipalDatabase.class.getName(), "passwordFile", "/not/found")); - fail("Exception not thrown"); - } - catch (ConfigurationException ce) + UsernamePasswordInitialiser usernamePasswordInitialiser = new UsernamePasswordInitialiser() { - // PASS - assertNotNull("Expected an underlying cause", ce.getCause()); - assertEquals(FileNotFoundException.class, ce.getCause().getClass()); - } + @Override + public Class<? extends SaslServerFactory> getServerFactoryClassForJCARegistration() + { + return MySaslServerFactory.class; + } + + @Override + public String getMechanismName() + { + return MOCK_MECH_NAME; + } + }; + + Map<String,AuthenticationProviderInitialiser> initialisers = new HashMap<String, AuthenticationProviderInitialiser>(); + initialisers.put(MOCK_MECH_NAME, usernamePasswordInitialiser); + + when(_principalDatabase.getMechanisms()).thenReturn(initialisers); + + usernamePasswordInitialiser.initialise(_principalDatabase); + + _manager = new PrincipalDatabaseAuthenticationManager(_principalDatabase); + _manager.initialise(); } /** @@ -153,11 +113,16 @@ public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBa */ public void testRegisteredMechanisms() throws Exception { + //Ensure we haven't registered anything yet (though this would really indicate a prior test failure!) + Provider qpidProvider = Security.getProvider(AuthenticationManager.PROVIDER_NAME); + assertNull(qpidProvider); + + setupMocksWithInitialiser(); + assertNotNull(_manager.getMechanisms()); - // relies on those mechanisms attached to PropertiesPrincipalDatabaseManager - assertEquals("AMQPLAIN PLAIN CRAM-MD5", _manager.getMechanisms()); + assertEquals(MOCK_MECH_NAME, _manager.getMechanisms()); - Provider qpidProvider = Security.getProvider(PrincipalDatabaseAuthenticationManager.PROVIDER_NAME); + qpidProvider = Security.getProvider(AuthenticationManager.PROVIDER_NAME); assertNotNull(qpidProvider); } @@ -167,96 +132,103 @@ public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBa */ public void testSaslMechanismCreation() throws Exception { - SaslServer server = _manager.createSaslServer("CRAM-MD5", "localhost", null); + setupMocksWithInitialiser(); + + SaslServer server = _manager.createSaslServer(MOCK_MECH_NAME, "localhost", null); assertNotNull(server); // Merely tests the creation of the mechanism. Mechanisms themselves are tested // by their own tests. } - + /** * Tests that the authenticate method correctly interprets an * authentication success. - * + * */ public void testSaslAuthenticationSuccess() throws Exception { + setupMocks(); + SaslServer testServer = createTestSaslServer(true, false); - + AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes()); - final Subject subject = result.getSubject(); - assertTrue(subject.getPrincipals().contains(new UsernamePrincipal("guest"))); + + assertOnlyContainsWrapped(PRINCIPAL, result.getPrincipals()); assertEquals(AuthenticationStatus.SUCCESS, result.getStatus()); } /** - * + * * Tests that the authenticate method correctly interprets an * authentication not complete. - * + * */ public void testSaslAuthenticationNotCompleted() throws Exception { + setupMocks(); + SaslServer testServer = createTestSaslServer(false, false); - + AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes()); - assertNull(result.getSubject()); + assertEquals("Principals was not expected size", 0, result.getPrincipals().size()); + assertEquals(AuthenticationStatus.CONTINUE, result.getStatus()); } /** - * + * * Tests that the authenticate method correctly interprets an * authentication error. - * + * */ public void testSaslAuthenticationError() throws Exception { + setupMocks(); + SaslServer testServer = createTestSaslServer(false, true); - + AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes()); - assertNull(result.getSubject()); + assertEquals("Principals was not expected size", 0, result.getPrincipals().size()); assertEquals(AuthenticationStatus.ERROR, result.getStatus()); } - /** - * Tests that the authenticate method correctly interprets an - * authentication success. - * - */ public void testNonSaslAuthenticationSuccess() throws Exception { + setupMocks(); + + when(_principalDatabase.verifyPassword("guest", "guest".toCharArray())).thenReturn(true); + AuthenticationResult result = _manager.authenticate("guest", "guest"); - final Subject subject = result.getSubject(); - assertFalse("Subject should not be set read-only", subject.isReadOnly()); - assertTrue(subject.getPrincipals().contains(new UsernamePrincipal("guest"))); + assertOnlyContainsWrapped(PRINCIPAL, result.getPrincipals()); assertEquals(AuthenticationStatus.SUCCESS, result.getStatus()); } - /** - * Tests that the authenticate method correctly interprets an - * authentication success. - * - */ public void testNonSaslAuthenticationNotCompleted() throws Exception { + setupMocks(); + + when(_principalDatabase.verifyPassword("guest", "wrongpassword".toCharArray())).thenReturn(false); + AuthenticationResult result = _manager.authenticate("guest", "wrongpassword"); - assertNull(result.getSubject()); + assertEquals("Principals was not expected size", 0, result.getPrincipals().size()); assertEquals(AuthenticationStatus.CONTINUE, result.getStatus()); } - + /** * Tests the ability to de-register the provider. */ public void testClose() throws Exception { - assertEquals("AMQPLAIN PLAIN CRAM-MD5", _manager.getMechanisms()); - assertNotNull(Security.getProvider(PrincipalDatabaseAuthenticationManager.PROVIDER_NAME)); + setupMocksWithInitialiser(); + + assertEquals(MOCK_MECH_NAME, _manager.getMechanisms()); + assertNotNull(Security.getProvider(AuthenticationManager.PROVIDER_NAME)); _manager.close(); // Check provider has been removed. assertNull(_manager.getMechanisms()); - assertNull(Security.getProvider(PrincipalDatabaseAuthenticationManager.PROVIDER_NAME)); + assertNull(Security.getProvider(AuthenticationManager.PROVIDER_NAME)); _manager = null; } @@ -265,94 +237,90 @@ public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBa */ private SaslServer createTestSaslServer(final boolean complete, final boolean throwSaslException) { - return new SaslServer() - { - public String getMechanismName() - { - return null; - } + return new MySaslServer(throwSaslException, complete); + } - public byte[] evaluateResponse(byte[] response) throws SaslException - { - if (throwSaslException) - { - throw new SaslException("Mocked exception"); - } - return null; - } + public static final class MySaslServer implements SaslServer + { + private final boolean _throwSaslException; + private final boolean _complete; - public boolean isComplete() - { - return complete; - } + public MySaslServer() + { + this(false, true); + } - public String getAuthorizationID() - { - return complete ? "guest" : null; - } + private MySaslServer(boolean throwSaslException, boolean complete) + { + _throwSaslException = throwSaslException; + _complete = complete; + } - public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException - { - return null; - } + public String getMechanismName() + { + return null; + } - public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException + public byte[] evaluateResponse(byte[] response) throws SaslException + { + if (_throwSaslException) { - return null; + throw new SaslException("Mocked exception"); } + return null; + } - public Object getNegotiatedProperty(String propName) - { - return null; - } + public boolean isComplete() + { + return _complete; + } - public void dispose() throws SaslException - { - } - }; - } + public String getAuthorizationID() + { + return _complete ? "guest" : null; + } - private ConfigurationPlugin getConfig(final String clazz, final String argName, final String argValue) throws Exception - { - final ConfigurationPlugin config = new PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration(); + public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException + { + return null; + } - XMLConfiguration xmlconfig = new XMLConfiguration(); - xmlconfig.addProperty("pd-auth-manager.principal-database.class", clazz); + public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException + { + return null; + } - if (argName != null) + public Object getNegotiatedProperty(String propName) { - xmlconfig.addProperty("pd-auth-manager.principal-database.attributes.attribute.name", argName); - xmlconfig.addProperty("pd-auth-manager.principal-database.attributes.attribute.value", argValue); + return null; } - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - config.setConfiguration("security", xmlconfig); - return config; + public void dispose() throws SaslException + { + } } - private File createPasswordFile() throws Exception + public static class MySaslServerFactory implements SaslServerFactory { - BufferedWriter writer = null; - try - { - File testFile = File.createTempFile(this.getClass().getName(),"tmp"); - testFile.deleteOnExit(); - - writer = new BufferedWriter(new FileWriter(testFile)); - writer.write(TEST_USERNAME + ":" + TEST_PASSWORD); - writer.newLine(); - - return testFile; - - } - finally + @Override + public SaslServer createSaslServer(String mechanism, String protocol, + String serverName, Map<String, ?> props, CallbackHandler cbh) + throws SaslException { - if (writer != null) + if (MOCK_MECH_NAME.equals(mechanism)) { - writer.close(); + return new MySaslServer(); } + else + { + return null; + } + } + + @Override + public String[] getMechanismNames(Map<String, ?> props) + { + return new String[]{MOCK_MECH_NAME}; } } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java new file mode 100644 index 0000000000..1424bee611 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth.manager; + +import java.util.HashMap; +import java.util.Map; + + +import junit.framework.TestCase; + +public class SimpleLDAPAuthenticationManagerFactoryTest extends TestCase +{ + private SimpleLDAPAuthenticationManagerFactory _factory = new SimpleLDAPAuthenticationManagerFactory(); + private Map<String, Object> _configuration = new HashMap<String, Object>(); + + public void testInstanceCreated() throws Exception + { + _configuration.put(SimpleLDAPAuthenticationManagerFactory.ATTRIBUTE_TYPE, SimpleLDAPAuthenticationManagerFactory.PROVIDER_TYPE); + _configuration.put("providerUrl", "ldaps://example.com:636/"); + _configuration.put("searchContext", "dc=example"); + + AuthenticationManager manager = _factory.createInstance(_configuration); + assertNotNull(manager); + } + + public void testReturnsNullWhenNoConfig() throws Exception + { + AuthenticationManager manager = _factory.createInstance(_configuration); + assertNull(manager); + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java index c0c55de92a..52b525dd80 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java @@ -20,20 +20,26 @@ */ package org.apache.qpid.server.security.auth.rmi; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.security.Principal; +import java.util.regex.Pattern; + +import javax.security.auth.Subject; + import junit.framework.TestCase; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.auth.AuthenticationResult; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; - -import javax.management.remote.JMXPrincipal; -import javax.security.auth.Subject; -import javax.security.sasl.SaslException; -import javax.security.sasl.SaslServer; -import java.net.InetSocketAddress; -import java.util.Collections; +import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; +import org.apache.qpid.server.security.SecurityManager; /** * Tests the RMIPasswordAuthenticator and its collaboration with the AuthenticationManager. @@ -41,36 +47,35 @@ import java.util.Collections; */ public class RMIPasswordAuthenticatorTest extends TestCase { - private final String USERNAME = "guest"; - private final String PASSWORD = "guest"; + private static final String USERNAME = "guest"; + private static final String PASSWORD = "password"; + + private final Broker _broker = mock(Broker.class); + private final SecurityManager _securityManager = mock(SecurityManager.class); + private final Subject _loginSubject = new Subject(); + private final String[] _credentials = new String[] {USERNAME, PASSWORD}; + private RMIPasswordAuthenticator _rmipa; - private String[] _credentials; + + private SubjectCreator _usernamePasswordOkaySuvjectCreator = createMockSubjectCreator(true, null); + private SubjectCreator _badPasswordSubjectCreator = createMockSubjectCreator(false, null); protected void setUp() throws Exception { - _rmipa = new RMIPasswordAuthenticator(new InetSocketAddress(5672)); - - _credentials = new String[] {USERNAME, PASSWORD}; + when(_broker.getSecurityManager()).thenReturn(_securityManager); + _rmipa = new RMIPasswordAuthenticator(_broker, new InetSocketAddress(8999)); } /** - * Tests a successful authentication. Ensures that a populated read-only subject it returned. + * Tests a successful authentication. Ensures that the expected subject is returned. */ public void testAuthenticationSuccess() { - final Subject expectedSubject = new Subject(true, - Collections.singleton(new JMXPrincipal(USERNAME)), - Collections.EMPTY_SET, - Collections.EMPTY_SET); - - _rmipa.setAuthenticationManager(createTestAuthenticationManager(true, null)); - + when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(_usernamePasswordOkaySuvjectCreator); + when(_securityManager.accessManagement()).thenReturn(true); Subject newSubject = _rmipa.authenticate(_credentials); - assertTrue("Subject must be readonly", newSubject.isReadOnly()); - assertTrue("Returned subject does not equal expected value", - newSubject.equals(expectedSubject)); - + assertSame("Subject must be unchanged", _loginSubject, newSubject); } /** @@ -78,7 +83,7 @@ public class RMIPasswordAuthenticatorTest extends TestCase */ public void testUsernameOrPasswordInvalid() { - _rmipa.setAuthenticationManager(createTestAuthenticationManager(false, null)); + when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(_badPasswordSubjectCreator); try { @@ -89,17 +94,31 @@ public class RMIPasswordAuthenticatorTest extends TestCase { assertEquals("Unexpected exception message", RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage()); + } + } + + public void testAuthorisationFailure() + { + when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(_usernamePasswordOkaySuvjectCreator); + when(_securityManager.accessManagement()).thenReturn(false); + try + { + _rmipa.authenticate(_credentials); + fail("Exception not thrown"); + } + catch (SecurityException se) + { + assertEquals("Unexpected exception message", + RMIPasswordAuthenticator.USER_NOT_AUTHORISED_FOR_MANAGEMENT, se.getMessage()); } } - /** - * Tests case where authentication system itself fails. - */ - public void testAuthenticationFailure() + public void testSubjectCreatorInternalFailure() { final Exception mockAuthException = new Exception("Mock Auth system failure"); - _rmipa.setAuthenticationManager(createTestAuthenticationManager(false, mockAuthException)); + SubjectCreator subjectCreator = createMockSubjectCreator(false, mockAuthException); + when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(subjectCreator); try { @@ -112,13 +131,13 @@ public class RMIPasswordAuthenticatorTest extends TestCase } } - /** * Tests case where authentication manager is not set. */ - public void testNullAuthenticationManager() throws Exception + public void testNullSubjectCreator() throws Exception { - _rmipa.setAuthenticationManager(null); + when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(null); + try { _rmipa.authenticate(_credentials); @@ -126,8 +145,7 @@ public class RMIPasswordAuthenticatorTest extends TestCase } catch (SecurityException se) { - assertEquals("Unexpected exception message", - RMIPasswordAuthenticator.UNABLE_TO_LOOKUP, se.getMessage()); + assertTrue("Unexpected exception message", Pattern.matches("Can't get subject creator for .*:8999", se.getMessage())); } } @@ -155,11 +173,13 @@ public class RMIPasswordAuthenticatorTest extends TestCase */ public void testWithIllegalNumberOfArguments() { + String[] credentials; + // Test handling of incorrect number of credentials try { - _credentials = new String[]{USERNAME, PASSWORD, PASSWORD}; - _rmipa.authenticate(_credentials); + credentials = new String[]{USERNAME, PASSWORD, PASSWORD}; + _rmipa.authenticate(credentials); fail("SecurityException expected due to supplying wrong number of credentials"); } catch (SecurityException se) @@ -172,8 +192,8 @@ public class RMIPasswordAuthenticatorTest extends TestCase try { //send a null array - _credentials = null; - _rmipa.authenticate(_credentials); + credentials = null; + _rmipa.authenticate(credentials); fail("SecurityException expected due to not supplying an array of credentials"); } catch (SecurityException se) @@ -185,8 +205,8 @@ public class RMIPasswordAuthenticatorTest extends TestCase try { //send a null password - _credentials = new String[]{USERNAME, null}; - _rmipa.authenticate(_credentials); + credentials = new String[]{USERNAME, null}; + _rmipa.authenticate(credentials); fail("SecurityException expected due to sending a null password"); } catch (SecurityException se) @@ -198,8 +218,8 @@ public class RMIPasswordAuthenticatorTest extends TestCase try { //send a null username - _credentials = new String[]{null, PASSWORD}; - _rmipa.authenticate(_credentials); + credentials = new String[]{null, PASSWORD}; + _rmipa.authenticate(credentials); fail("SecurityException expected due to sending a null username"); } catch (SecurityException se) @@ -209,55 +229,30 @@ public class RMIPasswordAuthenticatorTest extends TestCase } } - private AuthenticationManager createTestAuthenticationManager(final boolean successfulAuth, final Exception exception) + private SubjectCreator createMockSubjectCreator(final boolean successfulAuth, final Exception exception) { - return new AuthenticationManager() + SubjectCreator subjectCreator = mock(SubjectCreator.class); + + SubjectAuthenticationResult subjectAuthenticationResult; + + if (exception != null) { + + subjectAuthenticationResult = new SubjectAuthenticationResult( + new AuthenticationResult(AuthenticationStatus.ERROR, exception)); + } + else if (successfulAuth) { - public void configure(ConfigurationPlugin config) - { - throw new UnsupportedOperationException(); - } - - public void initialise() - { - throw new UnsupportedOperationException(); - } - - public void close() - { - throw new UnsupportedOperationException(); - } - - public String getMechanisms() - { - throw new UnsupportedOperationException(); - } - - public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException - { - throw new UnsupportedOperationException(); - } - - public AuthenticationResult authenticate(SaslServer server, byte[] response) - { - throw new UnsupportedOperationException(); - } - - public AuthenticationResult authenticate(String username, String password) - { - if (exception != null) { - return new AuthenticationResult(AuthenticationStatus.ERROR, exception); - } - else if (successfulAuth) - { - return new AuthenticationResult(new Subject()); - } - else - { - return new AuthenticationResult(AuthenticationStatus.CONTINUE); - } - } - - }; + + subjectAuthenticationResult = new SubjectAuthenticationResult( + new AuthenticationResult(mock(Principal.class)), _loginSubject); + } + else + { + subjectAuthenticationResult = new SubjectAuthenticationResult(new AuthenticationResult(AuthenticationStatus.CONTINUE)); + } + + when(subjectCreator.authenticate(anyString(), anyString())).thenReturn(subjectAuthenticationResult); + + return subjectCreator; } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalDatabase.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalDatabase.java index 8c7f3ad6ef..f94d8ddfc3 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalDatabase.java +++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalDatabase.java @@ -86,4 +86,10 @@ public class TestPrincipalDatabase implements PrincipalDatabase // TODO Auto-generated method stub } + @Override + public void setPasswordFile(String passwordFile) throws IOException + { + // TODO Auto-generated method stub + } + } diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupDatabaseTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupDatabaseTest.java new file mode 100644 index 0000000000..b020c1655a --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupDatabaseTest.java @@ -0,0 +1,456 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.group; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Properties; +import java.util.Set; + +import org.apache.qpid.server.security.group.FileGroupDatabase; + +import junit.framework.TestCase; + +public class FileGroupDatabaseTest extends TestCase +{ + private static final String USER1 = "user1"; + private static final String USER2 = "user2"; + private static final String USER3 = "user3"; + + private static final String MY_GROUP = "myGroup"; + private static final String MY_GROUP2 = "myGroup2"; + private static final String MY_GROUP1 = "myGroup1"; + + private FileGroupDatabase _groupDatabase = new FileGroupDatabase(); + private String _groupFile; + + public void testGetAllGroups() throws Exception + { + writeAndSetGroupFile("myGroup.users", USER1); + + Set<String> groups = _groupDatabase.getAllGroups(); + assertEquals(1, groups.size()); + assertTrue(groups.contains(MY_GROUP)); + } + + public void testGetAllGroupsWhenGroupFileEmpty() throws Exception + { + _groupDatabase.setGroupFile(_groupFile); + + Set<String> groups = _groupDatabase.getAllGroups(); + assertEquals(0, groups.size()); + } + + public void testMissingGroupFile() throws Exception + { + try + { + _groupDatabase.setGroupFile("/not/a/file"); + fail("Exception not thrown"); + } + catch (FileNotFoundException fnfe) + { + // PASS + } + } + + public void testInvalidFormat() throws Exception + { + writeGroupFile("name.notvalid", USER1); + + try + { + _groupDatabase.setGroupFile(_groupFile); + fail("Exception not thrown"); + } + catch (IllegalArgumentException gde) + { + // PASS + } + } + + public void testGetUsersInGroup() throws Exception + { + writeGroupFile("myGroup.users", "user1,user2,user3"); + + _groupDatabase.setGroupFile(_groupFile); + + Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP); + assertNotNull(users); + assertEquals(3, users.size()); + } + + public void testDuplicateUsersInGroupAreConflated() throws Exception + { + writeAndSetGroupFile("myGroup.users", "user1,user1,user3,user1"); + + Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP); + assertNotNull(users); + assertEquals(2, users.size()); + } + + public void testGetUsersWithEmptyGroup() throws Exception + { + writeAndSetGroupFile("myGroup.users", ""); + + Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP); + assertNotNull(users); + assertTrue(users.isEmpty()); + } + + public void testGetUsersInNonExistentGroup() throws Exception + { + writeAndSetGroupFile("myGroup.users", "user1,user2,user3"); + + Set<String> users = _groupDatabase.getUsersInGroup("groupDoesntExist"); + assertNotNull(users); + assertTrue(users.isEmpty()); + } + + public void testGetUsersInNullGroup() throws Exception + { + writeAndSetGroupFile(); + assertTrue(_groupDatabase.getUsersInGroup(null).isEmpty()); + } + + public void testGetGroupPrincipalsForUserWhenUserBelongsToOneGroup() throws Exception + { + writeAndSetGroupFile("myGroup.users", "user1,user2"); + Set<String> groups = _groupDatabase.getGroupsForUser(USER1); + assertEquals(1, groups.size()); + assertTrue(groups.contains(MY_GROUP)); + } + + public void testGetGroupPrincipalsForUserWhenUserBelongsToTwoGroup() throws Exception + { + writeAndSetGroupFile("myGroup1.users", "user1,user2", + "myGroup2.users", "user1,user3"); + Set<String> groups = _groupDatabase.getGroupsForUser(USER1); + assertEquals(2, groups.size()); + assertTrue(groups.contains(MY_GROUP1)); + assertTrue(groups.contains(MY_GROUP2)); + } + + public void testGetGroupPrincipalsForUserWhenUserAddedToGroup() throws Exception + { + writeAndSetGroupFile("myGroup1.users", "user1,user2", + "myGroup2.users", USER2); + Set<String> groups = _groupDatabase.getGroupsForUser(USER1); + assertEquals(1, groups.size()); + assertTrue(groups.contains(MY_GROUP1)); + + _groupDatabase.addUserToGroup(USER1, MY_GROUP2); + + groups = _groupDatabase.getGroupsForUser(USER1); + assertEquals(2, groups.size()); + assertTrue(groups.contains(MY_GROUP1)); + assertTrue(groups.contains(MY_GROUP2)); + + Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP2); + assertEquals(2, users.size()); + assertTrue(users.contains(USER1)); + assertTrue(users.contains(USER2)); + } + + public void testGetGroupPrincipalsForUserWhenUserRemovedFromGroup() throws Exception + { + writeAndSetGroupFile("myGroup1.users", "user1,user2", + "myGroup2.users", "user1,user2"); + Set<String> groups = _groupDatabase.getGroupsForUser(USER1); + assertEquals(2, groups.size()); + assertTrue(groups.contains(MY_GROUP1)); + assertTrue(groups.contains(MY_GROUP2)); + + _groupDatabase.removeUserFromGroup(USER1, MY_GROUP2); + + groups = _groupDatabase.getGroupsForUser(USER1); + assertEquals(1, groups.size()); + assertTrue(groups.contains(MY_GROUP1)); + } + + public void testGetGroupPrincipalsForUserWhenUserAdddedToGroupTheyAreAlreadyIn() throws Exception + { + writeAndSetGroupFile("myGroup.users", USER1); + _groupDatabase.addUserToGroup(USER1, MY_GROUP); + + Set<String> groups = _groupDatabase.getGroupsForUser(USER1); + + assertEquals(1, groups.size()); + assertTrue(groups.contains(MY_GROUP)); + + Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP); + assertEquals(1, users.size()); + assertTrue(users.contains(USER1)); + } + + public void testGetGroupPrincipalsForUserWhenUserNotKnown() throws Exception + { + writeAndSetGroupFile("myGroup.users", "user1,user2"); + Set<String> groups = _groupDatabase.getGroupsForUser(USER3); + assertEquals(0, groups.size()); + } + + public void testGetGroupPrincipalsForNullUser() throws Exception + { + writeAndSetGroupFile(); + assertTrue(_groupDatabase.getGroupsForUser(null).isEmpty()); + } + + public void testAddUserToExistingGroup() throws Exception + { + writeAndSetGroupFile("myGroup.users", "user1,user2"); + + Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP); + assertNotNull(users); + assertEquals(2, users.size()); + + _groupDatabase.addUserToGroup(USER3, MY_GROUP); + + users = _groupDatabase.getUsersInGroup(MY_GROUP); + assertNotNull(users); + assertEquals(3, users.size()); + } + + public void testAddUserToEmptyGroup() throws Exception + { + writeAndSetGroupFile("myGroup.users", ""); + + Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP); + assertNotNull(users); + assertEquals(0, users.size()); + + _groupDatabase.addUserToGroup(USER3, MY_GROUP); + + users = _groupDatabase.getUsersInGroup(MY_GROUP); + assertNotNull(users); + assertEquals(1, users.size()); + } + + public void testAddUserToNonExistentGroup() throws Exception + { + writeAndSetGroupFile(); + + Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP); + assertNotNull(users); + assertEquals(0, users.size()); + + try + { + _groupDatabase.addUserToGroup(USER3, MY_GROUP); + fail("Expected exception not thrown"); + } + catch(IllegalArgumentException e) + { + // pass + } + + users = _groupDatabase.getUsersInGroup(MY_GROUP); + assertNotNull(users); + assertEquals(0, users.size()); + } + + public void testRemoveUserFromExistingGroup() throws Exception + { + writeAndSetGroupFile("myGroup.users", "user1,user2"); + + Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP); + assertNotNull(users); + assertEquals(2, users.size()); + + _groupDatabase.removeUserFromGroup(USER2, MY_GROUP); + + users = _groupDatabase.getUsersInGroup(MY_GROUP); + assertNotNull(users); + assertEquals(1, users.size()); + } + + public void testRemoveUserFromNonexistentGroup() throws Exception + { + writeAndSetGroupFile(); + + try + { + _groupDatabase.removeUserFromGroup(USER1, MY_GROUP); + fail("Expected exception not thrown"); + } + catch(IllegalArgumentException e) + { + // pass + } + + assertTrue(_groupDatabase.getUsersInGroup(MY_GROUP).isEmpty()); + } + + public void testRemoveUserFromGroupTwice() throws Exception + { + writeAndSetGroupFile("myGroup.users", USER1); + assertTrue(_groupDatabase.getUsersInGroup(MY_GROUP).contains(USER1)); + + _groupDatabase.removeUserFromGroup(USER1, MY_GROUP); + assertTrue(_groupDatabase.getUsersInGroup(MY_GROUP).isEmpty()); + + _groupDatabase.removeUserFromGroup(USER1, MY_GROUP); + assertTrue(_groupDatabase.getUsersInGroup(MY_GROUP).isEmpty()); + } + + public void testAddUserPersistedToFile() throws Exception + { + writeAndSetGroupFile("myGroup.users", "user1,user2"); + + Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP); + assertEquals(2, users.size()); + + _groupDatabase.addUserToGroup(USER3, MY_GROUP); + assertEquals(3, users.size()); + + FileGroupDatabase newGroupDatabase = new FileGroupDatabase(); + newGroupDatabase.setGroupFile(_groupFile); + + Set<String> newUsers = newGroupDatabase.getUsersInGroup(MY_GROUP); + assertEquals(users.size(), newUsers.size()); + } + + public void testRemoveUserPersistedToFile() throws Exception + { + writeAndSetGroupFile("myGroup.users", "user1,user2"); + + Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP); + assertEquals(2, users.size()); + + _groupDatabase.removeUserFromGroup(USER2, MY_GROUP); + assertEquals(1, users.size()); + + FileGroupDatabase newGroupDatabase = new FileGroupDatabase(); + newGroupDatabase.setGroupFile(_groupFile); + + Set<String> newUsers = newGroupDatabase.getUsersInGroup(MY_GROUP); + assertEquals(users.size(), newUsers.size()); + } + + public void testCreateGroupPersistedToFile() throws Exception + { + writeAndSetGroupFile(); + + Set<String> groups = _groupDatabase.getAllGroups(); + assertEquals(0, groups.size()); + + _groupDatabase.createGroup(MY_GROUP); + + groups = _groupDatabase.getAllGroups(); + assertEquals(1, groups.size()); + assertTrue(groups.contains(MY_GROUP)); + + FileGroupDatabase newGroupDatabase = new FileGroupDatabase(); + newGroupDatabase.setGroupFile(_groupFile); + + Set<String> newGroups = newGroupDatabase.getAllGroups(); + assertEquals(1, newGroups.size()); + assertTrue(newGroups.contains(MY_GROUP)); + } + + public void testRemoveGroupPersistedToFile() throws Exception + { + writeAndSetGroupFile("myGroup1.users", "user1,user2", + "myGroup2.users", "user1,user2"); + + Set<String> groups = _groupDatabase.getAllGroups(); + assertEquals(2, groups.size()); + + Set<String> groupsForUser1 = _groupDatabase.getGroupsForUser(USER1); + assertEquals(2, groupsForUser1.size()); + + _groupDatabase.removeGroup(MY_GROUP1); + + groups = _groupDatabase.getAllGroups(); + assertEquals(1, groups.size()); + assertTrue(groups.contains(MY_GROUP2)); + + groupsForUser1 = _groupDatabase.getGroupsForUser(USER1); + assertEquals(1, groupsForUser1.size()); + + FileGroupDatabase newGroupDatabase = new FileGroupDatabase(); + newGroupDatabase.setGroupFile(_groupFile); + + Set<String> newGroups = newGroupDatabase.getAllGroups(); + assertEquals(1, newGroups.size()); + assertTrue(newGroups.contains(MY_GROUP2)); + + Set<String> newGroupsForUser1 = newGroupDatabase.getGroupsForUser(USER1); + assertEquals(1, newGroupsForUser1.size()); + assertTrue(newGroupsForUser1.contains(MY_GROUP2)); +} + + @Override + protected void setUp() throws Exception + { + super.setUp(); + _groupFile = createEmptyTestGroupFile(); + } + + private void writeAndSetGroupFile(String... groupAndUsers) throws Exception + { + writeGroupFile(groupAndUsers); + _groupDatabase.setGroupFile(_groupFile); + } + + private void writeGroupFile(String... groupAndUsers) throws Exception + { + if (groupAndUsers.length % 2 != 0) + { + throw new IllegalArgumentException("Number of groupAndUsers must be even"); + } + + Properties props = new Properties(); + for (int i = 0 ; i < groupAndUsers.length; i=i+2) + { + String group = groupAndUsers[i]; + String users = groupAndUsers[i+1]; + props.put(group, users); + } + + props.store(new FileOutputStream(_groupFile), "test group file"); + } + + private String createEmptyTestGroupFile() throws IOException + { + File tmpGroupFile = File.createTempFile("groups", "grp"); + tmpGroupFile.deleteOnExit(); + + return tmpGroupFile.getAbsolutePath(); + } + + @Override + protected void tearDown() throws Exception + { + super.tearDown(); + + if (_groupFile != null) + { + File groupFile = new File(_groupFile); + if (groupFile.exists()) + { + groupFile.delete(); + } + } + } + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerFactoryTest.java new file mode 100644 index 0000000000..934c0082ea --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerFactoryTest.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.security.group; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.test.utils.TestFileUtils; + +public class FileGroupManagerFactoryTest extends TestCase +{ + + private FileGroupManagerFactory _factory = new FileGroupManagerFactory(); + private Map<String, Object> _configuration = new HashMap<String, Object>(); + private String _emptyButValidGroupFile = TestFileUtils.createTempFile(this).getAbsolutePath(); + + public void testInstanceCreated() throws Exception + { + _configuration.put(GroupProvider.TYPE, FileGroupManagerFactory.FILE_GROUP_MANAGER_TYPE); + _configuration.put(FileGroupManagerFactory.FILE, _emptyButValidGroupFile); + + GroupManager manager = _factory.createInstance(_configuration); + assertNotNull(manager); + assertTrue(manager instanceof FileGroupManager); + } + + public void testReturnsNullWhenNoConfig() throws Exception + { + GroupManager manager = _factory.createInstance(_configuration); + assertNull(manager); + } + + public void testReturnsNullWhenConfigNotForThisPlugin() throws Exception + { + _configuration.put(GroupProvider.TYPE, "other-group-manager"); + + GroupManager manager = _factory.createInstance(_configuration); + assertNull(manager); + } + + + public void testRejectsConfigThatIsMissingAttributeValue() throws Exception + { + _configuration.put(GroupProvider.TYPE, FileGroupManagerFactory.FILE_GROUP_MANAGER_TYPE); + _configuration.put(FileGroupManagerFactory.FILE, null); + + try + { + _factory.createInstance(_configuration); + fail("Exception not thrown"); + } + catch (RuntimeException re) + { + // PASS + } + } + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerTest.java new file mode 100644 index 0000000000..b83d25b206 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerTest.java @@ -0,0 +1,197 @@ +/* + * 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.security.group; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.security.Principal; +import java.util.Properties; +import java.util.Set; + +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.security.auth.UsernamePrincipal; +import org.apache.qpid.test.utils.QpidTestCase; + +public class FileGroupManagerTest extends QpidTestCase +{ + private static final String MYGROUP_USERS = "user1"; + private static final String MY_GROUP = "myGroup.users"; + private static final String MY_GROUP2 = "myGroup2.users"; + private File _tmpGroupFile; + private FileGroupManager _manager; + + @Override + public void tearDown() throws Exception + { + super.tearDown(); + + if (_tmpGroupFile != null) + { + if (_tmpGroupFile.exists()) + { + _tmpGroupFile.delete(); + } + } + } + + public void testValidGroupFile() throws Exception + { + final String groupFileName = writeGroupFile(); + + _manager = new FileGroupManager(groupFileName); + assertNotNull(_manager); + } + + public void testNonExistentGroupFile() throws Exception + { + final String filePath = "/does.not.exist/"; + + try + { + _manager = new FileGroupManager(filePath); + fail("expected exception was not thrown"); + } + catch(IllegalConfigurationException ce) + { + assertNotNull(ce.getCause()); + assertTrue(ce.getCause() instanceof FileNotFoundException); + } + } + + public void testGetGroupPrincipalsForUser() throws Exception + { + final String groupFileName = writeGroupFile(); + _manager = new FileGroupManager(groupFileName); + + Set<Principal> principals = _manager.getGroupPrincipalsForUser("user1"); + assertEquals(1, principals.size()); + assertTrue(principals.contains(new GroupPrincipal("myGroup"))); + } + + public void testGetUserPrincipalsForGroup() throws Exception + { + final String groupFileName = writeGroupFile(); + _manager = new FileGroupManager(groupFileName); + + Set<Principal> principals = _manager.getUserPrincipalsForGroup("myGroup"); + assertEquals(1, principals.size()); + assertTrue(principals.contains(new UsernamePrincipal("user1"))); + } + + public void testGetGroupPrincipals() throws Exception + { + final String groupFileName = writeGroupFile(MY_GROUP, MYGROUP_USERS, MY_GROUP2, MYGROUP_USERS); + _manager = new FileGroupManager(groupFileName); + + Set<Principal> principals = _manager.getGroupPrincipals(); + assertEquals(2, principals.size()); + assertTrue(principals.contains(new GroupPrincipal("myGroup"))); + assertTrue(principals.contains(new GroupPrincipal("myGroup2"))); + } + + public void testCreateGroup() throws Exception + { + final String groupFileName = writeGroupFile(); + _manager = new FileGroupManager(groupFileName); + + Set<Principal> principals = _manager.getGroupPrincipals(); + assertEquals(1, principals.size()); + + _manager.createGroup("myGroup2"); + + principals = _manager.getGroupPrincipals(); + assertEquals(2, principals.size()); + assertTrue(principals.contains(new GroupPrincipal("myGroup2"))); + } + + public void testRemoveGroup() throws Exception + { + final String groupFileName = writeGroupFile(MY_GROUP, MYGROUP_USERS); + _manager = new FileGroupManager(groupFileName); + + Set<Principal> principals = _manager.getGroupPrincipals(); + assertEquals(1, principals.size()); + + _manager.removeGroup("myGroup"); + + principals = _manager.getGroupPrincipals(); + assertEquals(0, principals.size()); + } + + public void testAddUserToGroup() throws Exception + { + final String groupFileName = writeGroupFile(MY_GROUP, MYGROUP_USERS); + _manager = new FileGroupManager(groupFileName); + + Set<Principal> principals = _manager.getUserPrincipalsForGroup("myGroup"); + assertEquals(1, principals.size()); + assertFalse(principals.contains(new UsernamePrincipal("user2"))); + + _manager.addUserToGroup("user2", "myGroup"); + + principals = _manager.getUserPrincipalsForGroup("myGroup"); + assertEquals(2, principals.size()); + assertTrue(principals.contains(new UsernamePrincipal("user2"))); + } + + public void testRemoveUserInGroup() throws Exception + { + final String groupFileName = writeGroupFile(MY_GROUP, MYGROUP_USERS); + _manager = new FileGroupManager(groupFileName); + + Set<Principal> principals = _manager.getUserPrincipalsForGroup("myGroup"); + assertEquals(1, principals.size()); + assertTrue(principals.contains(new UsernamePrincipal("user1"))); + + _manager.removeUserFromGroup("user1", "myGroup"); + + principals = _manager.getUserPrincipalsForGroup("myGroup"); + assertEquals(0, principals.size()); + } + + private String writeGroupFile() throws Exception + { + return writeGroupFile(MY_GROUP, MYGROUP_USERS); + } + + private String writeGroupFile(String... groupAndUsers) throws Exception + { + if (groupAndUsers.length % 2 != 0) + { + throw new IllegalArgumentException("Number of groupAndUsers must be even"); + } + + _tmpGroupFile = File.createTempFile("groups", "grp"); + _tmpGroupFile.deleteOnExit(); + + Properties props = new Properties(); + for (int i = 0 ; i < groupAndUsers.length; i=i+2) + { + String group = groupAndUsers[i]; + String users = groupAndUsers[i+1]; + props.put(group, users); + } + + props.store(new FileOutputStream(_tmpGroupFile), "test group file"); + + return _tmpGroupFile.getCanonicalPath(); + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalAccessorTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalAccessorTest.java new file mode 100644 index 0000000000..e58a1a01f8 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalAccessorTest.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.security.group; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.security.Principal; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import junit.framework.TestCase; + +import org.apache.qpid.server.model.GroupProvider; + +public class GroupPrincipalAccessorTest extends TestCase +{ + private static final String USERNAME = "username"; + + private GroupProvider _groupManager1 = mock(GroupProvider.class); + private GroupProvider _groupManager2 = mock(GroupProvider.class); + + private Principal _group1 = mock(Principal.class); + private Principal _group2 = mock(Principal.class); + + @Override + public void setUp() + { + when(_groupManager1.getGroupPrincipalsForUser(USERNAME)).thenReturn(Collections.singleton(_group1)); + when(_groupManager2.getGroupPrincipalsForUser(USERNAME)).thenReturn(Collections.singleton(_group2)); + } + + public void testGetGroupPrincipals() + { + getAndAssertGroupPrincipals(_group1, _group2); + } + + public void testGetGroupPrincipalsWhenAGroupManagerReturnsNull() + { + when(_groupManager1.getGroupPrincipalsForUser(USERNAME)).thenReturn(null); + + getAndAssertGroupPrincipals(_group2); + } + + public void testGetGroupPrincipalsWhenAGroupManagerReturnsEmptySet() + { + when(_groupManager2.getGroupPrincipalsForUser(USERNAME)).thenReturn(new HashSet<Principal>()); + + getAndAssertGroupPrincipals(_group1); + } + + private void getAndAssertGroupPrincipals(Principal... expectedGroups) + { + GroupPrincipalAccessor groupPrincipalAccessor = new GroupPrincipalAccessor(Arrays.asList(_groupManager1, _groupManager2)); + + Set<Principal> actualGroupPrincipals = groupPrincipalAccessor.getGroupPrincipals(USERNAME); + + Set<Principal> expectedGroupPrincipals = new HashSet<Principal>(Arrays.asList(expectedGroups)); + + assertEquals(expectedGroupPrincipals, actualGroupPrincipals); + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalTest.java index 076b7c9248..d285a0797a 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalTest.java @@ -7,9 +7,9 @@ * 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 @@ -18,7 +18,9 @@ * under the License. * */ -package org.apache.qpid.server.security.auth.sasl; +package org.apache.qpid.server.security.group; + +import org.apache.qpid.server.security.auth.UsernamePrincipal; import junit.framework.TestCase; @@ -34,7 +36,7 @@ public class GroupPrincipalTest extends TestCase { final GroupPrincipal principal = new GroupPrincipal("group"); final UsernamePrincipal user = new UsernamePrincipal("name"); - + try { principal.addMember(user); @@ -45,7 +47,7 @@ public class GroupPrincipalTest extends TestCase // PASS } } - + public void testEqualitySameName() { final String string = "string"; @@ -80,7 +82,7 @@ public class GroupPrincipalTest extends TestCase assertFalse(principal.equals(null)); } - + } diff --git a/java/broker/src/test/java/org/apache/qpid/server/signal/SignalHandlerTaskTest.java b/java/broker/src/test/java/org/apache/qpid/server/signal/SignalHandlerTaskTest.java deleted file mode 100644 index 23ee82eae6..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/signal/SignalHandlerTaskTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * - * 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.signal; - -import org.apache.log4j.Logger; - -import org.apache.qpid.test.utils.QpidTestCase; - -import java.lang.management.ManagementFactory; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -public class SignalHandlerTaskTest extends QpidTestCase -{ - private static final Logger LOGGER = Logger.getLogger(SignalHandlerTaskTest.class); - private static final String SUN_MISC_SIGNAL_CLASS = "sun.misc.Signal"; - private static final String SUN_MISC_SIGNAL_HANDLER_CLASS = "sun.misc.SignalHandler"; - - protected void setUp() throws Exception - { - super.setUp(); - } - - public void testSignalHandlerTask() throws Exception - { - final boolean expectedResult = classifyExpectedRegistrationResult(); - final int pid = getPID(); - final CountDownLatch latch = new CountDownLatch(1); - - SignalHandlerTask hupReparseTask = new SignalHandlerTask() - { - public void handle() - { - latch.countDown(); - LOGGER.info("Signal handled, latch decremented"); - } - }; - - assertEquals("Unexpected result trying to register Signal handler", - expectedResult, hupReparseTask.register("HUP")); - LOGGER.info("Signal handler was registered"); - - assertEquals("unexpected count for the latch", 1, latch.getCount()); - - if(expectedResult) - { - //registration succeeded as expected, so now - //send SIGHUP and verify the handler was run - String cmd = "/bin/kill -SIGHUP " + pid; - - LOGGER.info("Sending SIGHUP"); - Runtime.getRuntime().exec(cmd); - - assertTrue("HUP Signal was not handled in the allowed timeframe", - latch.await(5, TimeUnit.SECONDS)); - } - } - - public void testGetPlatformDescription() throws Exception - { - assertNotNull(SignalHandlerTask.getPlatformDescription()); - } - - private boolean classifyExpectedRegistrationResult() - { - String os = System.getProperty("os.name"); - if(String.valueOf(os).toLowerCase().contains("windows")) - { - //Windows does not support SIGHUP so registration will fail - LOGGER.info("Running on windows, so we expect SIGHUP handler registration to fail"); - return false; - } - - //otherwise, if the signal handler classes are present we would expect - //registration to succeed - boolean classesPresent = true; - try - { - Class.forName(SUN_MISC_SIGNAL_CLASS); - Class.forName(SUN_MISC_SIGNAL_HANDLER_CLASS); - LOGGER.info("Signal handling classes were present so we expect SIGHUP handler registration to succeed"); - } - catch (ClassNotFoundException cnfe) - { - classesPresent = false; - } - - return classesPresent; - } - - private int getPID() - { - String processName = ManagementFactory.getRuntimeMXBean().getName(); - - int pid = Integer.parseInt(processName.substring(0,processName.indexOf('@'))); - LOGGER.info("PID was determined to be " + pid); - - return pid; - } - -} diff --git a/java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java b/java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java index cd8d91d835..f0ecfb6407 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java @@ -51,10 +51,6 @@ import org.apache.qpid.server.message.EnqueableMessage; import org.apache.qpid.server.model.UUIDGenerator; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.MockStoredMessage; -import org.apache.qpid.server.store.ConfigurationRecoveryHandler; -import org.apache.qpid.server.store.MessageStore; -import org.apache.qpid.server.store.MessageStoreRecoveryHandler; -import org.apache.qpid.server.store.TransactionLogRecoveryHandler; import org.apache.qpid.server.store.ConfigurationRecoveryHandler.BindingRecoveryHandler; import org.apache.qpid.server.store.ConfigurationRecoveryHandler.ExchangeRecoveryHandler; import org.apache.qpid.server.store.ConfigurationRecoveryHandler.QueueRecoveryHandler; @@ -76,7 +72,6 @@ public class DurableConfigurationStoreTest extends QpidTestCase private QueueRecoveryHandler _queueRecoveryHandler; private ExchangeRecoveryHandler _exchangeRecoveryHandler; private BindingRecoveryHandler _bindingRecoveryHandler; - private ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler _linkRecoveryHandler; private MessageStoreRecoveryHandler _messageStoreRecoveryHandler; private StoredMessageRecoveryHandler _storedMessageRecoveryHandler; private TransactionLogRecoveryHandler _logRecoveryHandler; @@ -116,7 +111,6 @@ public class DurableConfigurationStoreTest extends QpidTestCase when(_recoveryHandler.begin(isA(MessageStore.class))).thenReturn(_exchangeRecoveryHandler); when(_exchangeRecoveryHandler.completeExchangeRecovery()).thenReturn(_queueRecoveryHandler); when(_queueRecoveryHandler.completeQueueRecovery()).thenReturn(_bindingRecoveryHandler); - when(_bindingRecoveryHandler.completeBindingRecovery()).thenReturn(_linkRecoveryHandler); when(_logRecoveryHandler.begin(any(MessageStore.class))).thenReturn(_queueEntryRecoveryHandler); when(_queueEntryRecoveryHandler.completeQueueEntryRecovery()).thenReturn(_dtxRecordRecoveryHandler); when(_exchange.getNameShortString()).thenReturn(AMQShortString.valueOf(EXCHANGE_NAME)); @@ -161,7 +155,7 @@ public class DurableConfigurationStoreTest extends QpidTestCase public void testBindQueue() throws Exception { AMQQueue queue = createTestQueue(QUEUE_NAME, "queueOwner", false); - Binding binding = new Binding(UUIDGenerator.generateRandomUUID(), null, ROUTING_KEY, queue, + Binding binding = new Binding(UUIDGenerator.generateRandomUUID(), ROUTING_KEY, queue, _exchange, FieldTable.convertToMap(_bindingArgs)); _store.bindQueue(binding); @@ -175,7 +169,7 @@ public class DurableConfigurationStoreTest extends QpidTestCase public void testUnbindQueue() throws Exception { AMQQueue queue = createTestQueue(QUEUE_NAME, "queueOwner", false); - Binding binding = new Binding(UUIDGenerator.generateRandomUUID(), null, ROUTING_KEY, queue, + Binding binding = new Binding(UUIDGenerator.generateRandomUUID(), ROUTING_KEY, queue, _exchange, FieldTable.convertToMap(_bindingArgs)); _store.bindQueue(binding); diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommand.java b/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreCreatorTest.java index 4f143701af..e74937dd1c 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommand.java +++ b/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreCreatorTest.java @@ -18,37 +18,22 @@ * under the License. * */ +package org.apache.qpid.server.store; -package org.apache.qpid.qmf; +import org.apache.qpid.server.store.derby.DerbyMessageStore; +import org.apache.qpid.test.utils.QpidTestCase; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBEncoder; - -public abstract class QMFCommand +public class MessageStoreCreatorTest extends QpidTestCase { + private static final String[] STORE_TYPES = {MemoryMessageStore.TYPE, DerbyMessageStore.TYPE}; - private final QMFCommandHeader _header; - - protected QMFCommand(QMFCommandHeader header) - { - _header = header; - } - - - public void process(final VirtualHost virtualHost, final ServerMessage message) - { - throw new UnsupportedOperationException(); - } - - public void encode(BBEncoder encoder) - { - _header.encode(encoder); - - } - - public QMFCommandHeader getHeader() + public void testMessageStoreCreator() { - return _header; + MessageStoreCreator messageStoreCreator = new MessageStoreCreator(); + for (String type : STORE_TYPES) + { + MessageStore store = messageStoreCreator.createMessageStore(type); + assertNotNull("Store of type " + type + " is not created", store); + } } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java b/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java index a1536565ad..ffd777243b 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.server.store; + import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.qpid.AMQException; @@ -35,11 +36,12 @@ import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.DirectExchange; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.exchange.ExchangeType; import org.apache.qpid.server.exchange.TopicExchange; import org.apache.qpid.server.message.AMQMessage; import org.apache.qpid.server.message.MessageMetaData; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.queue.AMQPriorityQueue; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; @@ -48,11 +50,11 @@ import org.apache.qpid.server.queue.ConflationQueue; import org.apache.qpid.server.queue.IncomingMessage; import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.queue.SimpleAMQQueue; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.txn.AutoCommitTransaction; import org.apache.qpid.server.txn.ServerTransaction; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.test.utils.QpidTestCase; import org.apache.qpid.util.FileUtils; import java.io.File; @@ -66,7 +68,7 @@ import java.util.Map; * For persistent stores, it validates that Exchanges, Queues, Bindings and * Messages are persisted and recovered correctly. */ -public class MessageStoreTest extends InternalBrokerBaseCase +public class MessageStoreTest extends QpidTestCase { public static final int DEFAULT_PRIORTY_LEVEL = 5; public static final String SELECTOR_VALUE = "Test = 'MST'"; @@ -93,11 +95,15 @@ public class MessageStoreTest extends InternalBrokerBaseCase private AMQShortString queueOwner = new AMQShortString("MST"); - protected PropertiesConfiguration _config; + private PropertiesConfiguration _config; + + private VirtualHost _virtualHost; + private Broker _broker; public void setUp() throws Exception { super.setUp(); + BrokerTestHelper.setUp(); String storePath = System.getProperty("QPID_WORK") + File.separator + getName(); @@ -107,9 +113,38 @@ public class MessageStoreTest extends InternalBrokerBaseCase cleanup(new File(storePath)); + _broker = BrokerTestHelper.createBrokerMock(); + reloadVirtualHost(); } + @Override + public void tearDown() throws Exception + { + try + { + if (_virtualHost != null) + { + _virtualHost.close(); + } + } + finally + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } + } + + public VirtualHost getVirtualHost() + { + return _virtualHost; + } + + public PropertiesConfiguration getConfig() + { + return _config; + } + protected void reloadVirtualHost() { VirtualHost original = getVirtualHost(); @@ -119,8 +154,6 @@ public class MessageStoreTest extends InternalBrokerBaseCase try { getVirtualHost().close(); - getVirtualHost().getApplicationRegistry(). - getVirtualHostRegistry().unregisterVirtualHost(getVirtualHost()); } catch (Exception e) { @@ -131,7 +164,7 @@ public class MessageStoreTest extends InternalBrokerBaseCase try { - setVirtualHost(ApplicationRegistry.getInstance().createVirtualHost(new VirtualHostConfiguration(getClass().getName(), _config))); + _virtualHost = BrokerTestHelper.createVirtualHost(new VirtualHostConfiguration(getClass().getName(), _config, _broker)); } catch (Exception e) { @@ -628,7 +661,7 @@ public class MessageStoreTest extends InternalBrokerBaseCase { //To change body of implemented methods use File | Settings | File Templates. } - }, 0L); + }); } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java b/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java index 4aa023a25c..7c6891da71 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java @@ -27,6 +27,7 @@ import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.server.message.AMQMessage; import org.apache.qpid.server.message.MessageMetaData; +import org.apache.qpid.server.message.MessageReference; import org.apache.qpid.test.utils.QpidTestCase; /** @@ -86,10 +87,12 @@ public class ReferenceCountingTest extends QpidTestCase AMQMessage message = new AMQMessage(storedMessage); - message.incrementReference(); + MessageReference ref = message.newReference(); assertEquals(1, _store.getMessageCount()); - message.decrementReference(); + + ref.release(); + assertEquals(0, _store.getMessageCount()); } @@ -142,13 +145,13 @@ public class ReferenceCountingTest extends QpidTestCase AMQMessage message = new AMQMessage(storedMessage); - message.incrementReference(); + MessageReference ref = message.newReference(); // we call routing complete to set up the handle // message.routingComplete(_store, _storeContext, new MessageHandleFactory()); assertEquals(1, _store.getMessageCount()); - message.incrementReference(); - message.decrementReference(); + MessageReference ref2 = message.newReference(); + ref.release(); assertEquals(1, _store.getMessageCount()); } diff --git a/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java b/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java index 8c5d2684ff..a3552639d1 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java +++ b/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java @@ -294,17 +294,12 @@ public class MockSubscription implements Subscription private static class MockSessionModel implements AMQSessionModel { + private final UUID _id = UUID.randomUUID(); @Override - public int compareTo(AMQSessionModel o) - { - return 0; - } - - @Override - public UUID getQMFId() + public UUID getId() { - return null; + return _id; } @Override @@ -409,6 +404,12 @@ public class MockSubscription implements Subscription { return 0; } + + @Override + public int compareTo(AMQSessionModel o) + { + return getId().compareTo(o.getId()); + } } private static class MockConnectionModel implements AMQConnectionModel diff --git a/java/broker/src/test/java/org/apache/qpid/server/subscription/QueueBrowserUsesNoAckTest.java b/java/broker/src/test/java/org/apache/qpid/server/subscription/QueueBrowserUsesNoAckTest.java index 3272bd5447..d35a90e3c8 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/subscription/QueueBrowserUsesNoAckTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/subscription/QueueBrowserUsesNoAckTest.java @@ -21,14 +21,75 @@ package org.apache.qpid.server.subscription; import org.apache.qpid.AMQException; +import org.apache.qpid.common.AMQPFilterTypes; +import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.server.AMQChannel; +import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.protocol.InternalTestProtocolSession; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.queue.SimpleAMQQueue; +import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.store.TestableMemoryMessageStore; +import org.apache.qpid.server.util.BrokerTestHelper; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.test.utils.QpidTestCase; import java.util.List; -public class QueueBrowserUsesNoAckTest extends InternalBrokerBaseCase +public class QueueBrowserUsesNoAckTest extends QpidTestCase { + private AMQChannel _channel; + private SimpleAMQQueue _queue; + private MessageStore _messageStore; + private String _queueName; + + @Override + public void setUp() throws Exception + { + super.setUp(); + BrokerTestHelper.setUp(); + _channel = BrokerTestHelper.createChannel(); + VirtualHost virtualHost = _channel.getVirtualHost(); + _queueName = getTestName(); + _queue = BrokerTestHelper.createQueue(_queueName, virtualHost); + _messageStore = virtualHost.getMessageStore(); + Exchange defaultExchange = virtualHost.getExchangeRegistry().getDefaultExchange(); + virtualHost.getBindingFactory().addBinding(_queueName, _queue, defaultExchange, null); + } + + @Override + public void tearDown() throws Exception + { + try + { + if (_channel != null) + { + _channel.getVirtualHost().close(); + } + } + finally + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } + } + + private AMQChannel getChannel() + { + return _channel; + } + + private InternalTestProtocolSession getSession() + { + return (InternalTestProtocolSession)_channel.getProtocolSession(); + } + + private SimpleAMQQueue getQueue() + { + return _queue; + } public void testQueueBrowserUsesNoAck() throws AMQException { @@ -39,7 +100,7 @@ public class QueueBrowserUsesNoAckTest extends InternalBrokerBaseCase checkStoreContents(0); //Send required messsages to the queue - publishMessages(getSession(), getChannel(), sendMessageCount); + BrokerTestHelper.publishMessages(getChannel(), sendMessageCount, _queueName, ExchangeDefaults.DEFAULT_EXCHANGE_NAME.asString()); //Ensure they are stored checkStoreContents(sendMessageCount); @@ -74,4 +135,16 @@ public class QueueBrowserUsesNoAckTest extends InternalBrokerBaseCase .equals(Subscription.State.SUSPENDED)); } + private void checkStoreContents(int messageCount) + { + assertEquals("Message header count incorrect in the MetaDataMap", messageCount, ((TestableMemoryMessageStore) _messageStore).getMessageCount()); + } + + private AMQShortString browse(AMQChannel channel, AMQQueue queue) throws AMQException + { + FieldTable filters = new FieldTable(); + filters.put(AMQPFilterTypes.NO_CONSUME.getValue(), true); + + return channel.subscribeToQueue(null, queue, true, filters, false, true); + } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionFactoryImplTest.java b/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionFactoryImplTest.java index 29f45bf7f4..89d434e95d 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionFactoryImplTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionFactoryImplTest.java @@ -23,20 +23,55 @@ package org.apache.qpid.server.subscription; import org.apache.qpid.common.AMQPFilterTypes; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.flow.WindowCreditManager; +import org.apache.qpid.server.logging.UnitTestMessageLogger; +import org.apache.qpid.server.logging.actors.GenericActor; +import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.protocol.ProtocolEngine_0_10; import org.apache.qpid.server.transport.ServerConnection; import org.apache.qpid.server.transport.ServerSession; import org.apache.qpid.server.transport.ServerSessionDelegate; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.server.util.BrokerTestHelper; +import org.apache.qpid.test.utils.QpidTestCase; import org.apache.qpid.transport.Binary; import org.apache.qpid.transport.MessageAcceptMode; import org.apache.qpid.transport.MessageAcquireMode; import org.apache.qpid.transport.MessageFlowMode; import org.apache.qpid.transport.TestNetworkConnection; -public class SubscriptionFactoryImplTest extends InternalBrokerBaseCase +public class SubscriptionFactoryImplTest extends QpidTestCase { + private AMQChannel _channel; + private AMQProtocolSession _session; + + @Override + public void setUp() throws Exception + { + super.setUp(); + BrokerTestHelper.setUp(); + _channel = BrokerTestHelper.createChannel(); + _session = _channel.getProtocolSession(); + GenericActor.setDefaultMessageLogger(new UnitTestMessageLogger(false)); + } + + @Override + public void tearDown() throws Exception + { + try + { + if (_channel != null) + { + _channel.getVirtualHost().close(); + } + } + finally + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } + } + /** * Tests that while creating Subscriptions of various types, the * ID numbers assigned are allocated from a common sequence @@ -46,35 +81,34 @@ public class SubscriptionFactoryImplTest extends InternalBrokerBaseCase { //create a No-Ack subscription, get the first Subscription ID long previousId = 0; - Subscription noAckSub = SubscriptionFactoryImpl.INSTANCE.createSubscription(1, getSession(), new AMQShortString("1"), false, null, false, getChannel().getCreditManager()); + Subscription noAckSub = SubscriptionFactoryImpl.INSTANCE.createSubscription(1, _session, new AMQShortString("1"), false, null, false, _channel.getCreditManager()); previousId = noAckSub.getSubscriptionID(); //create an ack subscription, verify the next Subscription ID is used - Subscription ackSub = SubscriptionFactoryImpl.INSTANCE.createSubscription(1, getSession(), new AMQShortString("1"), true, null, false, getChannel().getCreditManager()); + Subscription ackSub = SubscriptionFactoryImpl.INSTANCE.createSubscription(1, _session, new AMQShortString("1"), true, null, false, _channel.getCreditManager()); assertEquals("Unexpected Subscription ID allocated", previousId + 1, ackSub.getSubscriptionID()); previousId = ackSub.getSubscriptionID(); //create a browser subscription FieldTable filters = new FieldTable(); filters.put(AMQPFilterTypes.NO_CONSUME.getValue(), true); - Subscription browerSub = SubscriptionFactoryImpl.INSTANCE.createSubscription(1, getSession(), new AMQShortString("1"), true, null, false, getChannel().getCreditManager()); + Subscription browerSub = SubscriptionFactoryImpl.INSTANCE.createSubscription(1, _session, new AMQShortString("1"), true, null, false, _channel.getCreditManager()); assertEquals("Unexpected Subscription ID allocated", previousId + 1, browerSub.getSubscriptionID()); previousId = browerSub.getSubscriptionID(); //create an BasicGet NoAck subscription - Subscription getNoAckSub = SubscriptionFactoryImpl.INSTANCE.createBasicGetNoAckSubscription(getChannel(), getSession(), new AMQShortString("1"), null, false, - getChannel().getCreditManager(),getChannel().getClientDeliveryMethod(), getChannel().getRecordDeliveryMethod()); + Subscription getNoAckSub = SubscriptionFactoryImpl.INSTANCE.createBasicGetNoAckSubscription(_channel, _session, new AMQShortString("1"), null, false, + _channel.getCreditManager(),_channel.getClientDeliveryMethod(), _channel.getRecordDeliveryMethod()); assertEquals("Unexpected Subscription ID allocated", previousId + 1, getNoAckSub.getSubscriptionID()); previousId = getNoAckSub.getSubscriptionID(); //create a 0-10 subscription ServerConnection conn = new ServerConnection(1); - ProtocolEngine_0_10 engine = new ProtocolEngine_0_10(conn, new TestNetworkConnection(), getRegistry()); - conn.setVirtualHost(getVirtualHost()); - conn.setConnectionConfig(engine); + ProtocolEngine_0_10 engine = new ProtocolEngine_0_10(conn, new TestNetworkConnection()); + conn.setVirtualHost(_session.getVirtualHost()); ServerSessionDelegate sesDel = new ServerSessionDelegate(); Binary name = new Binary(new byte[]{new Byte("1")}); - ServerSession session = new ServerSession(conn, sesDel, name, 0, engine); + ServerSession session = new ServerSession(conn, sesDel, name, 0); Subscription sub_0_10 = SubscriptionFactoryImpl.INSTANCE.createSubscription(session, "1", MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED, MessageFlowMode.WINDOW, new WindowCreditManager(), null, null); diff --git a/java/broker/src/test/java/org/apache/qpid/server/transport/ServerSessionTest.java b/java/broker/src/test/java/org/apache/qpid/server/transport/ServerSessionTest.java index d775b0f2f8..3389773ff8 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/transport/ServerSessionTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/transport/ServerSessionTest.java @@ -1,5 +1,4 @@ /* - * * 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 @@ -16,19 +15,17 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - * */ package org.apache.qpid.server.transport; -import java.util.UUID; - -import org.apache.qpid.server.configuration.MockConnectionConfig; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.util.InternalBrokerBaseCase; +import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.logging.actors.GenericActor; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.test.utils.QpidTestCase; import org.apache.qpid.transport.Binary; -public class ServerSessionTest extends InternalBrokerBaseCase +public class ServerSessionTest extends QpidTestCase { private VirtualHost _virtualHost; @@ -37,31 +34,44 @@ public class ServerSessionTest extends InternalBrokerBaseCase public void setUp() throws Exception { super.setUp(); - _virtualHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHosts().iterator().next(); + BrokerTestHelper.setUp(); + _virtualHost = BrokerTestHelper.createVirtualHost(getName()); + GenericActor.setDefaultMessageLogger(CurrentActor.get().getRootMessageLogger()); + } + + @Override + public void tearDown() throws Exception + { + try + { + if (_virtualHost != null) + { + _virtualHost.close(); + } + } + finally + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } } public void testCompareTo() throws Exception { ServerConnection connection = new ServerConnection(1); - connection.setConnectionConfig(createConnectionConfig()); + connection.setVirtualHost(_virtualHost); ServerSession session1 = new ServerSession(connection, new ServerSessionDelegate(), - new Binary(getName().getBytes()), 0 , connection.getConfig()); + new Binary(getName().getBytes()), 0); // create a session with the same name but on a different connection ServerConnection connection2 = new ServerConnection(2); - connection2.setConnectionConfig(createConnectionConfig()); + connection2.setVirtualHost(_virtualHost); ServerSession session2 = new ServerSession(connection2, new ServerSessionDelegate(), - new Binary(getName().getBytes()), 0 , connection2.getConfig()); + new Binary(getName().getBytes()), 0); assertFalse("Unexpected compare result", session1.compareTo(session2) == 0); assertEquals("Unexpected compare result", 0, session1.compareTo(session1)); } - private MockConnectionConfig createConnectionConfig() - { - return new MockConnectionConfig(UUID.randomUUID(), null, null, - false, 1, _virtualHost, "address", Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, - "authid", "remoteProcessName", new Integer(1967), new Integer(1970), _virtualHost.getConfigStore(), Boolean.FALSE); - } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/txn/AsyncAutoCommitTransactionTest.java b/java/broker/src/test/java/org/apache/qpid/server/txn/AsyncAutoCommitTransactionTest.java index 1aa91fa98a..5c1012d50b 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/txn/AsyncAutoCommitTransactionTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/txn/AsyncAutoCommitTransactionTest.java @@ -82,7 +82,7 @@ public class AsyncAutoCommitTransactionTest extends QpidTestCase AsyncAutoCommitTransaction asyncAutoCommitTransaction = new AsyncAutoCommitTransaction(_messageStore, _futureRecorder); - asyncAutoCommitTransaction.enqueue(Collections.singletonList(_queue), _message, _postTransactionAction, System.currentTimeMillis()); + asyncAutoCommitTransaction.enqueue(Collections.singletonList(_queue), _message, _postTransactionAction); verify(_storeTransaction).enqueueMessage(_queue, _message); verify(_futureRecorder).recordFuture(_future, _postTransactionAction); diff --git a/java/broker/src/test/java/org/apache/qpid/server/txn/AutoCommitTransactionTest.java b/java/broker/src/test/java/org/apache/qpid/server/txn/AutoCommitTransactionTest.java index cd3fe3c473..06b8539eb1 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/txn/AutoCommitTransactionTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/txn/AutoCommitTransactionTest.java @@ -137,7 +137,7 @@ public class AutoCommitTransactionTest extends QpidTestCase _message = createTestMessage(false); _queues = createTestBaseQueues(new boolean[] {false, false, false}); - _transaction.enqueue(_queues, _message, _action, 0L); + _transaction.enqueue(_queues, _message, _action); assertEquals("Enqueue of non-persistent message must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages()); assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState()); @@ -157,7 +157,7 @@ public class AutoCommitTransactionTest extends QpidTestCase _message = createTestMessage(true); _queues = createTestBaseQueues(new boolean[] {false, false, false}); - _transaction.enqueue(_queues, _message, _action, 0L); + _transaction.enqueue(_queues, _message, _action); assertEquals("Enqueue of persistent message to non-durable queues must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages()); assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState()); @@ -175,7 +175,7 @@ public class AutoCommitTransactionTest extends QpidTestCase _message = createTestMessage(true); _queues = createTestBaseQueues(new boolean[] {false, true, false, true}); - _transaction.enqueue(_queues, _message, _action, 0L); + _transaction.enqueue(_queues, _message, _action); assertEquals("Enqueue of persistent message to durable/non-durable queues must cause messages to be enqueued", 2, _storeTransaction.getNumberOfEnqueuedMessages()); assertEquals("Unexpected transaction state", TransactionState.COMMITTED, _storeTransaction.getState()); @@ -198,7 +198,7 @@ public class AutoCommitTransactionTest extends QpidTestCase try { - _transaction.enqueue(_queues, _message, _action, 0L); + _transaction.enqueue(_queues, _message, _action); fail("Exception not thrown"); } catch (RuntimeException re) diff --git a/java/broker/src/test/java/org/apache/qpid/server/txn/LocalTransactionTest.java b/java/broker/src/test/java/org/apache/qpid/server/txn/LocalTransactionTest.java index 5992829f37..4904cbc6fb 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/txn/LocalTransactionTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/txn/LocalTransactionTest.java @@ -140,7 +140,7 @@ public class LocalTransactionTest extends QpidTestCase _message = createTestMessage(false); _queues = createTestBaseQueues(new boolean[] {false, false, false}); - _transaction.enqueue(_queues, _message, _action1, 0L); + _transaction.enqueue(_queues, _message, _action1); assertEquals("Enqueue of non-persistent message must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages()); assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState()); @@ -156,7 +156,7 @@ public class LocalTransactionTest extends QpidTestCase _message = createTestMessage(true); _queues = createTestBaseQueues(new boolean[] {false, false, false}); - _transaction.enqueue(_queues, _message, _action1, 0L); + _transaction.enqueue(_queues, _message, _action1); assertEquals("Enqueue of persistent message to non-durable queues must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages()); assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState()); @@ -173,7 +173,7 @@ public class LocalTransactionTest extends QpidTestCase _message = createTestMessage(true); _queues = createTestBaseQueues(new boolean[] {false, true, false, true}); - _transaction.enqueue(_queues, _message, _action1, 0L); + _transaction.enqueue(_queues, _message, _action1); assertEquals("Enqueue of persistent message to durable/non-durable queues must cause messages to be enqueued", 2, _storeTransaction.getNumberOfEnqueuedMessages()); assertEquals("Unexpected transaction state", TransactionState.STARTED, _storeTransaction.getState()); @@ -196,7 +196,7 @@ public class LocalTransactionTest extends QpidTestCase try { - _transaction.enqueue(_queues, _message, _action1, 0L); + _transaction.enqueue(_queues, _message, _action1); fail("Exception not thrown"); } catch (RuntimeException re) @@ -217,7 +217,7 @@ public class LocalTransactionTest extends QpidTestCase { _message = createTestMessage(false); _queue = createTestAMQQueue(false); - + _transaction.dequeue(_queue, _message, _action1); assertEquals("Dequeue of non-persistent message must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages()); @@ -465,7 +465,6 @@ public class LocalTransactionTest extends QpidTestCase */ public void testRollbackWorkWithAdditionalPostAction() throws Exception { - _message = createTestMessage(true); _queue = createTestAMQQueue(true); @@ -482,6 +481,122 @@ public class LocalTransactionTest extends QpidTestCase assertTrue("Rollback action2 must be fired", _action1.isRollbackActionFired()); } + public void testFirstEnqueueRecordsTransactionStartAndUpdateTime() throws Exception + { + assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime()); + assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime()); + + _message = createTestMessage(true); + _queue = createTestAMQQueue(true); + + long startTime = System.currentTimeMillis(); + _transaction.enqueue(_queue, _message, _action1); + + assertTrue("Transaction start time should have been recorded", _transaction.getTransactionStartTime() >= startTime); + assertEquals("Transaction update time should be the same as transaction start time", _transaction.getTransactionStartTime(), _transaction.getTransactionUpdateTime()); + } + + public void testSubsequentEnqueueAdvancesTransactionUpdateTimeOnly() throws Exception + { + assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime()); + assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime()); + + _message = createTestMessage(true); + _queue = createTestAMQQueue(true); + + _transaction.enqueue(_queue, _message, _action1); + + final long transactionStartTimeAfterFirstEnqueue = _transaction.getTransactionStartTime(); + final long transactionUpdateTimeAfterFirstEnqueue = _transaction.getTransactionUpdateTime(); + + Thread.sleep(1); + _transaction.enqueue(_queue, _message, _action2); + + final long transactionStartTimeAfterSecondEnqueue = _transaction.getTransactionStartTime(); + final long transactionUpdateTimeAfterSecondEnqueue = _transaction.getTransactionUpdateTime(); + + assertEquals("Transaction start time after second enqueue should be unchanged", transactionStartTimeAfterFirstEnqueue, transactionStartTimeAfterSecondEnqueue); + assertTrue("Transaction update time after second enqueue should be greater than first update time", transactionUpdateTimeAfterSecondEnqueue > transactionUpdateTimeAfterFirstEnqueue); + } + + public void testFirstDequeueRecordsTransactionStartAndUpdateTime() throws Exception + { + assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime()); + assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime()); + + _message = createTestMessage(true); + _queue = createTestAMQQueue(true); + + long startTime = System.currentTimeMillis(); + _transaction.dequeue(_queue, _message, _action1); + + assertTrue("Transaction start time should have been recorded", _transaction.getTransactionStartTime() >= startTime); + assertEquals("Transaction update time should be the same as transaction start time", _transaction.getTransactionStartTime(), _transaction.getTransactionUpdateTime()); + } + + public void testMixedEnqueuesAndDequeuesAdvancesTransactionUpdateTimeOnly() throws Exception + { + assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime()); + assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime()); + + _message = createTestMessage(true); + _queue = createTestAMQQueue(true); + + _transaction.enqueue(_queue, _message, _action1); + + final long transactionStartTimeAfterFirstEnqueue = _transaction.getTransactionStartTime(); + final long transactionUpdateTimeAfterFirstEnqueue = _transaction.getTransactionUpdateTime(); + + Thread.sleep(1); + _transaction.dequeue(_queue, _message, _action2); + + final long transactionStartTimeAfterFirstDequeue = _transaction.getTransactionStartTime(); + final long transactionUpdateTimeAfterFirstDequeue = _transaction.getTransactionUpdateTime(); + + assertEquals("Transaction start time after first dequeue should be unchanged", transactionStartTimeAfterFirstEnqueue, transactionStartTimeAfterFirstDequeue); + assertTrue("Transaction update time after first dequeue should be greater than first update time", transactionUpdateTimeAfterFirstDequeue > transactionUpdateTimeAfterFirstEnqueue); + } + + public void testCommitResetsTransactionStartAndUpdateTime() throws Exception + { + assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime()); + assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime()); + + _message = createTestMessage(true); + _queue = createTestAMQQueue(true); + + long startTime = System.currentTimeMillis(); + _transaction.enqueue(_queue, _message, _action1); + + assertTrue(_transaction.getTransactionStartTime() >= startTime); + assertTrue(_transaction.getTransactionUpdateTime() >= startTime); + + _transaction.commit(); + + assertEquals("Transaction start time should be reset after commit", 0, _transaction.getTransactionStartTime()); + assertEquals("Transaction update time should be reset after commit", 0, _transaction.getTransactionUpdateTime()); + } + + public void testRollbackResetsTransactionStartAndUpdateTime() throws Exception + { + assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime()); + assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime()); + + _message = createTestMessage(true); + _queue = createTestAMQQueue(true); + + long startTime = System.currentTimeMillis(); + _transaction.enqueue(_queue, _message, _action1); + + assertTrue(_transaction.getTransactionStartTime() >= startTime); + assertTrue(_transaction.getTransactionUpdateTime() >= startTime); + + _transaction.rollback(); + + assertEquals("Transaction start time should be reset after rollback", 0, _transaction.getTransactionStartTime()); + assertEquals("Transaction update time should be reset after rollback", 0, _transaction.getTransactionUpdateTime()); + } + private Collection<QueueEntry> createTestQueueEntries(boolean[] queueDurableFlags, boolean[] messagePersistentFlags) { Collection<QueueEntry> queueEntries = new ArrayList<QueueEntry>(); diff --git a/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java b/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java index f3b6cab626..aa5b555b3b 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java +++ b/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java @@ -22,7 +22,6 @@ package org.apache.qpid.server.txn; import org.apache.commons.lang.NotImplementedException; -import org.apache.qpid.server.configuration.SessionConfig; import org.apache.qpid.server.message.AMQMessageHeader; import org.apache.qpid.server.message.MessageReference; import org.apache.qpid.server.message.ServerMessage; @@ -68,11 +67,6 @@ class MockServerMessage implements ServerMessage throw new NotImplementedException(); } - public SessionConfig getSessionConfig() - { - throw new NotImplementedException(); - } - public String getRoutingKey() { throw new NotImplementedException(); diff --git a/java/broker/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java b/java/broker/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java new file mode 100644 index 0000000000..3be8927224 --- /dev/null +++ b/java/broker/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java @@ -0,0 +1,209 @@ +/* + * + * 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.util; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.SocketAddress; +import java.util.Collections; +import java.util.UUID; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.abstraction.MessagePublishInfo; +import org.apache.qpid.server.AMQChannel; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; +import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore; +import org.apache.qpid.server.exchange.DefaultExchangeFactory; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.logging.SystemOutMessageLogger; +import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.logging.actors.GenericActor; +import org.apache.qpid.server.logging.actors.TestLogActor; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.protocol.AMQProtocolSession; +import org.apache.qpid.server.protocol.InternalTestProtocolSession; +import org.apache.qpid.server.queue.AMQQueueFactory; +import org.apache.qpid.server.queue.SimpleAMQQueue; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.stats.StatisticsGatherer; +import org.apache.qpid.server.store.TestableMemoryMessageStore; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.virtualhost.VirtualHostImpl; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; + +public class BrokerTestHelper +{ + + protected static final String BROKER_STORE_CLASS_NAME_KEY = "brokerstore.class.name"; + protected static final String JSON_BROKER_STORE_CLASS_NAME = JsonConfigurationEntryStore.class.getName(); + + public static Broker createBrokerMock() + { + SubjectCreator subjectCreator = mock(SubjectCreator.class); + when(subjectCreator.getMechanisms()).thenReturn(""); + Broker broker = mock(Broker.class); + when(broker.getAttribute(Broker.SESSION_COUNT_LIMIT)).thenReturn(1); + when(broker.getAttribute(Broker.HOUSEKEEPING_CHECK_PERIOD)).thenReturn(10000l); + when(broker.getId()).thenReturn(UUID.randomUUID()); + when(broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(subjectCreator); + RootMessageLogger rootMessageLogger = CurrentActor.get().getRootMessageLogger(); + when(broker.getRootMessageLogger()).thenReturn(rootMessageLogger); + when(broker.getVirtualHostRegistry()).thenReturn(new VirtualHostRegistry()); + when(broker.getSecurityManager()).thenReturn(new SecurityManager(null)); + GenericActor.setDefaultMessageLogger(rootMessageLogger); + return broker; + } + + public static void setUp() + { + CurrentActor.set(new TestLogActor(new SystemOutMessageLogger())); + } + + public static void tearDown() + { + CurrentActor.remove(); + } + + public static VirtualHost createVirtualHost(VirtualHostConfiguration virtualHostConfiguration, VirtualHostRegistry virtualHostRegistry) + throws Exception + { + StatisticsGatherer statisticsGatherer = mock(StatisticsGatherer.class); + VirtualHost host = new VirtualHostImpl(virtualHostRegistry, statisticsGatherer, new SecurityManager(null), virtualHostConfiguration); + virtualHostRegistry.registerVirtualHost(host); + return host; + } + + public static VirtualHost createVirtualHost(VirtualHostConfiguration virtualHostConfiguration) throws Exception + { + return new VirtualHostImpl(null, mock(StatisticsGatherer.class), new SecurityManager(null), virtualHostConfiguration); + } + + public static VirtualHost createVirtualHost(String name, VirtualHostRegistry virtualHostRegistry) throws Exception + { + VirtualHostConfiguration vhostConfig = createVirtualHostConfiguration(name); + return createVirtualHost(vhostConfig, virtualHostRegistry); + } + + public static VirtualHost createVirtualHost(String name) throws Exception + { + VirtualHostConfiguration configuration = createVirtualHostConfiguration(name); + return createVirtualHost(configuration); + } + + private static VirtualHostConfiguration createVirtualHostConfiguration(String name) throws ConfigurationException + { + VirtualHostConfiguration vhostConfig = new VirtualHostConfiguration(name, new PropertiesConfiguration(), createBrokerMock()); + vhostConfig.setMessageStoreClass(TestableMemoryMessageStore.class.getName()); + return vhostConfig; + } + + public static AMQChannel createChannel(int channelId, AMQProtocolSession session) throws AMQException + { + AMQChannel channel = new AMQChannel(session, channelId, session.getVirtualHost().getMessageStore()); + session.addChannel(channel); + return channel; + } + + public static AMQChannel createChannel(int channelId) throws Exception + { + InternalTestProtocolSession session = createSession(); + return createChannel(channelId, session); + } + + public static AMQChannel createChannel() throws Exception + { + return createChannel(1); + } + + public static InternalTestProtocolSession createSession() throws Exception + { + return createSession("test"); + } + + public static InternalTestProtocolSession createSession(String hostName) throws Exception + { + VirtualHost virtualHost = createVirtualHost(hostName); + return new InternalTestProtocolSession(virtualHost, createBrokerMock()); + } + + public static Exchange createExchange(String hostName) throws Exception + { + SecurityManager securityManager = new SecurityManager(null); + VirtualHost virtualHost = mock(VirtualHost.class); + when(virtualHost.getName()).thenReturn(hostName); + when(virtualHost.getSecurityManager()).thenReturn(securityManager); + DefaultExchangeFactory factory = new DefaultExchangeFactory(virtualHost); + return factory.createExchange("amp.direct", "direct", false, false); + } + + public static void publishMessages(AMQChannel channel, int numberOfMessages, String queueName, String exchangeName) throws AMQException + { + AMQShortString rouningKey = new AMQShortString(queueName); + AMQShortString exchangeNameAsShortString = new AMQShortString(exchangeName); + MessagePublishInfo info = mock(MessagePublishInfo.class); + when(info.getExchange()).thenReturn(exchangeNameAsShortString); + when(info.getRoutingKey()).thenReturn(rouningKey); + + Exchange exchange = channel.getVirtualHost().getExchangeRegistry().getExchange(exchangeName); + for (int count = 0; count < numberOfMessages; count++) + { + channel.setPublishFrame(info, exchange); + + // Set the body size + ContentHeaderBody _headerBody = new ContentHeaderBody(); + _headerBody.setBodySize(0); + + // Set Minimum properties + BasicContentHeaderProperties properties = new BasicContentHeaderProperties(); + + properties.setExpiration(0L); + properties.setTimestamp(System.currentTimeMillis()); + + // Make Message Persistent + properties.setDeliveryMode((byte) 2); + + _headerBody.setProperties(properties); + + channel.publishContentHeader(_headerBody); + } + channel.sync(); + } + + public static SimpleAMQQueue createQueue(String queueName, VirtualHost virtualHost) throws AMQException + { + SimpleAMQQueue queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), queueName, false, null, + false, false, virtualHost, Collections.<String, Object>emptyMap()); + virtualHost.getQueueRegistry().registerQueue(queue); + return queue; + } + + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java b/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java deleted file mode 100644 index d7a9078412..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java +++ /dev/null @@ -1,372 +0,0 @@ -/* - * - * 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.util; - -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.XMLConfiguration; - -import org.apache.qpid.AMQException; -import org.apache.qpid.common.AMQPFilterTypes; -import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.abstraction.MessagePublishInfo; -import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.logging.SystemOutMessageLogger; -import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.logging.actors.TestLogActor; -import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.protocol.InternalTestProtocolSession; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.queue.AMQQueueFactory; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.store.MessageStore; -import org.apache.qpid.server.store.TestableMemoryMessageStore; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.test.utils.QpidTestCase; - - -public class InternalBrokerBaseCase extends QpidTestCase -{ - private IApplicationRegistry _registry; - private MessageStore _messageStore; - private AMQChannel _channel; - private InternalTestProtocolSession _session; - private VirtualHost _virtualHost; - private AMQQueue _queue; - private AMQShortString QUEUE_NAME; - private ServerConfiguration _configuration; - private XMLConfiguration _configXml = new XMLConfiguration(); - private boolean _started = false; - - public void setUp() throws Exception - { - super.setUp(); - - _configXml.addProperty("virtualhosts.virtualhost.name", "test"); - _configXml.addProperty("virtualhosts.virtualhost.test.store.class", TestableMemoryMessageStore.class.getName()); - - _configXml.addProperty("virtualhosts.virtualhost(-1).name", getName()); - _configXml.addProperty("virtualhosts.virtualhost(-1)."+getName()+".store.class", TestableMemoryMessageStore.class.getName()); - - createBroker(); - } - - protected void createBroker() throws Exception - { - _started = true; - CurrentActor.set(new TestLogActor(new SystemOutMessageLogger())); - - _configuration = new ServerConfiguration(_configXml); - - configure(); - - _registry = createApplicationRegistry(); - ApplicationRegistry.initialise(_registry); - _registry.getVirtualHostRegistry().setDefaultVirtualHostName(getName()); - _virtualHost = _registry.getVirtualHostRegistry().getVirtualHost(getName()); - - QUEUE_NAME = new AMQShortString("test"); - // Create a queue on the test Vhost.. this will aid in diagnosing duff tests - // as the ExpiredMessage Task will log with the test Name. - _queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), QUEUE_NAME.asString(), false, "testowner", - false, false, _virtualHost, null); - - Exchange defaultExchange = _virtualHost.getExchangeRegistry().getDefaultExchange(); - _virtualHost.getBindingFactory().addBinding(QUEUE_NAME.toString(), _queue, defaultExchange, null); - - _virtualHost = _registry.getVirtualHostRegistry().getVirtualHost("test"); - _messageStore = _virtualHost.getMessageStore(); - - _queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), getName(), false, "testowner", - false, false, _virtualHost, null); - - _virtualHost.getQueueRegistry().registerQueue(_queue); - - defaultExchange = _virtualHost.getExchangeRegistry().getDefaultExchange(); - - _virtualHost.getBindingFactory().addBinding(getName(), _queue, defaultExchange, null); - - _session = new InternalTestProtocolSession(_virtualHost); - CurrentActor.set(_session.getLogActor()); - - _channel = new AMQChannel(_session, 1, _messageStore); - - _session.addChannel(_channel); - } - - protected IApplicationRegistry createApplicationRegistry() throws ConfigurationException - { - return new TestApplicationRegistry(_configuration); - } - - protected void configure() - { - // Allow other tests to override configuration - } - - protected void stopBroker() - { - try - { - //Remove the ProtocolSession Actor added during createBroker - CurrentActor.remove(); - } - finally - { - ApplicationRegistry.remove(); - _started = false; - } - } - - - public void tearDown() throws Exception - { - try - { - if (_started) - { - stopBroker(); - } - } - finally - { - super.tearDown(); - // Purge Any erroneously added actors - CurrentActor.removeAll(); - } - } - - protected void checkStoreContents(int messageCount) - { - assertEquals("Message header count incorrect in the MetaDataMap", messageCount, ((TestableMemoryMessageStore) _messageStore).getMessageCount()); - - //The above publish message is sufficiently small not to fit in the header so no Body is required. - //assertEquals("Message body count incorrect in the ContentBodyMap", messageCount, ((TestableMemoryMessageStore) _messageStore).getContentBodyMap().size()); - } - - protected AMQShortString subscribe(InternalTestProtocolSession session, AMQChannel channel, AMQQueue queue) - { - try - { - return channel.subscribeToQueue(null, queue, true, null, false, true); - } - catch (AMQException e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - - //Keep the compiler happy - return null; - } - - protected AMQShortString browse(AMQChannel channel, AMQQueue queue) - { - try - { - FieldTable filters = new FieldTable(); - filters.put(AMQPFilterTypes.NO_CONSUME.getValue(), true); - - return channel.subscribeToQueue(null, queue, true, filters, false, true); - } - catch (AMQException e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - - //Keep the compiler happy - return null; - } - - public void publishMessages(InternalTestProtocolSession session, AMQChannel channel, int messages) throws AMQException - { - MessagePublishInfo info = new MessagePublishInfo() - { - public AMQShortString getExchange() - { - return ExchangeDefaults.DEFAULT_EXCHANGE_NAME; - } - - public void setExchange(AMQShortString exchange) - { - - } - - public boolean isImmediate() - { - return false; - } - - public boolean isMandatory() - { - return false; - } - - public AMQShortString getRoutingKey() - { - return new AMQShortString(getName()); - } - }; - - for (int count = 0; count < messages; count++) - { - channel.setPublishFrame(info, _virtualHost.getExchangeRegistry().getExchange(info.getExchange())); - - //Set the body size - ContentHeaderBody _headerBody = new ContentHeaderBody(); - _headerBody.setBodySize(0); - - //Set Minimum properties - BasicContentHeaderProperties properties = new BasicContentHeaderProperties(); - - properties.setExpiration(0L); - properties.setTimestamp(System.currentTimeMillis()); - - //Make Message Persistent - properties.setDeliveryMode((byte) 2); - - _headerBody.setProperties(properties); - - channel.publishContentHeader(_headerBody); - } - channel.sync(); - } - - public void acknowledge(AMQChannel channel, long deliveryTag) - { - try - { - channel.acknowledgeMessage(deliveryTag, false); - } - catch (AMQException e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - } - - public IApplicationRegistry getRegistry() - { - return _registry; - } - - public void setRegistry(IApplicationRegistry registry) - { - _registry = registry; - } - - public MessageStore getMessageStore() - { - return _messageStore; - } - - public void setMessageStore(MessageStore messageStore) - { - _messageStore = messageStore; - } - - public AMQChannel getChannel() - { - return _channel; - } - - public void setChannel(AMQChannel channel) - { - _channel = channel; - } - - public InternalTestProtocolSession getSession() - { - return _session; - } - - public void setSession(InternalTestProtocolSession session) - { - _session = session; - } - - public VirtualHost getVirtualHost() - { - return _virtualHost; - } - - public void setVirtualHost(VirtualHost virtualHost) - { - _virtualHost = virtualHost; - } - - public AMQQueue getQueue() - { - return _queue; - } - - public void setQueue(AMQQueue queue) - { - _queue = queue; - } - - public AMQShortString getQUEUE_NAME() - { - return QUEUE_NAME; - } - - public void setQUEUE_NAME(AMQShortString QUEUE_NAME) - { - this.QUEUE_NAME = QUEUE_NAME; - } - - public ServerConfiguration getConfiguration() - { - return _configuration; - } - - public void setConfiguration(ServerConfiguration configuration) - { - _configuration = configuration; - } - - public XMLConfiguration getConfigXml() - { - return _configXml; - } - - public void setConfigXml(XMLConfiguration configXml) - { - _configXml = configXml; - } - - public boolean isStarted() - { - return _started; - } - - public void setStarted(boolean started) - { - _started = started; - } -} diff --git a/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java b/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java deleted file mode 100644 index a64ab620ab..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * - * 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.util; - -import java.net.SocketAddress; -import java.util.Collections; -import java.util.Map; -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.logging.NullRootMessageLogger; -import org.apache.qpid.server.logging.actors.BrokerActor; -import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.logging.actors.GenericActor; -import org.apache.qpid.server.plugins.PluginManager; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.security.auth.database.PropertiesPrincipalDatabase; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; -import org.apache.qpid.server.security.auth.manager.IAuthenticationManagerRegistry; -import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager; - -import java.util.Properties; - -public class TestApplicationRegistry extends ApplicationRegistry -{ - - public TestApplicationRegistry(ServerConfiguration config) throws ConfigurationException - { - super(config); - } - - @Override - public void initialise() throws Exception - { - CurrentActor.setDefault(new BrokerActor(new NullRootMessageLogger())); - GenericActor.setDefaultMessageLogger(new NullRootMessageLogger()); - super.initialise(); - } - - @Override - protected IAuthenticationManagerRegistry createAuthenticationManagerRegistry( - ServerConfiguration _configuration, PluginManager _pluginManager) - throws ConfigurationException - { - final Properties users = new Properties(); - users.put("guest","guest"); - users.put("admin","admin"); - - final PropertiesPrincipalDatabase ppd = new PropertiesPrincipalDatabase(users); - - final AuthenticationManager pdam = new PrincipalDatabaseAuthenticationManager() - { - - /** - * @see org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager#configure(org.apache.qpid.server.configuration.plugins.ConfigurationPlugin) - */ - @Override - public void configure(ConfigurationPlugin config) throws ConfigurationException - { - // We don't pass configuration to this test instance. - } - - @Override - public void initialise() - { - setPrincipalDatabase(ppd); - - super.initialise(); - } - }; - pdam.initialise(); - - return new IAuthenticationManagerRegistry() - { - @Override - public void close() - { - pdam.close(); - } - - @Override - public AuthenticationManager getAuthenticationManager( - SocketAddress address) - { - return pdam; - } - - @Override - public Map<String, AuthenticationManager> getAvailableAuthenticationManagers() - { - return Collections.singletonMap(pdam.getClass().getName(), pdam); - } - - @Override - public void addRegistryChangeListener(RegistryChangeListener listener) - { - } - }; - } -} - - diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java index 290c465785..1d99d99820 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java +++ b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java @@ -22,26 +22,18 @@ package org.apache.qpid.server.virtualhost; import java.util.concurrent.ScheduledFuture; import org.apache.qpid.server.binding.BindingFactory; -import org.apache.qpid.server.configuration.BrokerConfig; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.VirtualHostConfig; -import org.apache.qpid.server.configuration.VirtualHostConfigType; import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.connection.IConnectionRegistry; import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.protocol.v1_0.LinkRegistry; import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.security.SecurityManager; import org.apache.qpid.server.security.auth.manager.AuthenticationManager; import org.apache.qpid.server.stats.StatisticsCounter; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.txn.DtxRegistry; -import java.util.Map; import java.util.UUID; public class MockVirtualHost implements VirtualHost @@ -58,19 +50,8 @@ public class MockVirtualHost implements VirtualHost } - public void createBrokerConnection(String transport, String host, int port, - String vhost, boolean durable, String authMechanism, - String username, String password) - { - - } - - public BrokerLink createBrokerConnection(final UUID id, final long createTime, final Map<String, String> arguments) - { - return null; - } - - public IApplicationRegistry getApplicationRegistry() + @Override + public VirtualHostRegistry getVirtualHostRegistry() { return null; } @@ -85,16 +66,6 @@ public class MockVirtualHost implements VirtualHost return null; } - public UUID getBrokerId() - { - return null; - } - - public ConfigStore getConfigStore() - { - return null; - } - public DtxRegistry getDtxRegistry() { return null; @@ -160,12 +131,6 @@ public class MockVirtualHost implements VirtualHost return null; } - - public void removeBrokerConnection(BrokerLink brokerLink) - { - - } - public LinkRegistry getLinkRegistry(String remoteContainerId) { return null; @@ -186,25 +151,6 @@ public class MockVirtualHost implements VirtualHost } - public BrokerConfig getBroker() - { - return null; - } - - public String getFederationTag() - { - return null; - } - - public void setBroker(BrokerConfig brokerConfig) - { - - } - - public VirtualHostConfigType getConfigType() - { - return null; - } public long getCreateTime() { @@ -216,17 +162,6 @@ public class MockVirtualHost implements VirtualHost return null; } - @Override - public UUID getQMFId() - { - return null; - } - - public ConfiguredObject<VirtualHostConfigType, VirtualHostConfig> getParent() - { - return null; - } - public boolean isDurable() { return false; diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java index b8ba76e43d..559a7f8aaf 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java @@ -20,15 +20,21 @@ */ package org.apache.qpid.server.virtualhost; +import static org.mockito.Mockito.mock; + +import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.XMLConfiguration; +import org.apache.commons.configuration.PropertiesConfiguration; + +import org.apache.qpid.server.configuration.VirtualHostConfiguration; -import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.stats.StatisticsGatherer; import org.apache.qpid.server.store.MemoryMessageStore; -import org.apache.qpid.server.util.TestApplicationRegistry; +import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.test.utils.QpidTestCase; import java.io.BufferedWriter; @@ -38,15 +44,31 @@ import java.io.IOException; public class VirtualHostImplTest extends QpidTestCase { - private ServerConfiguration _configuration; - private ApplicationRegistry _registry; + private VirtualHostRegistry _virtualHostRegistry; + + @Override + public void setUp() throws Exception + { + super.setUp(); + BrokerTestHelper.setUp(); + } @Override public void tearDown() throws Exception { - super.tearDown(); + try + { + if (_virtualHostRegistry != null) + { + _virtualHostRegistry.close(); + } + } + finally + { + BrokerTestHelper.tearDown(); + super.tearDown(); + } - ApplicationRegistry.remove(); } /** @@ -74,17 +96,23 @@ public class VirtualHostImplTest extends QpidTestCase */ public void testSpecifyingCustomBindingForDefaultExchangeThrowsException() throws Exception { - File config = writeConfigFile(getName(), getName(), null, false, new String[]{"custom-binding"}); + final String queueName = getName(); + final String customBinding = "custom-binding"; + File config = writeConfigFile(queueName, queueName, null, false, new String[]{customBinding}); try { - createVirtualHost(getName(), config); + createVirtualHost(queueName, config); fail("virtualhost creation should have failed due to illegal configuration"); } catch (RuntimeException e) { + assertNotNull(e.getCause()); + assertEquals(ConfigurationException.class, e.getCause().getClass()); - //expected + + Throwable configException = e.getCause(); + assertEquals("Illegal attempt to bind queue '" + queueName + "' to the default exchange with a key other than the queue name: " + customBinding, configException.getMessage()); } } @@ -96,6 +124,14 @@ public class VirtualHostImplTest extends QpidTestCase assertEquals(State.ACTIVE, vhost.getState()); } + public void testVirtualHostHavingStoreSetAsTypeBecomesActive() throws Exception + { + String virtualHostName = getName(); + VirtualHost host = createVirtualHostUsingStoreType(virtualHostName); + assertNotNull(host); + assertEquals(State.ACTIVE, host.getState()); + } + public void testVirtualHostBecomesStoppedOnClose() throws Exception { File config = writeConfigFile(getName(), getName(), getName() +".direct", false, new String[0]); @@ -107,22 +143,39 @@ public class VirtualHostImplTest extends QpidTestCase assertEquals(0, vhost.getHouseKeepingActiveCount()); } + public void testVirtualHostHavingStoreSetAsTypeBecomesStoppedOnClose() throws Exception + { + String virtualHostName = getName(); + VirtualHost host = createVirtualHostUsingStoreType(virtualHostName); + assertNotNull(host); + assertEquals(State.ACTIVE, host.getState()); + host.close(); + assertEquals(State.STOPPED, host.getState()); + assertEquals(0, host.getHouseKeepingActiveCount()); + } + /** * Tests that specifying an unknown exchange to bind the queue to results in failure to create the vhost */ public void testSpecifyingUnknownExchangeThrowsException() throws Exception { - File config = writeConfigFile(getName(), getName(), "made-up-exchange", true, new String[0]); + final String queueName = getName(); + final String exchangeName = "made-up-exchange"; + File config = writeConfigFile(queueName, queueName, exchangeName, true, new String[0]); try { - createVirtualHost(getName(), config); + createVirtualHost(queueName, config); fail("virtualhost creation should have failed due to illegal configuration"); } catch (RuntimeException e) { + assertNotNull(e.getCause()); + assertEquals(ConfigurationException.class, e.getCause().getClass()); - //expected + + Throwable configException = e.getCause(); + assertEquals("Attempt to bind queue '" + queueName + "' to unknown exchange:" + exchangeName, configException.getMessage()); } } @@ -154,12 +207,14 @@ public class VirtualHostImplTest extends QpidTestCase private VirtualHost createVirtualHost(String vhostName, File config) throws Exception { - _configuration = new ServerConfiguration(new XMLConfiguration(config)); + Broker broker = BrokerTestHelper.createBrokerMock(); + _virtualHostRegistry = broker.getVirtualHostRegistry(); - _registry = new TestApplicationRegistry(_configuration); - ApplicationRegistry.initialise(_registry); + VirtualHostConfiguration configuration = new VirtualHostConfiguration(vhostName, config, broker); + VirtualHost host = new VirtualHostImpl(_virtualHostRegistry, mock(StatisticsGatherer.class), new SecurityManager(null), configuration); + _virtualHostRegistry.registerVirtualHost(host); - return _registry.getVirtualHostRegistry().getVirtualHost(vhostName); + return host; } /** @@ -184,7 +239,6 @@ public class VirtualHostImplTest extends QpidTestCase BufferedWriter writer = new BufferedWriter(fstream); //extra outer tag to please Commons Configuration - writer.write("<configuration>"); writer.write("<virtualhosts>"); writer.write(" <default>" + vhostName + "</default>"); @@ -222,8 +276,6 @@ public class VirtualHostImplTest extends QpidTestCase writer.write(" </virtualhost>"); writer.write("</virtualhosts>"); - writer.write("</configuration>"); - writer.flush(); writer.close(); } @@ -234,4 +286,17 @@ public class VirtualHostImplTest extends QpidTestCase return tmpFile; } + + private VirtualHost createVirtualHostUsingStoreType(String virtualHostName) throws ConfigurationException, Exception + { + Broker broker = BrokerTestHelper.createBrokerMock(); + _virtualHostRegistry = broker.getVirtualHostRegistry(); + + Configuration config = new PropertiesConfiguration(); + config.setProperty("store.type", MemoryMessageStore.TYPE); + VirtualHostConfiguration configuration = new VirtualHostConfiguration(virtualHostName, config, broker); + VirtualHost host = new VirtualHostImpl(_virtualHostRegistry, mock(StatisticsGatherer.class), new SecurityManager(null), configuration); + _virtualHostRegistry.registerVirtualHost(host); + return host; + } } diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionConfigurationTest.java deleted file mode 100644 index e2375c579b..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionConfigurationTest.java +++ /dev/null @@ -1,347 +0,0 @@ -/* - * - * 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.virtualhost.plugins; - -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.XMLConfiguration; - -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionConfiguration; -import org.apache.qpid.server.util.InternalBrokerBaseCase; - -import java.util.concurrent.TimeUnit; - -/** - * Provide Unit Test coverage of the virtualhost SlowConsumer Configuration - * This is what controls how often the plugin will execute - */ -public class SlowConsumerDetectionConfigurationTest extends InternalBrokerBaseCase -{ - - /** - * Default Testing: - * - * Provide a fully complete and valid configuration specifying 'delay' and - * 'timeunit' and ensure that it is correctly processed. - * - * Ensure no exceptions are thrown and that we get the same values back that - * were put into the configuration. - */ - public void testConfigLoadingValidConfig() - { - SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - - long DELAY=10; - String TIMEUNIT=TimeUnit.MICROSECONDS.toString(); - xmlconfig.addProperty("delay", String.valueOf(DELAY)); - xmlconfig.addProperty("timeunit", TIMEUNIT); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - - try - { - config.setConfiguration("", composite); - } - catch (ConfigurationException e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - - assertEquals("Delay not correctly returned.", DELAY, config.getDelay()); - assertEquals("TimeUnit not correctly returned.", - TIMEUNIT, String.valueOf(config.getTimeUnit())); - } - - /** - * Default Testing: - * - * Test Missing TimeUnit value gets default. - * - * The TimeUnit value is optional and default to SECONDS. - * - * Test that if we do not specify a TimeUnit then we correctly get seconds. - * - * Also verify that relying on the default does not impact the setting of - * the 'delay' value. - * - */ - public void testConfigLoadingMissingTimeUnitDefaults() - { - SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - - long DELAY=10; - xmlconfig.addProperty("delay", String.valueOf(DELAY)); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - try - { - config.setConfiguration("", composite); - } - catch (ConfigurationException e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - - assertEquals("Delay not correctly returned.", DELAY, config.getDelay()); - assertEquals("Default TimeUnit incorrect", TimeUnit.SECONDS, config.getTimeUnit()); - } - - /** - * Input Testing: - * - * TimeUnit parsing requires the String value be in UpperCase. - * Ensure we can handle when the user doesn't know this. - * - * Same test as 'testConfigLoadingValidConfig' but checking that - * the timeunit field is not case sensitive. - * i.e. the toUpper is being correctly applied. - */ - public void testConfigLoadingValidConfigStrangeTimeUnit() - { - SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - - long DELAY=10; - - xmlconfig.addProperty("delay", DELAY); - xmlconfig.addProperty("timeunit", "MiCrOsEcOnDs"); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - - try - { - config.setConfiguration("", composite); - } - catch (ConfigurationException e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - - assertEquals("Delay not correctly returned.", DELAY, config.getDelay()); - assertEquals("TimeUnit not correctly returned.", - TimeUnit.MICROSECONDS.toString(), String.valueOf(config.getTimeUnit())); - - } - - /** - * Failure Testing: - * - * Test that delay must be long not a string value. - * Provide a delay as a written value not a long. 'ten'. - * - * This should throw a configuration exception which is being trapped and - * verified to be the right exception, a NumberFormatException. - * - */ - public void testConfigLoadingInValidDelayString() - { - SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - - xmlconfig.addProperty("delay", "ten"); - xmlconfig.addProperty("timeunit", TimeUnit.MICROSECONDS.toString()); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - - try - { - config.setConfiguration("", composite); - fail("Configuration should fail to validate"); - } - catch (ConfigurationException e) - { - Throwable cause = e.getCause(); - - assertEquals("Cause not correct", NumberFormatException.class, cause.getClass()); - } - } - - /** - * Failure Testing: - * - * Test that negative delays are invalid. - * - * Delay must be a positive value as negative delay means doesn't make sense. - * - * Configuration exception with a useful message should be thrown here. - * - */ - public void testConfigLoadingInValidDelayNegative() - { - SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - - xmlconfig.addProperty("delay", "-10"); - xmlconfig.addProperty("timeunit", TimeUnit.MICROSECONDS.toString()); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - - try - { - config.setConfiguration("", composite); - fail("Configuration should fail to validate"); - } - catch (ConfigurationException e) - { - Throwable cause = e.getCause(); - - assertNotNull("Configuration Exception must not be null.", cause); - assertEquals("Cause not correct", - ConfigurationException.class, cause.getClass()); - assertEquals("Incorrect message.", - "SlowConsumerDetectionConfiguration: 'delay' must be a Positive Long value.", - cause.getMessage()); - } - } - - /** - * Failure Testing: - * - * Test that delay cannot be 0. - * - * A zero delay means run constantly. This is not how VirtualHostTasks - * are designed to be run so we dis-allow the use of 0 delay. - * - * Same test as 'testConfigLoadingInValidDelayNegative' but with a 0 value. - * - */ - public void testConfigLoadingInValidDelayZero() - { - SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - - xmlconfig.addProperty("delay", "0"); - xmlconfig.addProperty("timeunit", TimeUnit.MICROSECONDS.toString()); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - - try - { - config.setConfiguration("", composite); - fail("Configuration should fail to validate"); - } - catch (ConfigurationException e) - { - Throwable cause = e.getCause(); - - assertNotNull("Configuration Exception must not be null.", cause); - assertEquals("Cause not correct", - ConfigurationException.class, cause.getClass()); - assertEquals("Incorrect message.", - "SlowConsumerDetectionConfiguration: 'delay' must be a Positive Long value.", - cause.getMessage()); - } - } - - /** - * Failure Testing: - * - * Test that missing delay fails. - * If we have no delay then we do not pick a default. So a Configuration - * Exception is thrown. - * - * */ - public void testConfigLoadingInValidMissingDelay() - { - SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - - xmlconfig.addProperty("timeunit", TimeUnit.SECONDS.toString()); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - try - { - config.setConfiguration("", composite); - fail("Configuration should fail to validate"); - } - catch (ConfigurationException e) - { - assertEquals("Incorrect message.", "SlowConsumerDetectionConfiguration: unable to configure invalid delay:null", e.getMessage()); - } - } - - /** - * Failure Testing: - * - * Test that erroneous TimeUnit fails. - * - * Valid TimeUnit values vary based on the JVM version i.e. 1.6 added HOURS/DAYS etc. - * - * We don't test the values for TimeUnit are accepted other than MILLISECONDS in the - * positive testing at the start. - * - * Here we ensure that an erroneous for TimeUnit correctly throws an exception. - * - * We test with 'foo', which will never be a TimeUnit - * - */ - public void testConfigLoadingInValidTimeUnit() - { - SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration(); - - String TIMEUNIT = "foo"; - XMLConfiguration xmlconfig = new XMLConfiguration(); - - xmlconfig.addProperty("delay", "10"); - xmlconfig.addProperty("timeunit", TIMEUNIT); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - try - { - config.setConfiguration("", composite); - fail("Configuration should fail to validate"); - } - catch (ConfigurationException e) - { - assertEquals("Incorrect message.", "Unable to configure Slow Consumer Detection invalid TimeUnit:" + TIMEUNIT, e.getMessage()); - } - } - - -} diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionPolicyConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionPolicyConfigurationTest.java deleted file mode 100644 index ea07632873..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionPolicyConfigurationTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * - * 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.virtualhost.plugins; - -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.XMLConfiguration; - -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionPolicyConfiguration; -import org.apache.qpid.server.util.InternalBrokerBaseCase; - -/** - * Test class to ensure that the policy configuration can be processed. - */ -public class SlowConsumerDetectionPolicyConfigurationTest extends InternalBrokerBaseCase -{ - - /** - * Input Testing: - * - * Test that a given String can be set and retrieved through the configuration - * - * No validation is being performed to ensure that the policy exists. Only - * that a value can be set for the policy. - * - */ - public void testConfigLoadingValidConfig() - { - SlowConsumerDetectionPolicyConfiguration config = new SlowConsumerDetectionPolicyConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - - String policyName = "TestPolicy"; - xmlconfig.addProperty("name", policyName); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - - try - { - config.setConfiguration("", composite); - } - catch (ConfigurationException e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - - assertEquals("Policy name not retrieved as expected.", - policyName, config.getPolicyName()); - } - - /** - * Failure Testing: - * - * Test that providing a configuration section without the 'name' field - * causes an exception to be thrown. - * - * An empty configuration is provided and the thrown exception message - * is checked to confirm the right reason. - * - */ - public void testConfigLoadingInValidConfig() - { - SlowConsumerDetectionPolicyConfiguration config = new SlowConsumerDetectionPolicyConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - - try - { - config.setConfiguration("", composite); - fail("Config is invalid so won't validate."); - } - catch (ConfigurationException e) - { - e.printStackTrace(); - assertEquals("Exception message not as expected.", "No Slow consumer policy defined.", e.getMessage()); - } - } - -} diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionQueueConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionQueueConfigurationTest.java deleted file mode 100644 index 96e524acf2..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionQueueConfigurationTest.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * 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.virtualhost.plugins; - -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.XMLConfiguration; - -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionQueueConfiguration; -import org.apache.qpid.server.util.InternalBrokerBaseCase; - -/** - * Unit test the QueueConfiguration processing. - * - * This is slightly awkward as the {@link SlowConsumerDetectionQueueConfiguration} - * requries that a policy be available. - * <p> - * So all the Valid test much catch the ensuing {@link ConfigurationException} and - * validate that the error is due to a lack of a valid policy. - */ -public class SlowConsumerDetectionQueueConfigurationTest extends InternalBrokerBaseCase -{ - /** - * Test a fully loaded configuration file. - * - * It is not an error to have all control values specified. - * <p> - * Here we need to catch the {@link ConfigurationException} that ensues due to lack - * of a policy plugin. - */ - public void testConfigLoadingValidConfig() - { - SlowConsumerDetectionQueueConfiguration config = new SlowConsumerDetectionQueueConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - - xmlconfig.addProperty("messageAge", "60000"); - xmlconfig.addProperty("depth", "1024"); - xmlconfig.addProperty("messageCount", "10"); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - - try - { - config.setConfiguration("", composite); - fail("No Policies are avaialbe to load in a unit test"); - } - catch (ConfigurationException e) - { - assertTrue("Exception message incorrect, was: " + e.getMessage(), - e.getMessage().startsWith("No Slow Consumer Policy specified. Known Policies:[")); - } - } - - /** - * When we do not specify any control value then a {@link ConfigurationException} - * must be thrown to remind us. - */ - public void testConfigLoadingMissingConfig() - { - SlowConsumerDetectionQueueConfiguration config = new SlowConsumerDetectionQueueConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - - try - { - config.setConfiguration("", composite); - fail("No Policies are avaialbe to load in a unit test"); - } - catch (ConfigurationException e) - { - - assertEquals("At least one configuration property('messageAge','depth'" + - " or 'messageCount') must be specified.", e.getMessage()); - } - } - - /** - * Setting messageAge on its own is enough to have a valid configuration - * - * Here we need to catch the {@link ConfigurationException} that ensues due to lack - * of a policy plugin. - */ - public void testConfigLoadingMessageAgeOk() - { - SlowConsumerDetectionQueueConfiguration config = new SlowConsumerDetectionQueueConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - xmlconfig.addProperty("messageAge", "60000"); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - - try - { - config.setConfiguration("", composite); - fail("No Policies are avaialbe to load in a unit test"); - } - catch (ConfigurationException e) - { - assertTrue("Exception message incorrect, was: " + e.getMessage(), - e.getMessage().startsWith("No Slow Consumer Policy specified. Known Policies:[")); - } - } - - /** - * Setting depth on its own is enough to have a valid configuration. - * - * Here we need to catch the {@link ConfigurationException} that ensues due to lack - * of a policy plugin. - */ - public void testConfigLoadingDepthOk() - { - SlowConsumerDetectionQueueConfiguration config = new SlowConsumerDetectionQueueConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - xmlconfig.addProperty("depth", "1024"); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - - try - { - config.setConfiguration("", composite); - fail("No Policies are avaialbe to load in a unit test"); - } - catch (ConfigurationException e) - { - assertTrue("Exception message incorrect, was: " + e.getMessage(), - e.getMessage().startsWith("No Slow Consumer Policy specified. Known Policies:[")); - } - } - - /** - * Setting messageCount on its own is enough to have a valid configuration. - * - * Here we need to catch the {@link ConfigurationException} that ensues due to lack - * of a policy plugin. - */ - public void testConfigLoadingMessageCountOk() - { - SlowConsumerDetectionQueueConfiguration config = new SlowConsumerDetectionQueueConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - xmlconfig.addProperty("messageCount", "10"); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - - try - { - config.setConfiguration("", composite); - fail("No Policies are avaialbe to load in a unit test"); - } - catch (ConfigurationException e) - { - assertTrue("Exception message incorrect, was: " + e.getMessage(), - e.getMessage().startsWith("No Slow Consumer Policy specified. Known Policies:[")); - } - } -} diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfigurationTest.java deleted file mode 100644 index f034d05c37..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfigurationTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * 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.virtualhost.plugins.policies; - -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.XMLConfiguration; - -import org.apache.qpid.server.util.InternalBrokerBaseCase; - -/** - * Test to ensure TopicDelete Policy configuration can be loaded. - */ -public class TopicDeletePolicyConfigurationTest extends InternalBrokerBaseCase -{ - /** - * Test without any configuration being provided that the - * deletePersistent option is disabled. - */ - public void testNoConfigNoDeletePersistent() - { - TopicDeletePolicyConfiguration config = new TopicDeletePolicyConfiguration(); - - assertFalse("TopicDelete Configuration with no config should not delete persistent queues.", - config.deletePersistent()); - } - - /** - * Test that with the correct configuration the deletePersistent option can - * be enabled. - * - * Test creates a new Configuration object and passes in the xml snippet - * that the ConfigurationPlugin would receive during normal execution. - * This is the XML that would be matched for this plugin: - * <topicdelete> - * <delete-persistent> - * <topicdelete> - * - * So it would be subset and passed in as just: - * <delete-persistent> - * - * - * The property should therefore be enabled. - * - */ - public void testConfigDeletePersistent() - { - TopicDeletePolicyConfiguration config = new TopicDeletePolicyConfiguration(); - - XMLConfiguration xmlconfig = new XMLConfiguration(); - - xmlconfig.addProperty("delete-persistent",""); - - // Create a CompositeConfiguration as this is what the broker uses - CompositeConfiguration composite = new CompositeConfiguration(); - composite.addConfiguration(xmlconfig); - - try - { - config.setConfiguration("",composite); - } - catch (ConfigurationException e) - { - fail(e.getMessage()); - } - - assertTrue("A configured TopicDelete should delete persistent queues.", - config.deletePersistent()); - } - -} diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyTest.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyTest.java deleted file mode 100644 index aa8448b99d..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyTest.java +++ /dev/null @@ -1,294 +0,0 @@ -/* - * - * 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.virtualhost.plugins.policies; - -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.XMLConfiguration; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.exchange.DirectExchange; -import org.apache.qpid.server.exchange.TopicExchange; -import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.protocol.InternalTestProtocolSession; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.queue.MockAMQQueue; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.util.InternalBrokerBaseCase; -import org.apache.qpid.server.virtualhost.VirtualHost; - -public class TopicDeletePolicyTest extends InternalBrokerBaseCase -{ - - private TopicDeletePolicyConfiguration _config; - - private VirtualHost _defaultVhost; - private InternalTestProtocolSession _connection; - - public void setUp() throws Exception - { - super.setUp(); - - _defaultVhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getDefaultVirtualHost(); - - _connection = new InternalTestProtocolSession(_defaultVhost); - - _config = new TopicDeletePolicyConfiguration(); - - XMLConfiguration config = new XMLConfiguration(); - - _config.setConfiguration("", config); - } - - private MockAMQQueue createOwnedQueue() - { - MockAMQQueue queue = new MockAMQQueue("testQueue"); - - _defaultVhost.getQueueRegistry().registerQueue(queue); - - try - { - AMQChannel channel = new AMQChannel(_connection, 0, null); - _connection.addChannel(channel); - - queue.setExclusiveOwningSession(channel); - } - catch (AMQException e) - { - fail("Unable to create Channel:" + e.getMessage()); - } - - return queue; - } - - private void setQueueToAutoDelete(final AMQQueue queue) - { - ((MockAMQQueue) queue).setAutoDelete(true); - - queue.setDeleteOnNoConsumers(true); - final AMQProtocolSession.Task deleteQueueTask = - new AMQProtocolSession.Task() - { - public void doTask(AMQProtocolSession session) throws AMQException - { - queue.delete(); - } - }; - - ((AMQChannel) queue.getExclusiveOwningSession()).getProtocolSession().addSessionCloseTask(deleteQueueTask); - } - - /** Check that a null queue passed in does not upset the policy. */ - public void testNullQueueParameter() throws ConfigurationException - { - TopicDeletePolicy policy = new TopicDeletePolicy(); - policy.configure(_config); - - try - { - policy.performPolicy(null); - } - catch (Exception e) - { - fail("Exception should not be thrown:" + e.getMessage()); - } - - } - - /** - * Set a owning Session to null which means this is not an exclusive queue - * so the queue should not be deleted - */ - public void testNonExclusiveQueue() - { - TopicDeletePolicy policy = new TopicDeletePolicy(); - policy.configure(_config); - - MockAMQQueue queue = createOwnedQueue(); - - queue.setExclusiveOwningSession(null); - - policy.performPolicy(queue); - - assertFalse("Queue should not be deleted", queue.isDeleted()); - assertFalse("Connection should not be closed", _connection.isClosed()); - } - - /** - * Test that exclusive JMS Queues are not deleted. - * Bind the queue to the direct exchange (so it is a JMS Queue). - * - * JMS Queues are not to be processed so this should not delete the queue. - */ - public void testQueuesAreNotProcessed() - { - TopicDeletePolicy policy = new TopicDeletePolicy(); - policy.configure(_config); - - MockAMQQueue queue = createOwnedQueue(); - - queue.addBinding(new Binding(null, null, "bindingKey", queue, new DirectExchange(), null)); - - policy.performPolicy(queue); - - assertFalse("Queue should not be deleted", queue.isDeleted()); - assertFalse("Connection should not be closed", _connection.isClosed()); - } - - /** - * Give a non auto-delete queue is bound to the topic exchange the - * TopicDeletePolicy will close the connection and delete the queue, - */ - public void testNonAutoDeleteTopicIsNotClosed() - { - TopicDeletePolicy policy = new TopicDeletePolicy(); - policy.configure(_config); - - MockAMQQueue queue = createOwnedQueue(); - - queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null)); - - queue.setAutoDelete(false); - - policy.performPolicy(queue); - - assertFalse("Queue should not be deleted", queue.isDeleted()); - assertTrue("Connection should be closed", _connection.isClosed()); - } - - /** - * Give a auto-delete queue bound to the topic exchange the TopicDeletePolicy will - * close the connection and delete the queue - */ - public void testTopicIsClosed() - { - TopicDeletePolicy policy = new TopicDeletePolicy(); - policy.configure(_config); - - final MockAMQQueue queue = createOwnedQueue(); - - queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null)); - - setQueueToAutoDelete(queue); - - policy.performPolicy(queue); - - assertTrue("Queue should be deleted", queue.isDeleted()); - assertTrue("Connection should be closed", _connection.isClosed()); - } - - /** - * Give a queue bound to the topic exchange the TopicDeletePolicy will - * close the connection and NOT delete the queue - */ - public void testNonAutoDeleteTopicIsClosedNotDeleted() - { - TopicDeletePolicy policy = new TopicDeletePolicy(); - policy.configure(_config); - - MockAMQQueue queue = createOwnedQueue(); - - queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null)); - - policy.performPolicy(queue); - - assertFalse("Queue should not be deleted", queue.isDeleted()); - assertTrue("Connection should be closed", _connection.isClosed()); - } - - /** - * Give a queue bound to the topic exchange the TopicDeletePolicy suitably - * configured with the delete-persistent tag will close the connection - * and delete the queue - */ - public void testPersistentTopicIsClosedAndDeleted() - { - //Set the config to delete persistent queues - _config.getConfig().addProperty("delete-persistent", ""); - - TopicDeletePolicy policy = new TopicDeletePolicy(); - policy.configure(_config); - - assertTrue("Config was not updated to delete Persistent topics", - _config.deletePersistent()); - - MockAMQQueue queue = createOwnedQueue(); - - queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null)); - - policy.performPolicy(queue); - - assertTrue("Queue should be deleted", queue.isDeleted()); - assertTrue("Connection should be closed", _connection.isClosed()); - } - - /** - * Give a queue bound to the topic exchange the TopicDeletePolicy not - * configured to close a persistent queue - */ - public void testPersistentTopicIsClosedAndDeletedNullConfig() - { - TopicDeletePolicy policy = new TopicDeletePolicy(); - // Explicity say we are not configuring the policy. - policy.configure(null); - - MockAMQQueue queue = createOwnedQueue(); - - queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null)); - - policy.performPolicy(queue); - - assertFalse("Queue should not be deleted", queue.isDeleted()); - assertTrue("Connection should be closed", _connection.isClosed()); - } - - public void testNonExclusiveQueueNullConfig() - { - _config = null; - testNonExclusiveQueue(); - } - - public void testQueuesAreNotProcessedNullConfig() - { - _config = null; - testQueuesAreNotProcessed(); - } - - public void testNonAutoDeleteTopicIsNotClosedNullConfig() - { - _config = null; - testNonAutoDeleteTopicIsNotClosed(); - } - - public void testTopicIsClosedNullConfig() - { - _config = null; - testTopicIsClosed(); - } - - public void testNonAutoDeleteTopicIsClosedNotDeletedNullConfig() throws AMQException - { - _config = null; - testNonAutoDeleteTopicIsClosedNotDeleted(); - } - -} diff --git a/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm b/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm index 02bf155c44..cddfcfb581 100644 --- a/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm +++ b/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm @@ -23,8 +23,8 @@ package ${package}; import static org.apache.qpid.server.logging.AbstractRootMessageLogger.DEFAULT_LOG_HIERARCHY_PREFIX; import org.apache.log4j.Logger; +import org.apache.qpid.server.configuration.BrokerProperties; import org.apache.qpid.server.logging.LogMessage; -import org.apache.qpid.server.registry.ApplicationRegistry; import java.text.MessageFormat; import java.util.Locale; @@ -44,7 +44,7 @@ import java.util.ResourceBundle; public class ${type.name}Messages { private static ResourceBundle _messages; - private static Locale _currentLocale; + private static Locale _currentLocale = BrokerProperties.getLocale(); public static final String ${type.name.toUpperCase()}_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "${type.name.toLowerCase()}"; #foreach( $message in ${type.list} ) @@ -58,24 +58,9 @@ public class ${type.name}Messages Logger.getLogger(${message.methodName.toUpperCase()}_LOG_HIERARCHY); #end - reload(); - } - - public static void reload() - { - if (ApplicationRegistry.isConfigured()) - { - _currentLocale = ApplicationRegistry.getInstance().getConfiguration().getLocale(); - } - else - { - _currentLocale = Locale.getDefault(); - } - _messages = ResourceBundle.getBundle("${resource}", _currentLocale); } - ## ## The list stored under key 'list' in the 'type' HashMap contains all the ## log messages that this class should contain. So for each entry in the list |